Class: Bolt::Inventory::Inventory

Inherits:
Object
  • Object
show all
Defined in:
lib/bolt/inventory/inventory.rb

Defined Under Namespace

Classes: WildcardError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, config = nil, plugins:) ⇒ Inventory

Returns a new instance of Inventory.



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/bolt/inventory/inventory.rb', line 16

def initialize(data, config = nil, plugins:)
  @logger = Logging.logger[self]
  # Config is saved to add config options to targets
  @config = config || Bolt::Config.default
  @data = data || {}
  @groups = Group.new(@data.merge('name' => 'all'), plugins)
  @plugins = plugins
  @group_lookup = {}
  # The targets hash is the canonical source for all targets in inventory
  @targets = {}
  @groups.resolve_string_targets(@groups.target_aliases, @groups.all_targets)
  collect_groups
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



9
10
11
# File 'lib/bolt/inventory/inventory.rb', line 9

def config
  @config
end

#pluginsObject (readonly)

Returns the value of attribute plugins.



9
10
11
# File 'lib/bolt/inventory/inventory.rb', line 9

def plugins
  @plugins
end

#targetsObject (readonly)

Returns the value of attribute targets.



9
10
11
# File 'lib/bolt/inventory/inventory.rb', line 9

def targets
  @targets
end

Class Method Details

.localhost_defaults(data) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/bolt/inventory/inventory.rb', line 86

def self.localhost_defaults(data)
  defaults = {
    'config' => {
      'transport' => 'local',
      'local' => { 'interpreters' => { '.rb' => RbConfig.ruby } }
    },
    'features' => ['puppet-agent']
  }
  data = Bolt::Util.deep_merge(defaults, data)
  # If features is an empty array deep_merge won't add the puppet-agent
  data['features'] += ['puppet-agent'] if data['features'].empty?
  data
end

Instance Method Details

#add_facts(target, new_facts = {}) ⇒ Object



295
296
297
298
# File 'lib/bolt/inventory/inventory.rb', line 295

def add_facts(target, new_facts = {})
  @targets[target.name].add_facts(new_facts)
  target
end

#add_to_group(targets, desired_group) ⇒ Object



276
277
278
279
280
281
282
283
284
285
# File 'lib/bolt/inventory/inventory.rb', line 276

def add_to_group(targets, desired_group)
  if group_names.include?(desired_group)
    targets.each do |target|
      # Add the inventory copy of the target
      add_target(@groups, @targets[target.name], desired_group)
    end
  else
    raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
  end
end

#clear_alia_from_group(group, target_name) ⇒ Object



251
252
253
254
255
256
257
258
# File 'lib/bolt/inventory/inventory.rb', line 251

def clear_alia_from_group(group, target_name)
  if group.all_target_names.include?(target_name)
    group.clear_alia(target_name)
  end
  group.groups.each do |grp|
    clear_alia_from_group(grp, target_name)
  end
end

#collect_groupsObject



42
43
44
45
# File 'lib/bolt/inventory/inventory.rb', line 42

def collect_groups
  # Provide a lookup map for finding a group by name
  @group_lookup = @groups.collect_groups
end

#create_target_from_hash(data) ⇒ Object

Add a brand new target, overriding any existing target with the same name. This method does not honor target config from the inventory. This is used when Target.new is called from a plan or with a data hash.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/bolt/inventory/inventory.rb', line 198

def create_target_from_hash(data)
  # If target already exists, delete old and replace with new, otherwise add to new to all group
  new_target = Bolt::Inventory::Target.new(data, self)
  existing_target = @targets.key?(new_target.name)

  validate_target_from_hash(new_target)
  @targets[new_target.name] = new_target

  if existing_target
    clear_alia_from_group(@groups, new_target.name)
  else
    add_to_group([new_target], 'all')
  end

  if new_target.target_alias
    @groups.insert_alia(new_target.name, Array(new_target.target_alias))
  end

  new_target
end

#create_target_from_inventory(target_name) ⇒ Object

Pull in a target definition from the inventory file and evaluate any associated references. This is used when a target is resolved by get_targets.



184
185
186
187
188
189
190
191
192
193
# File 'lib/bolt/inventory/inventory.rb', line 184

def create_target_from_inventory(target_name)
  target_data = @groups.target_collect(target_name) || { 'uri' => target_name }

  target = Bolt::Inventory::Target.new(target_data, self)
  @targets[target.name] = target

  add_to_group([target], 'all')

  target
end

#data_hashObject



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/bolt/inventory/inventory.rb', line 74

def data_hash
  {
    data: {},
    target_hash: {
      target_vars: {},
      target_facts: {},
      target_features: {}
    },
    config: @config.transport_data_get
  }
end

#facts(target) ⇒ Object



300
301
302
# File 'lib/bolt/inventory/inventory.rb', line 300

def facts(target)
  @targets[target.name].facts
end

#features(target) ⇒ Object



308
309
310
# File 'lib/bolt/inventory/inventory.rb', line 308

def features(target)
  @targets[target.name].features
end

#get_target(target) ⇒ Object



66
67
68
69
70
71
72
# File 'lib/bolt/inventory/inventory.rb', line 66

def get_target(target)
  target_array = get_targets(target)
  if target_array.count > 1
    raise ValidationError.new("'#{target}' refers to #{target_array.count} targets", nil)
  end
  target_array.first
end

#get_targets(targets) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/bolt/inventory/inventory.rb', line 57

def get_targets(targets)
  target_array = expand_targets(targets)
  if target_array.is_a? Array
    target_array.flatten.uniq(&:name)
  else
    [target_array]
  end
end

#group_data_for(target_name) ⇒ Object

PRIVATE ####



101
102
103
# File 'lib/bolt/inventory/inventory.rb', line 101

def group_data_for(target_name)
  @groups.group_collect(target_name)
end

#group_namesObject



47
48
49
# File 'lib/bolt/inventory/inventory.rb', line 47

def group_names
  @group_lookup.keys
end

#plugin_hooks(target) ⇒ Object



312
313
314
# File 'lib/bolt/inventory/inventory.rb', line 312

def plugin_hooks(target)
  @targets[target.name].plugin_hooks
end

#remove_from_group(target, desired_group) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/bolt/inventory/inventory.rb', line 260

def remove_from_group(target, desired_group)
  unless target.length == 1
    raise ValidationError.new("'remove_from_group' expects a single Target, got #{target.length}", nil)
  end

  if desired_group == 'all'
    raise ValidationError.new("Cannot remove Target from Group 'all'", nil)
  end

  if group_names.include?(desired_group)
    remove_target(@groups, @targets[target.first.name], desired_group)
  else
    raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
  end
end

#set_config(target, key_or_key_path, value) ⇒ Object



316
317
318
# File 'lib/bolt/inventory/inventory.rb', line 316

def set_config(target, key_or_key_path, value)
  @targets[target.name].set_config(key_or_key_path, value)
end

#set_feature(target, feature, value = true) ⇒ Object



304
305
306
# File 'lib/bolt/inventory/inventory.rb', line 304

def set_feature(target, feature, value = true)
  @targets[target.name].set_feature(feature, value)
end

#set_var(target, var_hash) ⇒ Object



287
288
289
# File 'lib/bolt/inventory/inventory.rb', line 287

def set_var(target, var_hash)
  @targets[target.name].set_var(var_hash)
end

#target_config(target) ⇒ Object



320
321
322
# File 'lib/bolt/inventory/inventory.rb', line 320

def target_config(target)
  @targets[target.name].config
end

#target_implementation_classObject



38
39
40
# File 'lib/bolt/inventory/inventory.rb', line 38

def target_implementation_class
  Bolt::Target
end

#target_namesObject Also known as: node_names



51
52
53
# File 'lib/bolt/inventory/inventory.rb', line 51

def target_names
  @groups.all_targets
end

#validateObject



30
31
32
# File 'lib/bolt/inventory/inventory.rb', line 30

def validate
  @groups.validate
end

#validate_target_from_hash(target) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/bolt/inventory/inventory.rb', line 219

def validate_target_from_hash(target)
  groups = Set.new(group_names)
  targets = target_names

  # Make sure there are no group name conflicts
  if groups.include?(target.name)
    raise ValidationError.new("Target name #{target.name} conflicts with group of the same name", nil)
  end

  # Validate any aliases
  if (aliases = target.target_alias)
    unless aliases.is_a?(Array) || aliases.is_a?(String)
      msg = "Alias entry on #{t_name} must be a String or Array, not #{aliases.class}"
      raise ValidationError.new(msg, @name)
    end
  end

  # Make sure there are no conflicts with the new target aliases
  used_aliases = @groups.target_aliases
  Array(target.target_alias).each do |alia|
    if groups.include?(alia)
      raise ValidationError.new("Alias #{alia} conflicts with group of the same name", nil)
    elsif targets.include?(alia)
      raise ValidationError.new("Alias #{alia} conflicts with target of the same name", nil)
    elsif used_aliases[alia] && used_aliases[alia] != target.name
      raise ValidationError.new(
        "Alias #{alia} refers to multiple targets: #{used_aliases[alia]} and #{target.name}", nil
      )
    end
  end
end

#vars(target) ⇒ Object



291
292
293
# File 'lib/bolt/inventory/inventory.rb', line 291

def vars(target)
  @targets[target.name].vars
end

#versionObject



34
35
36
# File 'lib/bolt/inventory/inventory.rb', line 34

def version
  2
end