-
Notifications
You must be signed in to change notification settings - Fork 220
/
inventory.rb
120 lines (100 loc) · 3.54 KB
/
inventory.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
116
117
118
119
120
# frozen_string_literal: true
require 'set'
require_relative '../bolt/config'
require_relative 'inventory/group'
require_relative 'inventory/inventory'
require_relative 'inventory/options'
require_relative '../bolt/target'
require_relative '../bolt/util'
require_relative '../bolt/plugin'
require_relative '../bolt/validator'
require 'yaml'
module Bolt
class Inventory
include Bolt::Inventory::Options
ENVIRONMENT_VAR = 'BOLT_INVENTORY'
class ValidationError < Bolt::Error
attr_accessor :path
def initialize(message, offending_group)
super(message, 'bolt.inventory/validation-error')
@_message = message
@path = [offending_group].compact
end
def details
{ 'path' => path }
end
def add_parent(parent_group)
@path << parent_group
end
def message
if path.empty?
@_message
else
"#{@_message} for group at #{path}"
end
end
end
class WildcardError < Bolt::Error
def initialize(target)
super("Found 0 nodes matching wildcard pattern #{target}", 'bolt.inventory/wildcard-error')
end
end
# Builds the schema used by the validator.
#
def self.schema
schema = {
type: Hash,
properties: OPTIONS.map { |opt| [opt, _ref: opt] }.to_h,
definitions: DEFINITIONS,
_plugin: true
}
schema[:definitions]['config'][:properties] = Bolt::Config.transport_definitions
schema
end
def self.from_config(config, plugins)
logger = Bolt::Logger.logger(self)
if ENV.include?(ENVIRONMENT_VAR)
begin
source = ENVIRONMENT_VAR
data = YAML.safe_load(ENV[ENVIRONMENT_VAR])
raise Bolt::ParseError, "Could not parse inventory from $#{ENVIRONMENT_VAR}" unless data.is_a?(Hash)
logger.debug("Loaded inventory from environment variable #{ENVIRONMENT_VAR}")
rescue Psych::Exception
raise Bolt::ParseError, "Could not parse inventory from $#{ENVIRONMENT_VAR}"
end
elsif config.inventoryfile
source = config.inventoryfile
data = Bolt::Util.read_yaml_hash(config.inventoryfile, 'inventory')
logger.debug("Loaded inventory from #{config.inventoryfile}")
else
source = config.default_inventoryfile
data = Bolt::Util.read_optional_yaml_hash(config.default_inventoryfile, 'inventory')
if config.default_inventoryfile.exist?
logger.debug("Loaded inventory from #{config.default_inventoryfile}")
else
source = nil
logger.debug("Tried to load inventory from #{config.default_inventoryfile}, but the file does not exist")
end
end
Bolt::Validator.new.tap do |validator|
validator.validate(data, schema, source)
validator.warnings.each { |warning| Bolt::Logger.warn(warning[:id], warning[:msg]) }
end
create_version(data, config.transport, config.transports, plugins, source)
end
def self.create_version(data, transport, transports, plugins, source = nil)
version = (data || {}).delete('version') { 2 }
case version
when 2
Bolt::Inventory::Inventory.new(data, transport, transports, plugins, source)
else
raise ValidationError.new("Unsupported version #{version} specified in inventory", nil)
end
end
def self.empty
config = Bolt::Config.default
plugins = Bolt::Plugin.new(config, nil)
create_version({}, config.transport, config.transports, plugins, nil)
end
end
end