leap_cli 1.8.1 → 1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/leap +6 -12
- data/lib/leap_cli.rb +3 -23
- data/lib/leap_cli/bootstrap.rb +36 -12
- data/lib/leap_cli/commands/common.rb +88 -46
- data/lib/leap_cli/commands/new.rb +24 -17
- data/lib/leap_cli/commands/pre.rb +3 -1
- data/lib/leap_cli/core_ext/hash.rb +19 -0
- data/lib/leap_cli/leapfile.rb +47 -32
- data/lib/leap_cli/log.rb +196 -88
- data/lib/leap_cli/path.rb +5 -5
- data/lib/leap_cli/util.rb +28 -18
- data/lib/leap_cli/version.rb +8 -3
- data/vendor/acme-client/lib/acme-client.rb +1 -0
- data/vendor/acme-client/lib/acme/client.rb +122 -0
- data/vendor/acme-client/lib/acme/client/certificate.rb +30 -0
- data/vendor/acme-client/lib/acme/client/certificate_request.rb +111 -0
- data/vendor/acme-client/lib/acme/client/crypto.rb +98 -0
- data/vendor/acme-client/lib/acme/client/error.rb +16 -0
- data/vendor/acme-client/lib/acme/client/faraday_middleware.rb +123 -0
- data/vendor/acme-client/lib/acme/client/resources.rb +5 -0
- data/vendor/acme-client/lib/acme/client/resources/authorization.rb +44 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges.rb +6 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/base.rb +43 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb +19 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb +18 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb +24 -0
- data/vendor/acme-client/lib/acme/client/resources/registration.rb +37 -0
- data/vendor/acme-client/lib/acme/client/self_sign_certificate.rb +60 -0
- data/vendor/acme-client/lib/acme/client/version.rb +7 -0
- data/vendor/base32/lib/base32.rb +67 -0
- data/vendor/certificate_authority/lib/certificate_authority.rb +2 -1
- data/vendor/certificate_authority/lib/certificate_authority/certificate.rb +4 -4
- data/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb +7 -5
- data/vendor/certificate_authority/lib/certificate_authority/core_extensions.rb +46 -0
- data/vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb +6 -2
- data/vendor/certificate_authority/lib/certificate_authority/extensions.rb +10 -3
- data/vendor/certificate_authority/lib/certificate_authority/key_material.rb +11 -9
- data/vendor/certificate_authority/lib/certificate_authority/ocsp_handler.rb +3 -3
- data/vendor/certificate_authority/lib/certificate_authority/pkcs11_key_material.rb +0 -2
- data/vendor/certificate_authority/lib/certificate_authority/serial_number.rb +8 -2
- data/vendor/certificate_authority/lib/certificate_authority/validations.rb +31 -0
- data/vendor/rsync_command/lib/rsync_command.rb +49 -12
- metadata +50 -91
- data/lib/leap/platform.rb +0 -90
- data/lib/leap_cli/config/environment.rb +0 -180
- data/lib/leap_cli/config/filter.rb +0 -178
- data/lib/leap_cli/config/manager.rb +0 -419
- data/lib/leap_cli/config/node.rb +0 -77
- data/lib/leap_cli/config/object.rb +0 -428
- data/lib/leap_cli/config/object_list.rb +0 -209
- data/lib/leap_cli/config/provider.rb +0 -22
- data/lib/leap_cli/config/secrets.rb +0 -87
- data/lib/leap_cli/config/sources.rb +0 -11
- data/lib/leap_cli/config/tag.rb +0 -25
- data/lib/leap_cli/lib_ext/capistrano_connections.rb +0 -16
- data/lib/leap_cli/logger.rb +0 -237
- data/lib/leap_cli/remote/leap_plugin.rb +0 -192
- data/lib/leap_cli/remote/puppet_plugin.rb +0 -26
- data/lib/leap_cli/remote/rsync_plugin.rb +0 -35
- data/lib/leap_cli/remote/tasks.rb +0 -51
- data/lib/leap_cli/ssh_key.rb +0 -195
- data/lib/leap_cli/util/remote_command.rb +0 -158
- data/lib/leap_cli/util/secret.rb +0 -55
- data/lib/leap_cli/util/x509.rb +0 -33
@@ -1,178 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Many leap_cli commands accept a list of filters to select a subset of nodes for the command to
|
3
|
-
# be applied to. This class is a helper for manager to run these filters.
|
4
|
-
#
|
5
|
-
# Classes other than Manager should not use this class.
|
6
|
-
#
|
7
|
-
# Filter rules:
|
8
|
-
#
|
9
|
-
# * A filter consists of a list of tokens
|
10
|
-
# * A token may be a service name, tag name, environment name, or node name.
|
11
|
-
# * Each token may be optionally prefixed with a plus sign.
|
12
|
-
# * Multiple tokens with a plus are treated as an OR condition,
|
13
|
-
# but treated as an AND condition with the plus sign.
|
14
|
-
#
|
15
|
-
# For example
|
16
|
-
#
|
17
|
-
# * openvpn +development => all nodes with service 'openvpn' AND environment 'development'
|
18
|
-
# * openvpn seattle => all nodes with service 'openvpn' OR tag 'seattle'.
|
19
|
-
#
|
20
|
-
# There can only be one environment specified. Typically, there are also tags
|
21
|
-
# for each environment name. These name are treated as environments, not tags.
|
22
|
-
#
|
23
|
-
module LeapCli
|
24
|
-
module Config
|
25
|
-
class Filter
|
26
|
-
|
27
|
-
#
|
28
|
-
# filter -- array of strings, each one a filter
|
29
|
-
# options -- hash, possible keys include
|
30
|
-
# :nopin -- disregard environment pinning
|
31
|
-
# :local -- if false, disallow local nodes
|
32
|
-
#
|
33
|
-
# A nil value in the filters array indicates
|
34
|
-
# the default environment. This is in order to support
|
35
|
-
# calls like `manager.filter(environments)`
|
36
|
-
#
|
37
|
-
def initialize(filters, options, manager)
|
38
|
-
@filters = filters.nil? ? [] : filters.dup
|
39
|
-
@environments = []
|
40
|
-
@options = options
|
41
|
-
@manager = manager
|
42
|
-
|
43
|
-
# split filters by pulling out items that happen
|
44
|
-
# to be environment names.
|
45
|
-
if LeapCli.leapfile.environment.nil? || @options[:nopin]
|
46
|
-
@environments = []
|
47
|
-
else
|
48
|
-
@environments = [LeapCli.leapfile.environment]
|
49
|
-
end
|
50
|
-
@filters.select! do |filter|
|
51
|
-
if filter.nil?
|
52
|
-
@environments << nil unless @environments.include?(nil)
|
53
|
-
false
|
54
|
-
else
|
55
|
-
filter_text = filter.sub(/^\+/,'')
|
56
|
-
if is_environment?(filter_text)
|
57
|
-
if filter_text == LeapCli.leapfile.environment
|
58
|
-
# silently ignore already pinned environments
|
59
|
-
elsif (filter =~ /^\+/ || @filters.first == filter) && !@environments.empty?
|
60
|
-
LeapCli::Util.bail! do
|
61
|
-
LeapCli::Util.log "Environments are exclusive: no node is in two environments." do
|
62
|
-
LeapCli::Util.log "Tried to filter on '#{@environments.join('\' AND \'')}' AND '#{filter_text}'"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
else
|
66
|
-
@environments << filter_text
|
67
|
-
end
|
68
|
-
false
|
69
|
-
else
|
70
|
-
true
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# don't let the first filter have a + prefix
|
76
|
-
if @filters[0] =~ /^\+/
|
77
|
-
@filters[0] = @filters[0][1..-1]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# actually run the filter, returns a filtered list of nodes
|
82
|
-
def nodes()
|
83
|
-
if @filters.empty?
|
84
|
-
return nodes_for_empty_filter
|
85
|
-
else
|
86
|
-
return nodes_for_filter
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
def nodes_for_empty_filter
|
93
|
-
node_list = @manager.nodes
|
94
|
-
if @environments.any?
|
95
|
-
node_list = node_list[ @environments.collect{|e|[:environment, env_to_filter(e)]} ]
|
96
|
-
end
|
97
|
-
if @options[:local] === false
|
98
|
-
node_list = node_list[:environment => '!local']
|
99
|
-
end
|
100
|
-
if @options[:disabled] === false
|
101
|
-
node_list = node_list[:environment => '!disabled']
|
102
|
-
end
|
103
|
-
node_list
|
104
|
-
end
|
105
|
-
|
106
|
-
def nodes_for_filter
|
107
|
-
node_list = Config::ObjectList.new
|
108
|
-
@filters.each do |filter|
|
109
|
-
if filter =~ /^\+/
|
110
|
-
keep_list = nodes_for_name(filter[1..-1])
|
111
|
-
node_list.delete_if do |name, node|
|
112
|
-
if keep_list[name]
|
113
|
-
false
|
114
|
-
else
|
115
|
-
true
|
116
|
-
end
|
117
|
-
end
|
118
|
-
else
|
119
|
-
node_list.merge!(nodes_for_name(filter))
|
120
|
-
end
|
121
|
-
end
|
122
|
-
node_list
|
123
|
-
end
|
124
|
-
|
125
|
-
private
|
126
|
-
|
127
|
-
#
|
128
|
-
# returns a set of nodes corresponding to a single name,
|
129
|
-
# where name could be a node name, service name, or tag name.
|
130
|
-
#
|
131
|
-
# For services and tags, we only include nodes for the
|
132
|
-
# environments that are active
|
133
|
-
#
|
134
|
-
def nodes_for_name(name)
|
135
|
-
if node = @manager.nodes[name]
|
136
|
-
return Config::ObjectList.new(node)
|
137
|
-
elsif @environments.empty?
|
138
|
-
if @manager.services[name]
|
139
|
-
return @manager.env('_all_').services[name].node_list
|
140
|
-
elsif @manager.tags[name]
|
141
|
-
return @manager.env('_all_').tags[name].node_list
|
142
|
-
else
|
143
|
-
LeapCli::Util.log :warning, "filter '#{name}' does not match any node names, tags, services, or environments."
|
144
|
-
return Config::ObjectList.new
|
145
|
-
end
|
146
|
-
else
|
147
|
-
node_list = Config::ObjectList.new
|
148
|
-
if @manager.services[name]
|
149
|
-
@environments.each do |env|
|
150
|
-
node_list.merge!(@manager.env(env).services[name].node_list)
|
151
|
-
end
|
152
|
-
elsif @manager.tags[name]
|
153
|
-
@environments.each do |env|
|
154
|
-
node_list.merge!(@manager.env(env).tags[name].node_list)
|
155
|
-
end
|
156
|
-
else
|
157
|
-
LeapCli::Util.log :warning, "filter '#{name}' does not match any node names, tags, services, or environments."
|
158
|
-
end
|
159
|
-
return node_list
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
#
|
164
|
-
# when pinning, we use the name 'default' to specify nodes
|
165
|
-
# without an environment set, but when filtering, we need to filter
|
166
|
-
# on :environment => nil.
|
167
|
-
#
|
168
|
-
def env_to_filter(environment)
|
169
|
-
environment == 'default' ? nil : environment
|
170
|
-
end
|
171
|
-
|
172
|
-
def is_environment?(text)
|
173
|
-
text == 'default' || @manager.environment_names.include?(text)
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
@@ -1,419 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'json/pure'
|
4
|
-
|
5
|
-
if $ruby_version < [1,9]
|
6
|
-
require 'iconv'
|
7
|
-
end
|
8
|
-
|
9
|
-
module LeapCli
|
10
|
-
module Config
|
11
|
-
|
12
|
-
#
|
13
|
-
# A class to manage all the objects in all the configuration files.
|
14
|
-
#
|
15
|
-
class Manager
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
@environments = {} # hash of `Environment` objects, keyed by name.
|
19
|
-
Config::Object.send(:include, LeapCli::Macro)
|
20
|
-
end
|
21
|
-
|
22
|
-
##
|
23
|
-
## ATTRIBUTES
|
24
|
-
##
|
25
|
-
|
26
|
-
#
|
27
|
-
# returns the Hash of the contents of facts.json
|
28
|
-
#
|
29
|
-
def facts
|
30
|
-
@facts ||= begin
|
31
|
-
content = Util.read_file(:facts)
|
32
|
-
if !content || content.empty?
|
33
|
-
content = "{}"
|
34
|
-
end
|
35
|
-
JSON.parse(content)
|
36
|
-
rescue SyntaxError, JSON::ParserError => exc
|
37
|
-
Util::bail! "Could not parse facts.json -- #{exc}"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
#
|
42
|
-
# returns an Array of all the environments defined for this provider.
|
43
|
-
# the returned array includes nil (for the default environment)
|
44
|
-
#
|
45
|
-
def environment_names
|
46
|
-
@environment_names ||= begin
|
47
|
-
[nil] + (env.tags.field('environment') + env.nodes.field('environment')).compact.uniq
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# Returns the appropriate environment variable
|
53
|
-
#
|
54
|
-
def env(env=nil)
|
55
|
-
@environments[env || 'default']
|
56
|
-
end
|
57
|
-
|
58
|
-
#
|
59
|
-
# The default accessors
|
60
|
-
#
|
61
|
-
# For these defaults, use 'default' environment, or whatever
|
62
|
-
# environment is pinned.
|
63
|
-
#
|
64
|
-
# I think it might be an error that these are ever used
|
65
|
-
# and I would like to get rid of them.
|
66
|
-
#
|
67
|
-
def services; env(default_environment).services; end
|
68
|
-
def tags; env(default_environment).tags; end
|
69
|
-
def partials; env(default_environment).partials; end
|
70
|
-
def provider; env(default_environment).provider; end
|
71
|
-
def common; env(default_environment).common; end
|
72
|
-
def secrets; env(default_environment).secrets; end
|
73
|
-
def nodes; env(default_environment).nodes; end
|
74
|
-
def template(*args)
|
75
|
-
self.env.template(*args)
|
76
|
-
end
|
77
|
-
|
78
|
-
def default_environment
|
79
|
-
LeapCli.leapfile.environment
|
80
|
-
end
|
81
|
-
|
82
|
-
##
|
83
|
-
## IMPORT EXPORT
|
84
|
-
##
|
85
|
-
|
86
|
-
def add_environment(args)
|
87
|
-
if args[:inherit]
|
88
|
-
parent = @environments[args.delete(:inherit)]
|
89
|
-
else
|
90
|
-
parent = nil
|
91
|
-
end
|
92
|
-
@environments[args[:name]] = Environment.new(
|
93
|
-
self,
|
94
|
-
args.delete(:name),
|
95
|
-
args.delete(:dir),
|
96
|
-
parent,
|
97
|
-
args
|
98
|
-
)
|
99
|
-
end
|
100
|
-
|
101
|
-
#
|
102
|
-
# load .json configuration files
|
103
|
-
#
|
104
|
-
def load(options = {})
|
105
|
-
@provider_dir = Path.provider
|
106
|
-
|
107
|
-
# load base
|
108
|
-
add_environment(name: '_base_', dir: Path.provider_base)
|
109
|
-
|
110
|
-
# load provider
|
111
|
-
Util::assert_files_exist!(Path.named_path(:provider_config, @provider_dir))
|
112
|
-
add_environment(name: 'default', dir: @provider_dir,
|
113
|
-
inherit: '_base_', no_dots: true)
|
114
|
-
|
115
|
-
# create a special '_all_' environment, used for tracking
|
116
|
-
# the union of all the environments
|
117
|
-
add_environment(name: '_all_', inherit: 'default')
|
118
|
-
|
119
|
-
# load environments
|
120
|
-
environment_names.each do |ename|
|
121
|
-
if ename
|
122
|
-
log 3, :loading, '%s environment...' % ename
|
123
|
-
add_environment(name: ename, dir: @provider_dir,
|
124
|
-
inherit: 'default', scope: ename)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
# apply inheritance
|
129
|
-
env.nodes.each do |name, node|
|
130
|
-
Util::assert! name =~ /^[0-9a-z-]+$/, "Illegal character(s) used in node name '#{name}'"
|
131
|
-
env.nodes[name] = apply_inheritance(node)
|
132
|
-
end
|
133
|
-
|
134
|
-
# do some node-list post-processing
|
135
|
-
cleanup_node_lists(options)
|
136
|
-
|
137
|
-
# apply control files
|
138
|
-
env.nodes.each do |name, node|
|
139
|
-
control_files(node).each do |file|
|
140
|
-
begin
|
141
|
-
node.eval_file file
|
142
|
-
rescue ConfigError => exc
|
143
|
-
if options[:continue_on_error]
|
144
|
-
exc.log
|
145
|
-
else
|
146
|
-
raise exc
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
#
|
154
|
-
# save compiled hiera .yaml files
|
155
|
-
#
|
156
|
-
# if a node_list is specified, only update those .yaml files.
|
157
|
-
# otherwise, update all files, destroying files that are no longer used.
|
158
|
-
#
|
159
|
-
def export_nodes(node_list=nil)
|
160
|
-
updated_hiera = []
|
161
|
-
updated_files = []
|
162
|
-
existing_hiera = nil
|
163
|
-
existing_files = nil
|
164
|
-
|
165
|
-
unless node_list
|
166
|
-
node_list = env.nodes
|
167
|
-
existing_hiera = Dir.glob(Path.named_path([:hiera, '*'], @provider_dir))
|
168
|
-
existing_files = Dir.glob(Path.named_path([:node_files_dir, '*'], @provider_dir))
|
169
|
-
end
|
170
|
-
|
171
|
-
node_list.each_node do |node|
|
172
|
-
filepath = Path.named_path([:node_files_dir, node.name], @provider_dir)
|
173
|
-
hierapath = Path.named_path([:hiera, node.name], @provider_dir)
|
174
|
-
Util::write_file!(hierapath, node.dump_yaml)
|
175
|
-
updated_files << filepath
|
176
|
-
updated_hiera << hierapath
|
177
|
-
end
|
178
|
-
|
179
|
-
if @disabled_nodes
|
180
|
-
# make disabled nodes appear as if they are still active
|
181
|
-
@disabled_nodes.each_node do |node|
|
182
|
-
updated_files << Path.named_path([:node_files_dir, node.name], @provider_dir)
|
183
|
-
updated_hiera << Path.named_path([:hiera, node.name], @provider_dir)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
# remove files that are no longer needed
|
188
|
-
if existing_hiera
|
189
|
-
(existing_hiera - updated_hiera).each do |filepath|
|
190
|
-
Util::remove_file!(filepath)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
if existing_files
|
194
|
-
(existing_files - updated_files).each do |filepath|
|
195
|
-
Util::remove_directory!(filepath)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def export_secrets(clean_unused_secrets = false)
|
201
|
-
if env.secrets.any?
|
202
|
-
Util.write_file!([:secrets_config, @provider_dir], env.secrets.dump_json(clean_unused_secrets) + "\n")
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
##
|
207
|
-
## FILTERING
|
208
|
-
##
|
209
|
-
|
210
|
-
#
|
211
|
-
# returns a node list consisting only of nodes that satisfy the filter criteria.
|
212
|
-
#
|
213
|
-
# filter: condition [condition] [condition] [+condition]
|
214
|
-
# condition: [node_name | service_name | tag_name | environment_name]
|
215
|
-
#
|
216
|
-
# if conditions is prefixed with +, then it works like an AND. Otherwise, it works like an OR.
|
217
|
-
#
|
218
|
-
# args:
|
219
|
-
# filter -- array of filter terms, one per item
|
220
|
-
#
|
221
|
-
# options:
|
222
|
-
# :local -- if :local is false and the filter is empty, then local nodes are excluded.
|
223
|
-
# :nopin -- if true, ignore environment pinning
|
224
|
-
#
|
225
|
-
def filter(filters=nil, options={})
|
226
|
-
Filter.new(filters, options, self).nodes()
|
227
|
-
end
|
228
|
-
|
229
|
-
#
|
230
|
-
# same as filter(), but exits if there is no matching nodes
|
231
|
-
#
|
232
|
-
def filter!(filters, options={})
|
233
|
-
node_list = filter(filters, options)
|
234
|
-
Util::assert! node_list.any?, "Could not match any nodes from '#{filters.join ' '}'"
|
235
|
-
return node_list
|
236
|
-
end
|
237
|
-
|
238
|
-
#
|
239
|
-
# returns a single Config::Object that corresponds to a Node.
|
240
|
-
#
|
241
|
-
def node(name)
|
242
|
-
if name =~ /\./
|
243
|
-
# probably got a fqdn, since periods are not allowed in node names.
|
244
|
-
# so, take the part before the first period as the node name
|
245
|
-
name = name.split('.').first
|
246
|
-
end
|
247
|
-
env.nodes[name]
|
248
|
-
end
|
249
|
-
|
250
|
-
#
|
251
|
-
# returns a single node that is disabled
|
252
|
-
#
|
253
|
-
def disabled_node(name)
|
254
|
-
@disabled_nodes[name]
|
255
|
-
end
|
256
|
-
|
257
|
-
#
|
258
|
-
# yields each node, in sorted order
|
259
|
-
#
|
260
|
-
def each_node(&block)
|
261
|
-
env.nodes.each_node &block
|
262
|
-
end
|
263
|
-
|
264
|
-
def reload_node!(node)
|
265
|
-
env.nodes[node.name] = apply_inheritance!(node)
|
266
|
-
end
|
267
|
-
|
268
|
-
##
|
269
|
-
## CONNECTIONS
|
270
|
-
##
|
271
|
-
|
272
|
-
class ConnectionList < Array
|
273
|
-
def add(data={})
|
274
|
-
self << {
|
275
|
-
"from" => data[:from],
|
276
|
-
"to" => data[:to],
|
277
|
-
"port" => data[:port]
|
278
|
-
}
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
def connections
|
283
|
-
@connections ||= ConnectionList.new
|
284
|
-
end
|
285
|
-
|
286
|
-
##
|
287
|
-
## PRIVATE
|
288
|
-
##
|
289
|
-
|
290
|
-
private
|
291
|
-
|
292
|
-
#
|
293
|
-
# makes a node inherit options from appropriate the common, service, and tag json files.
|
294
|
-
#
|
295
|
-
def apply_inheritance(node, throw_exceptions=false)
|
296
|
-
new_node = Config::Node.new(nil)
|
297
|
-
name = node.name
|
298
|
-
node_env = guess_node_env(node)
|
299
|
-
new_node.set_environment(node_env, new_node)
|
300
|
-
|
301
|
-
# inherit from common
|
302
|
-
new_node.deep_merge!(node_env.common)
|
303
|
-
|
304
|
-
# inherit from services
|
305
|
-
if node['services']
|
306
|
-
node['services'].to_a.each do |node_service|
|
307
|
-
service = node_env.services[node_service]
|
308
|
-
if service.nil?
|
309
|
-
msg = 'in node "%s": the service "%s" does not exist.' % [node['name'], node_service]
|
310
|
-
log 0, :error, msg
|
311
|
-
raise LeapCli::ConfigError.new(node, "error " + msg) if throw_exceptions
|
312
|
-
else
|
313
|
-
new_node.deep_merge!(service)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
# inherit from tags
|
319
|
-
if node.vagrant?
|
320
|
-
node['tags'] = (node['tags'] || []).to_a + ['local']
|
321
|
-
end
|
322
|
-
if node['tags']
|
323
|
-
node['tags'].to_a.each do |node_tag|
|
324
|
-
tag = node_env.tags[node_tag]
|
325
|
-
if tag.nil?
|
326
|
-
msg = 'in node "%s": the tag "%s" does not exist.' % [node['name'], node_tag]
|
327
|
-
log 0, :error, msg
|
328
|
-
raise LeapCli::ConfigError.new(node, "error " + msg) if throw_exceptions
|
329
|
-
else
|
330
|
-
new_node.deep_merge!(tag)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
# inherit from node
|
336
|
-
new_node.deep_merge!(node)
|
337
|
-
return new_node
|
338
|
-
end
|
339
|
-
|
340
|
-
def apply_inheritance!(node)
|
341
|
-
apply_inheritance(node, true)
|
342
|
-
end
|
343
|
-
|
344
|
-
#
|
345
|
-
# Guess the environment of the node from the tag names.
|
346
|
-
#
|
347
|
-
# Technically, this is wrong: a tag that sets the environment might not be
|
348
|
-
# named the same as the environment. This code assumes that it is.
|
349
|
-
#
|
350
|
-
# Unfortunately, it is a chicken and egg problem. We need to know the nodes
|
351
|
-
# likely environment in order to apply the inheritance that will actually
|
352
|
-
# determine the node's properties.
|
353
|
-
#
|
354
|
-
def guess_node_env(node)
|
355
|
-
environment = self.env(default_environment)
|
356
|
-
if node['tags']
|
357
|
-
node['tags'].to_a.each do |tag|
|
358
|
-
if self.environment_names.include?(tag)
|
359
|
-
environment = self.env(tag)
|
360
|
-
end
|
361
|
-
end
|
362
|
-
end
|
363
|
-
return environment
|
364
|
-
end
|
365
|
-
|
366
|
-
#
|
367
|
-
# does some final clean at the end of loading nodes.
|
368
|
-
# this includes removing disabled nodes, and populating
|
369
|
-
# the services[x].node_list and tags[x].node_list
|
370
|
-
#
|
371
|
-
def cleanup_node_lists(options)
|
372
|
-
@disabled_nodes = Config::ObjectList.new
|
373
|
-
env.nodes.each do |name, node|
|
374
|
-
if node.enabled || options[:include_disabled]
|
375
|
-
if node['services']
|
376
|
-
node['services'].to_a.each do |node_service|
|
377
|
-
env(node.environment).services[node_service].node_list.add(node.name, node)
|
378
|
-
env('_all_').services[node_service].node_list.add(node.name, node)
|
379
|
-
end
|
380
|
-
end
|
381
|
-
if node['tags']
|
382
|
-
node['tags'].to_a.each do |node_tag|
|
383
|
-
env(node.environment).tags[node_tag].node_list.add(node.name, node)
|
384
|
-
env('_all_').tags[node_tag].node_list.add(node.name, node)
|
385
|
-
end
|
386
|
-
end
|
387
|
-
elsif !options[:include_disabled]
|
388
|
-
log 2, :skipping, "disabled node #{name}."
|
389
|
-
env.nodes.delete(name)
|
390
|
-
@disabled_nodes[name] = node
|
391
|
-
end
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
#
|
396
|
-
# returns a list of 'control' files for this node.
|
397
|
-
# a control file is like a service or a tag JSON file, but it contains
|
398
|
-
# raw ruby code that gets evaluated in the context of the node.
|
399
|
-
# Yes, this entirely breaks our functional programming model
|
400
|
-
# for JSON generation.
|
401
|
-
#
|
402
|
-
def control_files(node)
|
403
|
-
files = []
|
404
|
-
[Path.provider_base, @provider_dir].each do |provider_dir|
|
405
|
-
[['services', :service_config], ['tags', :tag_config]].each do |attribute, path_sym|
|
406
|
-
node[attribute].each do |attr_value|
|
407
|
-
path = Path.named_path([path_sym, "#{attr_value}.rb"], provider_dir).sub(/\.json$/,'')
|
408
|
-
if File.exists?(path)
|
409
|
-
files << path
|
410
|
-
end
|
411
|
-
end
|
412
|
-
end
|
413
|
-
end
|
414
|
-
return files
|
415
|
-
end
|
416
|
-
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|