Class: Chef::Role

Inherits:
Object show all
Includes:
IndexQueue::Indexable, Mixin::FromFile, Mixin::ParamsValidate
Defined in:
lib/chef/role.rb

Constant Summary collapse

DESIGN_DOCUMENT =
{
  "version" => 6,
  "language" => "javascript",
  "views" => {
    "all" => {
      "map" => <<-EOJS
      function(doc) {
        if (doc.chef_type == "role") {
          emit(doc.name, doc);
        }
      }
      EOJS
    },
    "all_id" => {
      "map" => <<-EOJS
      function(doc) {
        if (doc.chef_type == "role") {
          emit(doc.name, doc.name);
        }
      }
      EOJS
    }
  }
}

Instance Attribute Summary collapse

Attributes included from IndexQueue::Indexable

#index_id

Class Method Summary collapse

Instance Method Summary collapse

Methods included from IndexQueue::Indexable

#add_to_index, #delete_from_index, included, #index_object_type, #with_indexer_metadata

Methods included from Mixin::ParamsValidate

#set_or_return, #validate

Methods included from Mixin::FromFile

#class_from_file, #from_file

Constructor Details

#initialize(couchdb = nil) ⇒ Role

Create a new Chef::Role object.


67
68
69
70
71
72
73
74
75
76
# File 'lib/chef/role.rb', line 67

def initialize(couchdb=nil)
  @name = ''
  @description = ''
  @default_attributes = Mash.new
  @override_attributes = Mash.new
  @env_run_lists = {"_default" => Chef::RunList.new}
  @couchdb_rev = nil
  @couchdb_id = nil
  @couchdb = couchdb || Chef::CouchDB.new
end

Instance Attribute Details

#couchdbObject

Returns the value of attribute couchdb


63
64
65
# File 'lib/chef/role.rb', line 63

def couchdb
  @couchdb
end

#couchdb_idObject

Returns the value of attribute couchdb_id


64
65
66
# File 'lib/chef/role.rb', line 64

def couchdb_id
  @couchdb_id
end

#couchdb_revObject

Returns the value of attribute couchdb_rev


63
64
65
# File 'lib/chef/role.rb', line 63

def couchdb_rev
  @couchdb_rev
end

Class Method Details

.cdb_list(inflate = false, couchdb = nil) ⇒ Object

List all the Chef::Role objects in the CouchDB. If inflate is set to true, you will get the full list of all Roles, fully inflated.


225
226
227
228
229
# File 'lib/chef/role.rb', line 225

def self.cdb_list(inflate=false, couchdb=nil)
  rs = (couchdb || Chef::CouchDB.new).list("roles", inflate)
  lookup = (inflate ? "value" : "key")
  rs["rows"].collect { |r| r[lookup] }
end

.cdb_load(name, couchdb = nil) ⇒ Object

Load a role by name from CouchDB


245
246
247
# File 'lib/chef/role.rb', line 245

def self.cdb_load(name, couchdb=nil)
  (couchdb || Chef::CouchDB.new).load("role", name)
end

.chef_server_restObject


87
88
89
# File 'lib/chef/role.rb', line 87

def self.chef_server_rest
  Chef::REST.new(Chef::Config[:chef_server_url])
end

.create_design_document(couchdb = nil) ⇒ Object

Set up our CouchDB design document


303
304
305
# File 'lib/chef/role.rb', line 303

def self.create_design_document(couchdb=nil)
  (couchdb || Chef::CouchDB.new).create_design_document("roles", DESIGN_DOCUMENT)
end

.exists?(rolename, couchdb) ⇒ Boolean

Returns:

  • (Boolean)

254
255
256
257
258
259
260
# File 'lib/chef/role.rb', line 254

def self.exists?(rolename, couchdb)
  begin
    self.cdb_load(rolename, couchdb)
  rescue Chef::Exceptions::CouchDBNotFound
    nil
  end
end

.from_disk(name, force = nil) ⇒ Object

Load a role from disk - prefers to load the JSON, but will happily load the raw rb files as well.


314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/chef/role.rb', line 314

def self.from_disk(name, force=nil)
  js_file = File.join(Chef::Config[:role_path], "#{name}.json")
  rb_file = File.join(Chef::Config[:role_path], "#{name}.rb")

  if File.exists?(js_file) || force == "json"
    # from_json returns object.class => json_class in the JSON.
    Chef::JSONCompat.from_json(IO.read(js_file))
  elsif File.exists?(rb_file) || force == "ruby"
    role = Chef::Role.new
    role.name(name)
    role.from_file(rb_file)
    role
  else
    raise Chef::Exceptions::RoleNotFound, "Role '#{name}' could not be loaded from disk"
  end
end

.json_create(o) ⇒ Object

Create a Chef::Role from JSON


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/chef/role.rb', line 199

def self.json_create(o)
  role = new
  role.name(o["name"])
  role.description(o["description"])
  role.default_attributes(o["default_attributes"])
  role.override_attributes(o["override_attributes"])

  # _default run_list is in 'run_list' for newer clients, and
  # 'recipes' for older clients.
  env_run_list_hash = {"_default" => (o.has_key?("run_list") ? o["run_list"] : o["recipes"])}

  # Clients before 0.10 do not include env_run_lists, so only
  # merge if it's there.
  if o["env_run_lists"]
    env_run_list_hash.merge!(o["env_run_lists"])
  end
  role.env_run_lists(env_run_list_hash)

  role.couchdb_rev = o["_rev"] if o.has_key?("_rev")
  role.index_id = role.couchdb_id
  role.couchdb_id = o["_id"] if o.has_key?("_id")
  role
end

.list(inflate = false) ⇒ Object

Get the list of all roles from the API.


232
233
234
235
236
237
238
239
240
241
242
# File 'lib/chef/role.rb', line 232

def self.list(inflate=false)
  if inflate
    response = Hash.new
    Chef::Search::Query.new.search(:role) do |n|
      response[n.name] = n unless n.nil?
    end
    response
  else
    chef_server_rest.get_rest("roles")
  end
end

.load(name) ⇒ Object

Load a role by name from the API


250
251
252
# File 'lib/chef/role.rb', line 250

def self.load(name)
  chef_server_rest.get_rest("roles/#{name}")
end

.sync_from_disk_to_couchdbObject

Sync all the json roles with couchdb from disk


332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/chef/role.rb', line 332

def self.sync_from_disk_to_couchdb
  Dir[File.join(Chef::Config[:role_path], "*.json")].each do |role_file|
    short_name = File.basename(role_file, ".json")
    Chef::Log.warn("Loading #{short_name}")
    r = Chef::Role.from_disk(short_name, "json")
    begin
      couch_role = Chef::Role.cdb_load(short_name)
      r.couchdb_rev = couch_role.couchdb_rev
      Chef::Log.debug("Replacing role #{short_name} with data from #{role_file}")
    rescue Chef::Exceptions::CouchDBNotFound
      Chef::Log.debug("Creating role #{short_name} with data from #{role_file}")
    end
    r.cdb_save
  end
end

Instance Method Details

#active_run_list_for(environment) ⇒ Object


125
126
127
# File 'lib/chef/role.rb', line 125

def active_run_list_for(environment)
  @env_run_lists.has_key?(environment) ? environment : '_default'
end

#cdb_destroyObject

Remove this role from the CouchDB


271
272
273
# File 'lib/chef/role.rb', line 271

def cdb_destroy
  couchdb.delete("role", @name, couchdb_rev)
end

#cdb_saveObject

Save this role to the CouchDB


281
282
283
# File 'lib/chef/role.rb', line 281

def cdb_save
  self.couchdb_rev = couchdb.store("role", @name, self)["rev"]
end

#chef_server_restObject


83
84
85
# File 'lib/chef/role.rb', line 83

def chef_server_rest
  Chef::REST.new(Chef::Config[:chef_server_url])
end

#createObject

Create the role via the REST API


297
298
299
300
# File 'lib/chef/role.rb', line 297

def create
  chef_server_rest.post_rest("roles", self)
  self
end

#default_attributes(arg = nil) ⇒ Object


145
146
147
148
149
150
151
# File 'lib/chef/role.rb', line 145

def default_attributes(arg=nil)
  set_or_return(
    :default_attributes,
    arg,
    :kind_of => Hash
  )
end

#description(arg = nil) ⇒ Object


99
100
101
102
103
104
105
# File 'lib/chef/role.rb', line 99

def description(arg=nil)
  set_or_return(
    :description,
    arg,
    :kind_of => String
  )
end

#destroyObject

Remove this role via the REST API


276
277
278
# File 'lib/chef/role.rb', line 276

def destroy
  chef_server_rest.delete_rest("roles/#{@name}")
end

#env_run_lists(env_run_lists = nil) ⇒ Object Also known as: env_run_list

Per environment run lists


130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/chef/role.rb', line 130

def env_run_lists(env_run_lists=nil)
  if (!env_run_lists.nil?)
    unless env_run_lists.key?("_default")
      msg = "_default key is required in env_run_lists.\n"
      msg << "(env_run_lists: #{env_run_lists.inspect})"
      raise Chef::Exceptions::InvalidEnvironmentRunListSpecification, msg
    end
    @env_run_lists.clear
    env_run_lists.each { |k,v| @env_run_lists[k] = Chef::RunList.new(*Array(v))}
  end
  @env_run_lists
end

#environment(env_name) ⇒ Object


262
263
264
# File 'lib/chef/role.rb', line 262

def environment(env_name)
  chef_server_rest.get_rest("roles/#{@name}/environments/#{env_name}")
end

#environmentsObject


266
267
268
# File 'lib/chef/role.rb', line 266

def environments
  chef_server_rest.get_rest("roles/#{@name}/environments")
end

#name(arg = nil) ⇒ Object


91
92
93
94
95
96
97
# File 'lib/chef/role.rb', line 91

def name(arg=nil)
  set_or_return(
    :name,
    arg,
    :regex => /^[\-[:alnum:]_]+$/
  )
end

#override_attributes(arg = nil) ⇒ Object


153
154
155
156
157
158
159
# File 'lib/chef/role.rb', line 153

def override_attributes(arg=nil)
  set_or_return(
    :override_attributes,
    arg,
    :kind_of => Hash
  )
end

#run_list(*args) ⇒ Object Also known as: recipes


107
108
109
110
111
112
# File 'lib/chef/role.rb', line 107

def run_list(*args)
  if (args.length > 0)
    @env_run_lists["_default"].reset!(args)
  end
  @env_run_lists["_default"]
end

#run_list_for(environment) ⇒ Object

For run_list expansion


117
118
119
120
121
122
123
# File 'lib/chef/role.rb', line 117

def run_list_for(environment)
  if env_run_lists[environment].nil?
    env_run_lists["_default"]
  else
    env_run_lists[environment]
  end
end

#saveObject

Save this role via the REST API


286
287
288
289
290
291
292
293
294
# File 'lib/chef/role.rb', line 286

def save
  begin
    chef_server_rest.put_rest("roles/#{@name}", self)
  rescue Net::HTTPServerException => e
    raise e unless e.response.code == "404"
    chef_server_rest.post_rest("roles", self)
  end
  self
end

#to_hashObject


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/chef/role.rb', line 161

def to_hash
  env_run_lists_without_default = @env_run_lists.dup
  env_run_lists_without_default.delete("_default")
  result = {
    "name" => @name,
    "description" => @description,
    'json_class' => self.class.name,
    "default_attributes" => @default_attributes,
    "override_attributes" => @override_attributes,
    "chef_type" => "role",

    #Render to_json correctly for run_list items (both run_list and evn_run_lists)
    #so malformed json does not result
    "run_list" => run_list.run_list.map { |item| item.to_s },
    "env_run_lists" => env_run_lists_without_default.inject({}) do |accumulator, (k, v)|
      accumulator[k] = v.map { |x| x.to_s }
      accumulator
    end
  }
  result["_rev"] = couchdb_rev if couchdb_rev
  result
end

#to_json(*a) ⇒ Object

Serialize this object as a hash


185
186
187
# File 'lib/chef/role.rb', line 185

def to_json(*a)
  to_hash.to_json(*a)
end

#to_sObject

As a string


308
309
310
# File 'lib/chef/role.rb', line 308

def to_s
  "role[#{@name}]"
end

#update_from!(o) ⇒ Object


189
190
191
192
193
194
195
196
# File 'lib/chef/role.rb', line 189

def update_from!(o)
  description(o.description)
  recipes(o.recipes) if defined?(o.recipes)
  default_attributes(o.default_attributes)
  override_attributes(o.override_attributes)
  env_run_lists(o.env_run_lists) unless o.env_run_lists.nil?
  self
end