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.



219
220
221
222
223
# File 'lib/chef/role.rb', line 219

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



239
240
241
# File 'lib/chef/role.rb', line 239

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



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

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

.exists?(rolename, couchdb) ⇒ Boolean

Returns:

  • (Boolean)


248
249
250
251
252
253
254
# File 'lib/chef/role.rb', line 248

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.



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/chef/role.rb', line 308

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



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/chef/role.rb', line 193

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.



226
227
228
229
230
231
232
233
234
235
236
# File 'lib/chef/role.rb', line 226

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



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

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



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/chef/role.rb', line 326

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



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

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

#cdb_saveObject

Save this role to the CouchDB



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

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



291
292
293
294
# File 'lib/chef/role.rb', line 291

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



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

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



256
257
258
# File 'lib/chef/role.rb', line 256

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

#environmentsObject



260
261
262
# File 'lib/chef/role.rb', line 260

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



280
281
282
283
284
285
286
287
288
# File 'lib/chef/role.rb', line 280

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
# 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",
    "run_list" => run_list,
    "env_run_lists" => env_run_lists_without_default
  }
  result["_rev"] = couchdb_rev if couchdb_rev
  result
end

#to_json(*a) ⇒ Object

Serialize this object as a hash



179
180
181
# File 'lib/chef/role.rb', line 179

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

#to_sObject

As a string



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

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

#update_from!(o) ⇒ Object



183
184
185
186
187
188
189
190
# File 'lib/chef/role.rb', line 183

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