Class: Chef::DataBag

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

Constant Summary collapse

VALID_NAME =
/^[\-[:alnum:]_]+$/
DESIGN_DOCUMENT =
{
  "version" => 2,
  "language" => "javascript",
  "views" => {
    "all" => {
      "map" => <<-EOJS
      function(doc) {
        if (doc.chef_type == "data_bag") {
          emit(doc.name, doc);
        }
      }
      EOJS
    },
    "all_id" => {
      "map" => <<-EOJS
      function(doc) {
        if (doc.chef_type == "data_bag") {
          emit(doc.name, doc.name);
        }
      }
      EOJS
    },
    "entries" => {
      "map" => <<-EOJS
      function(doc) {
        if (doc.chef_type == "data_bag_item") {
          emit(doc.data_bag, doc.raw_data.id);
        }
      }
      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) ⇒ DataBag

Create a new Chef::DataBag



82
83
84
85
86
87
# File 'lib/chef/data_bag.rb', line 82

def initialize(couchdb=nil)
  @name = ''
  @couchdb_rev = nil
  @couchdb_id = nil
  @couchdb = (couchdb || Chef::CouchDB.new)
end

Instance Attribute Details

#couchdbObject

Returns the value of attribute couchdb.



79
80
81
# File 'lib/chef/data_bag.rb', line 79

def couchdb
  @couchdb
end

#couchdb_idObject

Returns the value of attribute couchdb_id.



79
80
81
# File 'lib/chef/data_bag.rb', line 79

def couchdb_id
  @couchdb_id
end

#couchdb_revObject

Returns the value of attribute couchdb_rev.



79
80
81
# File 'lib/chef/data_bag.rb', line 79

def couchdb_rev
  @couchdb_rev
end

Class Method Details

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

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



132
133
134
135
136
# File 'lib/chef/data_bag.rb', line 132

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

.cdb_load(name, couchdb = nil) ⇒ Object

Load a Data Bag by name from CouchDB



151
152
153
# File 'lib/chef/data_bag.rb', line 151

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

.chef_server_restObject



116
117
118
# File 'lib/chef/data_bag.rb', line 116

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



228
229
230
# File 'lib/chef/data_bag.rb', line 228

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

.json_create(o) ⇒ Object

Create a Chef::Role from JSON



121
122
123
124
125
126
127
128
# File 'lib/chef/data_bag.rb', line 121

def self.json_create(o)
  bag = new
  bag.name(o["name"])
  bag.couchdb_rev = o["_rev"] if o.has_key?("_rev")
  bag.couchdb_id = o["_id"] if o.has_key?("_id")
  bag.index_id = bag.couchdb_id
  bag
end

.list(inflate = false) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/chef/data_bag.rb', line 138

def self.list(inflate=false)
  if inflate
    # Can't search for all data bags like other objects, fall back to N+1 :(
    list(false).inject({}) do |response, bag_and_uri|
      response[bag_and_uri.first] = load(bag_and_uri.first)
      response
    end
  else
    Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data")
  end
end

.load(name) ⇒ Object

Load a Data Bag by name via either the RESTful API or local data_bag_path if run in solo mode



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/chef/data_bag.rb', line 156

def self.load(name)
  if Chef::Config[:solo]
    unless File.directory?(Chef::Config[:data_bag_path])
      raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{Chef::Config[:data_bag_path]}' is invalid"
    end

    Dir.glob(File.join(Chef::Config[:data_bag_path], "#{name}", "*.json")).inject({}) do |bag, f|
      item = JSON.parse(IO.read(f))
      bag[item['id']] = item
      bag
    end
  else
    Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data/#{name}")
  end
end

.validate_name!(name) ⇒ Object



73
74
75
76
77
# File 'lib/chef/data_bag.rb', line 73

def self.validate_name!(name)
  unless name =~ VALID_NAME
    raise Exceptions::InvalidDataBagName, "DataBags must have a name matching #{VALID_NAME.inspect}, you gave #{name.inspect}"
  end
end

Instance Method Details

#cdb_destroyObject

Remove this Data Bag from CouchDB



173
174
175
176
177
178
179
180
181
# File 'lib/chef/data_bag.rb', line 173

def cdb_destroy
  removed = @couchdb.delete("data_bag", @name, @couchdb_rev)
  rs = @couchdb.get_view("data_bags", "entries", :include_docs => true, :startkey => @name, :endkey => @name)
  rs["rows"].each do |row|
    row["doc"].couchdb = couchdb
    row["doc"].cdb_destroy
  end
  removed
end

#cdb_saveObject

Save this Data Bag to the CouchDB



188
189
190
191
# File 'lib/chef/data_bag.rb', line 188

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

#chef_server_restObject



112
113
114
# File 'lib/chef/data_bag.rb', line 112

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

#createObject

create a data bag via RESTful API



209
210
211
212
# File 'lib/chef/data_bag.rb', line 209

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

#destroyObject



183
184
185
# File 'lib/chef/data_bag.rb', line 183

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

#list(inflate = false) ⇒ Object

List all the items in this Bag from CouchDB The self.load method does this through the REST API



216
217
218
219
220
221
222
223
224
225
# File 'lib/chef/data_bag.rb', line 216

def list(inflate=false)
  rs = nil
  if inflate
    rs = @couchdb.get_view("data_bags", "entries", :include_docs => true, :startkey => @name, :endkey => @name)
    rs["rows"].collect { |r| r["doc"] }
  else
    rs = @couchdb.get_view("data_bags", "entries", :startkey => @name, :endkey => @name)
    rs["rows"].collect { |r| r["value"] }
  end
end

#name(arg = nil) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/chef/data_bag.rb', line 89

def name(arg=nil)
  set_or_return(
    :name,
    arg,
    :regex => VALID_NAME
  )
end

#saveObject

Save the Data Bag via RESTful API



194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/chef/data_bag.rb', line 194

def save
  begin
    if Chef::Config[:why_run]
      Chef::Log.warn("In whyrun mode, so NOT performing data bag save.")
    else
      chef_server_rest.put_rest("data/#{@name}", self)
    end
  rescue Net::HTTPServerException => e
    raise e unless e.response.code == "404"
    chef_server_rest.post_rest("data", self)
  end
  self
end

#to_hashObject



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

def to_hash
  result = {
    "name" => @name,
    'json_class' => self.class.name,
    "chef_type" => "data_bag",
  }
  result["_rev"] = @couchdb_rev if @couchdb_rev
  result
end

#to_json(*a) ⇒ Object

Serialize this object as a hash



108
109
110
# File 'lib/chef/data_bag.rb', line 108

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

#to_sObject

As a string



233
234
235
# File 'lib/chef/data_bag.rb', line 233

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