cloud-mu 3.1.3 → 3.1.4
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/Dockerfile +10 -2
- data/bin/mu-adopt +5 -1
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-run-tests +112 -27
- data/cloud-mu.gemspec +20 -20
- data/cookbooks/mu-tools/libraries/helper.rb +2 -1
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +5 -15
- data/modules/mu.rb +10 -14
- data/modules/mu/adoption.rb +20 -14
- data/modules/mu/cleanup.rb +13 -9
- data/modules/mu/cloud.rb +26 -26
- data/modules/mu/clouds/aws.rb +100 -59
- data/modules/mu/clouds/aws/alarm.rb +4 -2
- data/modules/mu/clouds/aws/bucket.rb +25 -21
- data/modules/mu/clouds/aws/cache_cluster.rb +25 -23
- data/modules/mu/clouds/aws/collection.rb +21 -20
- data/modules/mu/clouds/aws/container_cluster.rb +47 -26
- data/modules/mu/clouds/aws/database.rb +57 -68
- data/modules/mu/clouds/aws/dnszone.rb +14 -14
- data/modules/mu/clouds/aws/endpoint.rb +20 -16
- data/modules/mu/clouds/aws/firewall_rule.rb +19 -16
- data/modules/mu/clouds/aws/folder.rb +7 -7
- data/modules/mu/clouds/aws/function.rb +15 -12
- data/modules/mu/clouds/aws/group.rb +14 -10
- data/modules/mu/clouds/aws/habitat.rb +16 -13
- data/modules/mu/clouds/aws/loadbalancer.rb +16 -15
- data/modules/mu/clouds/aws/log.rb +13 -10
- data/modules/mu/clouds/aws/msg_queue.rb +15 -8
- data/modules/mu/clouds/aws/nosqldb.rb +18 -11
- data/modules/mu/clouds/aws/notifier.rb +11 -6
- data/modules/mu/clouds/aws/role.rb +87 -70
- data/modules/mu/clouds/aws/search_domain.rb +30 -19
- data/modules/mu/clouds/aws/server.rb +102 -72
- data/modules/mu/clouds/aws/server_pool.rb +47 -28
- data/modules/mu/clouds/aws/storage_pool.rb +5 -6
- data/modules/mu/clouds/aws/user.rb +13 -10
- data/modules/mu/clouds/aws/vpc.rb +135 -121
- data/modules/mu/clouds/azure.rb +16 -9
- data/modules/mu/clouds/azure/container_cluster.rb +2 -3
- data/modules/mu/clouds/azure/firewall_rule.rb +10 -10
- data/modules/mu/clouds/azure/habitat.rb +8 -6
- data/modules/mu/clouds/azure/loadbalancer.rb +5 -5
- data/modules/mu/clouds/azure/role.rb +8 -10
- data/modules/mu/clouds/azure/server.rb +65 -25
- data/modules/mu/clouds/azure/user.rb +5 -7
- data/modules/mu/clouds/azure/vpc.rb +12 -15
- data/modules/mu/clouds/cloudformation.rb +8 -7
- data/modules/mu/clouds/cloudformation/vpc.rb +2 -4
- data/modules/mu/clouds/google.rb +39 -24
- data/modules/mu/clouds/google/bucket.rb +9 -11
- data/modules/mu/clouds/google/container_cluster.rb +27 -42
- data/modules/mu/clouds/google/database.rb +6 -9
- data/modules/mu/clouds/google/firewall_rule.rb +11 -10
- data/modules/mu/clouds/google/folder.rb +16 -9
- data/modules/mu/clouds/google/function.rb +127 -161
- data/modules/mu/clouds/google/group.rb +21 -18
- data/modules/mu/clouds/google/habitat.rb +18 -15
- data/modules/mu/clouds/google/loadbalancer.rb +14 -16
- data/modules/mu/clouds/google/role.rb +48 -31
- data/modules/mu/clouds/google/server.rb +105 -105
- data/modules/mu/clouds/google/server_pool.rb +12 -31
- data/modules/mu/clouds/google/user.rb +67 -13
- data/modules/mu/clouds/google/vpc.rb +58 -65
- data/modules/mu/config.rb +89 -1738
- data/modules/mu/config/bucket.rb +3 -3
- data/modules/mu/config/collection.rb +3 -3
- data/modules/mu/config/container_cluster.rb +2 -2
- data/modules/mu/config/dnszone.rb +5 -5
- data/modules/mu/config/doc_helpers.rb +517 -0
- data/modules/mu/config/endpoint.rb +3 -3
- data/modules/mu/config/firewall_rule.rb +118 -3
- data/modules/mu/config/folder.rb +3 -3
- data/modules/mu/config/function.rb +2 -2
- data/modules/mu/config/group.rb +3 -3
- data/modules/mu/config/habitat.rb +3 -3
- data/modules/mu/config/loadbalancer.rb +3 -3
- data/modules/mu/config/log.rb +3 -3
- data/modules/mu/config/msg_queue.rb +3 -3
- data/modules/mu/config/nosqldb.rb +3 -3
- data/modules/mu/config/notifier.rb +2 -2
- data/modules/mu/config/ref.rb +333 -0
- data/modules/mu/config/role.rb +3 -3
- data/modules/mu/config/schema_helpers.rb +508 -0
- data/modules/mu/config/search_domain.rb +3 -3
- data/modules/mu/config/server.rb +86 -58
- data/modules/mu/config/server_pool.rb +2 -2
- data/modules/mu/config/tail.rb +189 -0
- data/modules/mu/config/user.rb +3 -3
- data/modules/mu/config/vpc.rb +44 -4
- data/modules/mu/defaults/Google.yaml +2 -2
- data/modules/mu/deploy.rb +13 -10
- data/modules/mu/groomer.rb +1 -1
- data/modules/mu/groomers/ansible.rb +69 -24
- data/modules/mu/groomers/chef.rb +52 -44
- data/modules/mu/logger.rb +17 -14
- data/modules/mu/master.rb +317 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -2
- data/modules/mu/mommacat.rb +85 -1766
- data/modules/mu/mommacat/daemon.rb +394 -0
- data/modules/mu/mommacat/naming.rb +366 -0
- data/modules/mu/mommacat/storage.rb +689 -0
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/{win2k12.yaml → needwork/win2k12.yaml} +0 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- metadata +112 -102
|
@@ -47,10 +47,10 @@ module MU
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Generic pre-processing of {MU::Config::BasketofKittens::search_domains}, bare and unvalidated.
|
|
50
|
-
# @param
|
|
51
|
-
# @param
|
|
50
|
+
# @param _dom [Hash]: The resource to process and validate
|
|
51
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
|
52
52
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
|
53
|
-
def self.validate(
|
|
53
|
+
def self.validate(_dom, _configurator)
|
|
54
54
|
ok = true
|
|
55
55
|
# This resource basically only exists in AWS, so the validation lives
|
|
56
56
|
# there. If some other provider comes up with it we can factor
|
data/modules/mu/config/server.rb
CHANGED
|
@@ -17,6 +17,65 @@ module MU
|
|
|
17
17
|
# Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/server.rb
|
|
18
18
|
class Server
|
|
19
19
|
|
|
20
|
+
# Verify that a server or server_pool has a valid LDAP config referencing
|
|
21
|
+
# valid Vaults for credentials.
|
|
22
|
+
# @param server [Hash]
|
|
23
|
+
def self.checkVaultRefs(server)
|
|
24
|
+
ok = true
|
|
25
|
+
server['vault_access'] = [] if server['vault_access'].nil?
|
|
26
|
+
server['groomer'] ||= self.defaultGroomer
|
|
27
|
+
groomclass = MU::Groomer.loadGroomer(server['groomer'])
|
|
28
|
+
|
|
29
|
+
begin
|
|
30
|
+
if !server['active_directory'].nil?
|
|
31
|
+
["domain_admin_vault", "domain_join_vault"].each { |vault_class|
|
|
32
|
+
server['vault_access'] << {
|
|
33
|
+
"vault" => server['active_directory'][vault_class]['vault'],
|
|
34
|
+
"item" => server['active_directory'][vault_class]['item']
|
|
35
|
+
}
|
|
36
|
+
item = groomclass.getSecret(
|
|
37
|
+
vault: server['active_directory'][vault_class]['vault'],
|
|
38
|
+
item: server['active_directory'][vault_class]['item'],
|
|
39
|
+
)
|
|
40
|
+
["username_field", "password_field"].each { |field|
|
|
41
|
+
if !item.has_key?(server['active_directory'][vault_class][field])
|
|
42
|
+
ok = false
|
|
43
|
+
MU.log "I don't see a value named #{field} in Chef Vault #{server['active_directory'][vault_class]['vault']}:#{server['active_directory'][vault_class]['item']}", MU::ERR
|
|
44
|
+
end
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if !server['windows_auth_vault'].nil?
|
|
50
|
+
server['use_cloud_provider_windows_password'] = false
|
|
51
|
+
|
|
52
|
+
server['vault_access'] << {
|
|
53
|
+
"vault" => server['windows_auth_vault']['vault'],
|
|
54
|
+
"item" => server['windows_auth_vault']['item']
|
|
55
|
+
}
|
|
56
|
+
item = groomclass.getSecret(
|
|
57
|
+
vault: server['windows_auth_vault']['vault'],
|
|
58
|
+
item: server['windows_auth_vault']['item']
|
|
59
|
+
)
|
|
60
|
+
["password_field", "ec2config_password_field", "sshd_password_field"].each { |field|
|
|
61
|
+
if !item.has_key?(server['windows_auth_vault'][field])
|
|
62
|
+
MU.log "No value named #{field} in Chef Vault #{server['windows_auth_vault']['vault']}:#{server['windows_auth_vault']['item']}, will use a generated password.", MU::NOTICE
|
|
63
|
+
server['windows_auth_vault'].delete(field)
|
|
64
|
+
end
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
# Check all of the non-special ones while we're at it
|
|
68
|
+
server['vault_access'].each { |v|
|
|
69
|
+
next if v['vault'] == "splunk" and v['item'] == "admin_user"
|
|
70
|
+
item = groomclass.getSecret(vault: v['vault'], item: v['item'])
|
|
71
|
+
}
|
|
72
|
+
rescue MuError
|
|
73
|
+
MU.log "Can't load a Chef Vault I was configured to use. Does it exist?", MU::ERR
|
|
74
|
+
ok = false
|
|
75
|
+
end
|
|
76
|
+
return ok
|
|
77
|
+
end
|
|
78
|
+
|
|
20
79
|
# Generate schema for a storage volume
|
|
21
80
|
# @return [Hash]
|
|
22
81
|
def self.storage_primitive
|
|
@@ -332,9 +391,8 @@ module MU
|
|
|
332
391
|
},
|
|
333
392
|
"userdata_script" => userdata_primitive,
|
|
334
393
|
"windows_admin_username" => {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
"description" => "Use an alternate Windows account for Administrator functions. Will change the name of the Administrator account, if it has not already been done."
|
|
394
|
+
"type" => "string",
|
|
395
|
+
"description" => "Use an alternate Windows account for Administrator functions. Will change the name of the Administrator account, if it has not already been done."
|
|
338
396
|
},
|
|
339
397
|
"windows_auth_vault" => {
|
|
340
398
|
"type" => "object",
|
|
@@ -370,60 +428,30 @@ module MU
|
|
|
370
428
|
}
|
|
371
429
|
},
|
|
372
430
|
"ssh_user" => {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
"key_is" => "platform",
|
|
398
|
-
"value_is" => "ubuntu",
|
|
399
|
-
"set" => "ubuntu"
|
|
400
|
-
},
|
|
401
|
-
{
|
|
402
|
-
"key_is" => "platform",
|
|
403
|
-
"value_is" => "ubuntu14",
|
|
404
|
-
"set" => "ubuntu"
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
"key_is" => "platform",
|
|
408
|
-
"value_is" => "centos7",
|
|
409
|
-
"set" => "centos"
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
"key_is" => "platform",
|
|
413
|
-
"value_is" => "rhel7",
|
|
414
|
-
"set" => "ec2-user"
|
|
415
|
-
},
|
|
416
|
-
{
|
|
417
|
-
"key_is" => "platform",
|
|
418
|
-
"value_is" => "rhel71",
|
|
419
|
-
"set" => "ec2-user"
|
|
420
|
-
},
|
|
421
|
-
{
|
|
422
|
-
"key_is" => "platform",
|
|
423
|
-
"value_is" => "amazon",
|
|
424
|
-
"set" => "ec2-user"
|
|
425
|
-
}
|
|
426
|
-
]
|
|
431
|
+
"type" => "string",
|
|
432
|
+
"default" => "root",
|
|
433
|
+
"default_if" => [
|
|
434
|
+
{
|
|
435
|
+
"key_is" => "platform",
|
|
436
|
+
"value_is" => "centos",
|
|
437
|
+
"set" => "centos"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"key_is" => "platform",
|
|
441
|
+
"value_is" => "centos6",
|
|
442
|
+
"set" => "centos"
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
"key_is" => "platform",
|
|
446
|
+
"value_is" => "centos7",
|
|
447
|
+
"set" => "centos"
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
"key_is" => "platform",
|
|
451
|
+
"value_is" => "centos8",
|
|
452
|
+
"set" => "centos"
|
|
453
|
+
}
|
|
454
|
+
]
|
|
427
455
|
},
|
|
428
456
|
"use_cloud_provider_windows_password" => {
|
|
429
457
|
"type" => "boolean",
|
|
@@ -595,7 +623,7 @@ module MU
|
|
|
595
623
|
server['ingress_rules'] ||= []
|
|
596
624
|
server['vault_access'] ||= []
|
|
597
625
|
server['vault_access'] << {"vault" => "splunk", "item" => "admin_user"}
|
|
598
|
-
ok = false if !MU::Config.
|
|
626
|
+
ok = false if !MU::Config::Server.checkVaultRefs(server)
|
|
599
627
|
|
|
600
628
|
if server["cloud"] != "Azure"
|
|
601
629
|
server['dependencies'] << configurator.adminFirewallRuleset(vpc: server['vpc'], region: server['region'], cloud: server['cloud'], credentials: server['credentials'])
|
|
@@ -178,7 +178,7 @@ module MU
|
|
|
178
178
|
pool['ingress_rules'] ||= []
|
|
179
179
|
pool['vault_access'] ||= []
|
|
180
180
|
pool['vault_access'] << {"vault" => "splunk", "item" => "admin_user"}
|
|
181
|
-
ok = false if !MU::Config.
|
|
181
|
+
ok = false if !MU::Config::Server.checkVaultRefs(pool)
|
|
182
182
|
|
|
183
183
|
if !pool['scrub_mu_isms'] and pool["cloud"] != "Azure"
|
|
184
184
|
pool['dependencies'] << configurator.adminFirewallRuleset(vpc: pool['vpc'], region: pool['region'], cloud: pool['cloud'], credentials: pool['credentials'])
|
|
@@ -202,7 +202,7 @@ module MU
|
|
|
202
202
|
# ok = false if !insertKitten(alarm, "alarms")
|
|
203
203
|
# }
|
|
204
204
|
# end
|
|
205
|
-
if pool["basis"]["server"]
|
|
205
|
+
if pool["basis"] and pool["basis"]["server"]
|
|
206
206
|
pool["dependencies"] << {"type" => "server", "name" => pool["basis"]["server"]}
|
|
207
207
|
end
|
|
208
208
|
if !pool['static_ip'].nil? and !pool['ip'].nil?
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Copyright:: Copyright (c) 2020 eGlobalTech, Inc., all rights reserved
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the BSD-3 license (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License in the root of the project or at
|
|
6
|
+
#
|
|
7
|
+
# http://egt-labs.com/mu/LICENSE.html
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
module MU
|
|
16
|
+
|
|
17
|
+
# Methods and structures for parsing Mu's configuration files. See also {MU::Config::BasketofKittens}.
|
|
18
|
+
class Config
|
|
19
|
+
|
|
20
|
+
# A wrapper for config leaves that came from ERB parameters instead of raw
|
|
21
|
+
# YAML or JSON. Will behave like a string for things that expect that
|
|
22
|
+
# sort of thing. Code that needs to know that this leaf was the result of
|
|
23
|
+
# a parameter will be able to tell by the object class being something
|
|
24
|
+
# other than a plain string, array, or hash.
|
|
25
|
+
class Tail
|
|
26
|
+
@value = nil
|
|
27
|
+
@name = nil
|
|
28
|
+
@prettyname = nil
|
|
29
|
+
@description = nil
|
|
30
|
+
@prefix = ""
|
|
31
|
+
@suffix = ""
|
|
32
|
+
@is_list_element = false
|
|
33
|
+
@pseudo = false
|
|
34
|
+
@runtimecode = nil
|
|
35
|
+
@valid_values = []
|
|
36
|
+
@index = 0
|
|
37
|
+
attr_reader :description
|
|
38
|
+
attr_reader :pseudo
|
|
39
|
+
attr_reader :index
|
|
40
|
+
attr_reader :value
|
|
41
|
+
attr_reader :runtimecode
|
|
42
|
+
attr_reader :valid_values
|
|
43
|
+
attr_reader :is_list_element
|
|
44
|
+
|
|
45
|
+
def initialize(name, value, prettyname = nil, cloudtype = "String", valid_values = [], description = "", is_list_element = false, prefix: "", suffix: "", pseudo: false, runtimecode: nil, index: 0)
|
|
46
|
+
@name = name
|
|
47
|
+
@bindings = {}
|
|
48
|
+
@value = value
|
|
49
|
+
@valid_values = valid_values
|
|
50
|
+
@pseudo = pseudo
|
|
51
|
+
@index = index
|
|
52
|
+
@runtimecode = runtimecode
|
|
53
|
+
@cloudtype = cloudtype
|
|
54
|
+
@is_list_element = is_list_element
|
|
55
|
+
@description ||=
|
|
56
|
+
if !description.nil?
|
|
57
|
+
description
|
|
58
|
+
else
|
|
59
|
+
""
|
|
60
|
+
end
|
|
61
|
+
@prettyname ||=
|
|
62
|
+
if !prettyname.nil?
|
|
63
|
+
prettyname
|
|
64
|
+
else
|
|
65
|
+
@name.capitalize.gsub(/[^a-z0-9]/i, "")
|
|
66
|
+
end
|
|
67
|
+
@prefix = prefix if !prefix.nil?
|
|
68
|
+
@suffix = suffix if !suffix.nil?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Return the parameter name of this Tail
|
|
72
|
+
def getName
|
|
73
|
+
@name
|
|
74
|
+
end
|
|
75
|
+
# Return the platform-specific cloud type of this Tail
|
|
76
|
+
def getCloudType
|
|
77
|
+
@cloudtype
|
|
78
|
+
end
|
|
79
|
+
# Return the human-friendly name of this Tail
|
|
80
|
+
def getPrettyName
|
|
81
|
+
@prettyname
|
|
82
|
+
end
|
|
83
|
+
# Walk like a String
|
|
84
|
+
def to_s
|
|
85
|
+
@prefix.to_s+@value.to_s+@suffix.to_s
|
|
86
|
+
end
|
|
87
|
+
# Quack like a String
|
|
88
|
+
def to_str
|
|
89
|
+
to_s
|
|
90
|
+
end
|
|
91
|
+
# Upcase like a String
|
|
92
|
+
def upcase
|
|
93
|
+
to_s.upcase
|
|
94
|
+
end
|
|
95
|
+
# Downcase like a String
|
|
96
|
+
def downcase
|
|
97
|
+
to_s.downcase
|
|
98
|
+
end
|
|
99
|
+
# Check for emptiness like a String
|
|
100
|
+
def empty?
|
|
101
|
+
to_s.empty?
|
|
102
|
+
end
|
|
103
|
+
# Match like a String
|
|
104
|
+
def match(*args)
|
|
105
|
+
to_s.match(*args)
|
|
106
|
+
end
|
|
107
|
+
# Check for equality like a String
|
|
108
|
+
def ==(o)
|
|
109
|
+
(o.class == self.class or o.class == "String") && o.to_s == to_s
|
|
110
|
+
end
|
|
111
|
+
# Concatenate like a string
|
|
112
|
+
def +(o)
|
|
113
|
+
return to_s if o.nil?
|
|
114
|
+
to_s + o.to_s
|
|
115
|
+
end
|
|
116
|
+
# Perform global substitutions like a String
|
|
117
|
+
def gsub(*args)
|
|
118
|
+
to_s.gsub(*args)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Wrapper method for creating a {MU::Config::Tail} object as a reference to
|
|
123
|
+
# a parameter that's valid in the loaded configuration.
|
|
124
|
+
# @param param [<String>]: The name of the parameter to which this should be tied.
|
|
125
|
+
# @param value [<String>]: The value of the parameter to return when asked
|
|
126
|
+
# @param prettyname [<String>]: A human-friendly parameter name to be used when generating CloudFormation templates and the like
|
|
127
|
+
# @param cloudtype [<String>]: A platform-specific identifier used by cloud layers to identify a parameter's type, e.g. AWS::EC2::VPC::Id
|
|
128
|
+
# @param valid_values [Array<String>]: A list of acceptable String values for the given parameter.
|
|
129
|
+
# @param description [<String>]: A long-form description of what the parameter does.
|
|
130
|
+
# @param list_of [<String>]: Indicates that the value should be treated as a member of a list (array) by the cloud layer.
|
|
131
|
+
# @param prefix [<String>]: A static String that should be prefixed to the stored value when queried
|
|
132
|
+
# @param suffix [<String>]: A static String that should be appended to the stored value when queried
|
|
133
|
+
# @param pseudo [<Boolean>]: This is a pseudo-parameter, automatically provided, and not available as user input.
|
|
134
|
+
# @param runtimecode [<String>]: Actual code to allow the cloud layer to interpret literally in its own idiom, e.g. '"Ref" : "AWS::StackName"' for CloudFormation
|
|
135
|
+
def getTail(param, value: nil, prettyname: nil, cloudtype: "String", valid_values: [], description: nil, list_of: nil, prefix: "", suffix: "", pseudo: false, runtimecode: nil)
|
|
136
|
+
if value.nil?
|
|
137
|
+
if @@parameters.nil? or !@@parameters.has_key?(param)
|
|
138
|
+
MU.log "Parameter '#{param}' (#{param.class.name}) referenced in config but not provided (#{caller[0]})", MU::DEBUG, details: @@parameters
|
|
139
|
+
return nil
|
|
140
|
+
# raise DeployParamError
|
|
141
|
+
else
|
|
142
|
+
value = @@parameters[param]
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
if !prettyname.nil?
|
|
146
|
+
prettyname.gsub!(/[^a-z0-9]/i, "") # comply with CloudFormation restrictions
|
|
147
|
+
end
|
|
148
|
+
if value.is_a?(MU::Config::Tail)
|
|
149
|
+
MU.log "Parameter #{param} is using a nested parameter as a value. This rarely works, depending on the target cloud. YMMV.", MU::WARN
|
|
150
|
+
tail = MU::Config::Tail.new(param, value, prettyname, cloudtype, valid_values, description, prefix: prefix, suffix: suffix, pseudo: pseudo, runtimecode: runtimecode)
|
|
151
|
+
elsif !list_of.nil? or (@@tails.has_key?(param) and @@tails[param].is_a?(Array))
|
|
152
|
+
tail = []
|
|
153
|
+
count = 0
|
|
154
|
+
value.split(/\s*,\s*/).each { |subval|
|
|
155
|
+
if @@tails.has_key?(param) and !@@tails[param][count].nil?
|
|
156
|
+
subval = @@tails[param][count].values.first.to_s if subval.nil?
|
|
157
|
+
list_of = @@tails[param][count].values.first.getName if list_of.nil?
|
|
158
|
+
prettyname = @@tails[param][count].values.first.getPrettyName if prettyname.nil?
|
|
159
|
+
description = @@tails[param][count].values.first.description if description.nil?
|
|
160
|
+
valid_values = @@tails[param][count].values.first.valid_values if valid_values.nil? or valid_values.empty?
|
|
161
|
+
cloudtype = @@tails[param][count].values.first.getCloudType if @@tails[param][count].values.first.getCloudType != "String"
|
|
162
|
+
end
|
|
163
|
+
prettyname = param.capitalize if prettyname.nil?
|
|
164
|
+
tail << { list_of => MU::Config::Tail.new(list_of, subval, prettyname, cloudtype, valid_values, description, true, pseudo: pseudo, index: count) }
|
|
165
|
+
count = count + 1
|
|
166
|
+
}
|
|
167
|
+
else
|
|
168
|
+
if @@tails.has_key?(param)
|
|
169
|
+
pseudo = @@tails[param].pseudo
|
|
170
|
+
value = @@tails[param].to_s if value.nil?
|
|
171
|
+
prettyname = @@tails[param].getPrettyName if prettyname.nil?
|
|
172
|
+
description = @@tails[param].description if description.nil?
|
|
173
|
+
valid_values = @@tails[param].valid_values if valid_values.nil? or valid_values.empty?
|
|
174
|
+
cloudtype = @@tails[param].getCloudType if @@tails[param].getCloudType != "String"
|
|
175
|
+
end
|
|
176
|
+
tail = MU::Config::Tail.new(param, value, prettyname, cloudtype, valid_values, description, prefix: prefix, suffix: suffix, pseudo: pseudo, runtimecode: runtimecode)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
if valid_values and valid_values.size > 0 and value
|
|
180
|
+
if !valid_values.include?(value)
|
|
181
|
+
raise DeployParamError, "Invalid parameter value '#{value}' supplied for '#{param}'"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
@@tails[param] = tail
|
|
185
|
+
|
|
186
|
+
tail
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
data/modules/mu/config/user.rb
CHANGED
|
@@ -68,10 +68,10 @@ module MU
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
# Generic pre-processing of {MU::Config::BasketofKittens::user}, bare and unvalidated.
|
|
71
|
-
# @param
|
|
72
|
-
# @param
|
|
71
|
+
# @param _user [Hash]: The resource to process and validate
|
|
72
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
|
73
73
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
|
74
|
-
def self.validate(
|
|
74
|
+
def self.validate(_user, _configurator)
|
|
75
75
|
ok = true
|
|
76
76
|
|
|
77
77
|
ok
|
data/modules/mu/config/vpc.rb
CHANGED
|
@@ -418,7 +418,6 @@ module MU
|
|
|
418
418
|
if !vpc['ip_block']
|
|
419
419
|
if configurator.updating and configurator.existing_deploy and
|
|
420
420
|
configurator.existing_deploy.original_config['vpcs']
|
|
421
|
-
pieces = []
|
|
422
421
|
configurator.existing_deploy.original_config['vpcs'].each { |v|
|
|
423
422
|
if v['name'] == vpc['name']
|
|
424
423
|
vpc['ip_block'] = v['ip_block']
|
|
@@ -799,7 +798,7 @@ MU.log "VPC lookup cache hit", MU::WARN, details: vpc_block
|
|
|
799
798
|
end
|
|
800
799
|
@@reference_cache[vpc_block] ||= ext_vpc if ok
|
|
801
800
|
end
|
|
802
|
-
rescue
|
|
801
|
+
rescue StandardError => e
|
|
803
802
|
raise MuError, e.inspect, e.backtrace
|
|
804
803
|
ensure
|
|
805
804
|
if !ext_vpc and vpc_block['cloud'] != "CloudFormation"
|
|
@@ -877,7 +876,7 @@ MU.log "VPC lookup cache hit", MU::WARN, details: vpc_block
|
|
|
877
876
|
tag_key, tag_value = vpc_block['tag'].split(/=/, 2) if !vpc_block['tag'].nil?
|
|
878
877
|
begin
|
|
879
878
|
ext_subnet = ext_vpc.getSubnet(cloud_id: vpc_block['subnet_id'], name: vpc_block['subnet_name'], tag_key: tag_key, tag_value: tag_value)
|
|
880
|
-
rescue MuError
|
|
879
|
+
rescue MuError
|
|
881
880
|
end
|
|
882
881
|
|
|
883
882
|
if ext_subnet.nil?
|
|
@@ -918,7 +917,6 @@ MU.log "VPC lookup cache hit", MU::WARN, details: vpc_block
|
|
|
918
917
|
public_subnets = []
|
|
919
918
|
public_subnets_map = {}
|
|
920
919
|
subnet_ptr = "subnet_id"
|
|
921
|
-
all_subnets = []
|
|
922
920
|
if !is_sibling
|
|
923
921
|
pub = priv = 0
|
|
924
922
|
raise MuError, "No subnets found in #{ext_vpc}" if ext_vpc.subnets.nil?
|
|
@@ -1068,5 +1066,47 @@ MU.log "VPC lookup cache hit", MU::WARN, details: vpc_block
|
|
|
1068
1066
|
end
|
|
1069
1067
|
|
|
1070
1068
|
end
|
|
1069
|
+
|
|
1070
|
+
# Take an IP block and split it into a more-or-less arbitrary number of
|
|
1071
|
+
# subnets.
|
|
1072
|
+
# @param ip_block [String]: CIDR of the network to subdivide
|
|
1073
|
+
# @param subnets_desired [Integer]: Number of subnets we want back
|
|
1074
|
+
# @param max_mask [Integer]: The highest netmask we're allowed to use for a subnet (various by cloud provider)
|
|
1075
|
+
# @return [MU::Config::Tail]: Resulting subnet tails, or nil if an error occurred.
|
|
1076
|
+
def divideNetwork(ip_block, subnets_desired, max_mask = 28)
|
|
1077
|
+
cidr = NetAddr::IPv4Net.parse(ip_block.to_s)
|
|
1078
|
+
|
|
1079
|
+
# Ugly but reliable method of landing on the right subnet size
|
|
1080
|
+
subnet_bits = cidr.netmask.prefix_len
|
|
1081
|
+
begin
|
|
1082
|
+
subnet_bits += 1
|
|
1083
|
+
if subnet_bits > max_mask
|
|
1084
|
+
MU.log "Can't subdivide #{cidr.to_s} into #{subnets_desired.to_s}", MU::ERR
|
|
1085
|
+
raise MuError, "Subnets smaller than /#{max_mask} not permitted"
|
|
1086
|
+
end
|
|
1087
|
+
end while cidr.subnet_count(subnet_bits) < subnets_desired
|
|
1088
|
+
|
|
1089
|
+
if cidr.subnet_count(subnet_bits) > subnets_desired
|
|
1090
|
+
MU.log "Requested #{subnets_desired.to_s} subnets from #{cidr.to_s}, leaving #{(cidr.subnet_count(subnet_bits)-subnets_desired).to_s} unused /#{subnet_bits.to_s}s available", MU::NOTICE
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1093
|
+
begin
|
|
1094
|
+
subnets = []
|
|
1095
|
+
(0..subnets_desired).each { |x|
|
|
1096
|
+
subnets << cidr.nth_subnet(subnet_bits, x).to_s
|
|
1097
|
+
}
|
|
1098
|
+
rescue RuntimeError => e
|
|
1099
|
+
if e.message.match(/exceeds subnets available for allocation/)
|
|
1100
|
+
MU.log e.message, MU::ERR
|
|
1101
|
+
MU.log "I'm attempting to create #{subnets_desired} subnets (one public and one private for each Availability Zone), of #{subnet_size} addresses each, but that's too many for a /#{cidr.netmask.prefix_len} network. Either declare a larger network, or explicitly declare a list of subnets with few enough entries to fit.", MU::ERR
|
|
1102
|
+
return nil
|
|
1103
|
+
else
|
|
1104
|
+
raise e
|
|
1105
|
+
end
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
subnets = getTail("subnetblocks", value: subnets.join(","), cloudtype: "CommaDelimitedList", description: "IP Address ranges to be used for VPC subnets", prettyname: "SubnetIpBlocks", list_of: "ip_block").map { |tail| tail["ip_block"] }
|
|
1109
|
+
subnets
|
|
1110
|
+
end
|
|
1071
1111
|
end
|
|
1072
1112
|
end
|