Class: Chef::DataBag

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

Constant Summary collapse

VALID_NAME =
/^[\.\-[:alnum:]_]+$/.freeze
RESERVED_NAMES =
/^(node|role|environment|client)$/.freeze

Instance Attribute Summary

Attributes included from Mixin::FromFile

#source_file

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ParamsValidate

#lazy, #set_or_return, #validate

Methods included from Mixin::FromFile

#class_from_file, #from_file

Constructor Details

#initialize(chef_server_rest: nil) ⇒ DataBag

Create a new Chef::DataBag



48
49
50
51
# File 'lib/chef/data_bag.rb', line 48

def initialize(chef_server_rest: nil)
  @name = ""
  @chef_server_rest = chef_server_rest
end

Class Method Details

.chef_server_restObject



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

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

.from_hash(o) ⇒ Object



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

def self.from_hash(o)
  bag = new
  bag.name(o["name"])
  bag
end

.list(inflate = false) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/chef/data_bag.rb', line 90

def self.list(inflate = false)
  if Chef::Config[:solo_legacy_mode]
    paths = Array(Chef::Config[:data_bag_path])
    names = []
    paths.each do |path|
      unless File.directory?(path)
        raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' not found. Please create this directory."
      end

      names += Dir.glob(File.join(
        Chef::Util::PathHelper.escape_glob_dir(path), "*"
      )).map { |f| File.basename(f) }.sort
    end
    names.inject({}) { |h, n| h[n] = n; h }
  else
    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::ServerAPI.new(Chef::Config[:chef_server_url]).get("data")
    end
  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



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/chef/data_bag.rb', line 118

def self.load(name)
  if Chef::Config[:solo_legacy_mode]
    paths = Array(Chef::Config[:data_bag_path])
    data_bag = {}
    paths.each do |path|
      unless File.directory?(path)
        raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' not found. Please create this directory."
      end

      Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(path, name.to_s), "*.json")).inject({}) do |bag, f|
        item = Chef::JSONCompat.parse(IO.read(f))

        # Check if we have multiple items with similar names (ids) and raise if their content differs
        if data_bag.key?(item["id"]) && data_bag[item["id"]] != item
          raise Chef::Exceptions::DuplicateDataBagItem, "Data bag '#{name}' has items with the same name '#{item["id"]}' but different content."
        else
          data_bag[item["id"]] = item
        end
      end
    end
    data_bag
  else
    Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("data/#{name}")
  end
end

.validate_name!(name) ⇒ Object



38
39
40
41
42
43
44
45
# File 'lib/chef/data_bag.rb', line 38

def self.validate_name!(name)
  unless VALID_NAME.match?(name)
    raise Exceptions::InvalidDataBagName, "DataBags must have a name matching #{VALID_NAME.inspect}, you gave #{name.inspect}"
  end
  if RESERVED_NAMES.match?(name)
    raise Exceptions::InvalidDataBagName, "DataBags may not have a name matching #{RESERVED_NAMES.inspect}, you gave #{name.inspect}"
  end
end

Instance Method Details

#chef_server_restObject



76
77
78
# File 'lib/chef/data_bag.rb', line 76

def chef_server_rest
  @chef_server_rest ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end

#createObject

create a data bag via RESTful API



163
164
165
166
# File 'lib/chef/data_bag.rb', line 163

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

#destroyObject



144
145
146
# File 'lib/chef/data_bag.rb', line 144

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

#name(arg = nil) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/chef/data_bag.rb', line 53

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

#saveObject

Save the Data Bag via RESTful API



149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/chef/data_bag.rb', line 149

def save
  begin
    if Chef::Config[:why_run]
      Chef::Log.warn("In why-run mode, so NOT performing data bag save.")
    else
      create
    end
  rescue Net::HTTPClientException => e
    raise e unless e.response.code == "409"
  end
  self
end

#to_hObject Also known as: to_hash



61
62
63
64
65
66
67
# File 'lib/chef/data_bag.rb', line 61

def to_h
  {
    "name" => @name,
    "json_class" => self.class.name,
    "chef_type" => "data_bag",
  }
end

#to_json(*a) ⇒ Object

Serialize this object as a hash



72
73
74
# File 'lib/chef/data_bag.rb', line 72

def to_json(*a)
  Chef::JSONCompat.to_json(to_h, *a)
end

#to_sObject

As a string



169
170
171
# File 'lib/chef/data_bag.rb', line 169

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