cloud-mu 3.1.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +15 -3
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +10 -13
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +135 -37
- data/cloud-mu.gemspec +22 -20
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +3 -2
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +6 -16
- data/modules/mu.rb +165 -111
- data/modules/mu/adoption.rb +401 -68
- data/modules/mu/cleanup.rb +199 -306
- data/modules/mu/cloud.rb +100 -1632
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +46 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +920 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +165 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +4 -4
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +83 -104
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +6 -6
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +4 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +3 -3
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/loadbalancer.rb +60 -14
- data/modules/mu/config/log.rb +4 -4
- data/modules/mu/config/msg_queue.rb +4 -4
- data/modules/mu/config/nosqldb.rb +4 -4
- data/modules/mu/config/notifier.rb +3 -3
- data/modules/mu/config/ref.rb +365 -0
- data/modules/mu/config/role.rb +4 -4
- data/modules/mu/config/schema_helpers.rb +509 -0
- data/modules/mu/config/search_domain.rb +4 -4
- data/modules/mu/config/server.rb +97 -70
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +5 -9
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +200 -0
- data/modules/mu/config/user.rb +4 -4
- data/modules/mu/config/vpc.rb +70 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +83 -60
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +30 -26
- data/modules/mu/groomer.rb +17 -2
- data/modules/mu/groomers/ansible.rb +188 -41
- data/modules/mu/groomers/chef.rb +116 -55
- data/modules/mu/logger.rb +127 -148
- data/modules/mu/master.rb +389 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -3
- data/modules/mu/mommacat.rb +217 -2612
- data/modules/mu/mommacat/daemon.rb +397 -0
- data/modules/mu/mommacat/naming.rb +473 -0
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +722 -0
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +271 -112
- data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
- data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
- data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
- data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
- data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
- data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
- data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
- data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
- data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
- data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
- data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +29 -9
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
- data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
- data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
- data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
- data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +67 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
- data/modules/mu/{clouds → providers}/google/database.rb +10 -20
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
- data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
- data/modules/mu/{clouds → providers}/google/function.rb +139 -167
- data/modules/mu/{clouds → providers}/google/group.rb +29 -34
- data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
- data/modules/mu/{clouds → providers}/google/role.rb +92 -58
- data/modules/mu/{clouds → providers}/google/server.rb +242 -155
- data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
- data/modules/mu/{clouds → providers}/google/user.rb +95 -31
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +11 -0
- data/modules/tests/centos7.yaml +11 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -0
- data/modules/tests/super_simple_bok.yml +1 -3
- data/modules/tests/win2k12.yaml +17 -5
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +232 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
@@ -15,7 +15,7 @@
|
|
15
15
|
module MU
|
16
16
|
class Cloud
|
17
17
|
class AWS
|
18
|
-
# A log as configured in {MU::Config::BasketofKittens::
|
18
|
+
# A log as configured in {MU::Config::BasketofKittens::folders}
|
19
19
|
class Folder < MU::Cloud::Folder
|
20
20
|
|
21
21
|
# Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
|
@@ -78,20 +78,20 @@ module MU
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# Cloud-specific configuration properties.
|
81
|
-
# @param
|
81
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
82
82
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
83
|
-
def self.schema(
|
83
|
+
def self.schema(_config)
|
84
84
|
toplevel_required = []
|
85
85
|
schema = {
|
86
86
|
}
|
87
87
|
[toplevel_required, schema]
|
88
88
|
end
|
89
89
|
|
90
|
-
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::
|
91
|
-
# @param
|
92
|
-
# @param
|
90
|
+
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::folders}, bare and unvalidated.
|
91
|
+
# @param _folder [Hash]: The resource to process and validate
|
92
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
93
93
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
94
|
-
def self.validateConfig(
|
94
|
+
def self.validateConfig(_folder, _configurator)
|
95
95
|
ok = true
|
96
96
|
|
97
97
|
ok
|
@@ -29,12 +29,12 @@ module MU
|
|
29
29
|
def assign_tag(resource_arn, tag_list, region=@config['region'])
|
30
30
|
begin
|
31
31
|
tag_list.each do |each_pair|
|
32
|
-
|
32
|
+
MU::Cloud::AWS.lambda(region: region, credentials: @config['credentials']).tag_resource({
|
33
33
|
resource: resource_arn,
|
34
34
|
tags: each_pair
|
35
35
|
})
|
36
36
|
end
|
37
|
-
rescue
|
37
|
+
rescue StandardError => e
|
38
38
|
MU.log e, MU::ERR
|
39
39
|
end
|
40
40
|
end
|
@@ -153,7 +153,7 @@ module MU
|
|
153
153
|
|
154
154
|
MU.log trigger_properties, MU::DEBUG
|
155
155
|
begin
|
156
|
-
|
156
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).add_permission(trigger_properties)
|
157
157
|
rescue Aws::Lambda::Errors::ResourceConflictException
|
158
158
|
end
|
159
159
|
adjust_trigger(tr['service'], trigger_arn, func_arn, @mu_name)
|
@@ -176,7 +176,7 @@ module MU
|
|
176
176
|
begin
|
177
177
|
# XXX There doesn't seem to be an API call to list or view existing
|
178
178
|
# permissions, wtaf. This means we can't intelligently guard this.
|
179
|
-
|
179
|
+
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).add_permission(trigger)
|
180
180
|
rescue Aws::Lambda::Errors::ResourceConflictException => e
|
181
181
|
if e.message.match(/already exists/)
|
182
182
|
MU::Cloud::AWS.lambda(region: @config['region'], credentials: @config['credentials']).remove_permission(
|
@@ -220,15 +220,15 @@ module MU
|
|
220
220
|
|
221
221
|
when 'sns'
|
222
222
|
# XXX don't do this, use MU::Cloud::AWS::Notification
|
223
|
-
sns_client = MU::Cloud::AWS.sns(region:
|
224
|
-
|
223
|
+
sns_client = MU::Cloud::AWS.sns(region: region, credentials: @config['credentials'])
|
224
|
+
sns_client.subscribe({
|
225
225
|
topic_arn: trig_arn,
|
226
226
|
protocol: protocol,
|
227
227
|
endpoint: func_arn
|
228
228
|
})
|
229
229
|
when 'event','cloudwatch_event', 'events'
|
230
230
|
# XXX don't do this, use MU::Cloud::AWS::Log
|
231
|
-
|
231
|
+
MU::Cloud::AWS.cloudwatch_events(region: region, credentials: @config['credentials']).put_targets({
|
232
232
|
rule: @config['trigger']['name'],
|
233
233
|
targets: [
|
234
234
|
{
|
@@ -271,11 +271,13 @@ module MU
|
|
271
271
|
# @param region [String]: The cloud provider region
|
272
272
|
# @return [void]
|
273
273
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
274
|
+
MU.log "AWS::Function.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
275
|
+
|
274
276
|
MU::Cloud::AWS.lambda(credentials: credentials, region: region).list_functions.functions.each { |f|
|
275
277
|
desc = MU::Cloud::AWS.lambda(credentials: credentials, region: region).get_function(
|
276
278
|
function_name: f.function_name
|
277
279
|
)
|
278
|
-
if desc.tags and desc.tags["MU-ID"] == MU.deploy_id
|
280
|
+
if desc.tags and desc.tags["MU-ID"] == MU.deploy_id and (desc.tags["MU-MASTER-IP"] == MU.mu_public_ip or ignoremaster)
|
279
281
|
MU.log "Deleting Lambda function #{f.function_name}"
|
280
282
|
if !noop
|
281
283
|
MU::Cloud::AWS.lambda(credentials: credentials, region: region).delete_function(
|
@@ -312,7 +314,7 @@ module MU
|
|
312
314
|
# Reverse-map our cloud description into a runnable config hash.
|
313
315
|
# We assume that any values we have in +@config+ are placeholders, and
|
314
316
|
# calculate our own accordingly based on what's live in the cloud.
|
315
|
-
def toKitten(
|
317
|
+
def toKitten(**_args)
|
316
318
|
bok = {
|
317
319
|
"cloud" => "AWS",
|
318
320
|
"credentials" => @config['credentials'],
|
@@ -407,9 +409,9 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
407
409
|
|
408
410
|
|
409
411
|
# Cloud-specific configuration properties.
|
410
|
-
# @param
|
412
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
411
413
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
412
|
-
def self.schema(
|
414
|
+
def self.schema(_config)
|
413
415
|
toplevel_required = ["runtime"]
|
414
416
|
schema = {
|
415
417
|
"triggers" => {
|
@@ -437,6 +439,7 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
437
439
|
},
|
438
440
|
"code" => {
|
439
441
|
"type" => "object",
|
442
|
+
"description" => "Zipped deployment package to upload to our function.",
|
440
443
|
"properties" => {
|
441
444
|
"s3_bucket" => {
|
442
445
|
"type" => "string",
|
@@ -502,11 +505,7 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
502
505
|
function["add_firewall_rules"] << {"name" => fwname}
|
503
506
|
function["permissions"] ||= []
|
504
507
|
function["permissions"] << "network"
|
505
|
-
function
|
506
|
-
function['dependencies'] << {
|
507
|
-
"name" => fwname,
|
508
|
-
"type" => "firewall_rule"
|
509
|
-
}
|
508
|
+
MU::Config.addDependency(function, fwname, "firewall_rule")
|
510
509
|
end
|
511
510
|
|
512
511
|
if !function['iam_role']
|
@@ -538,13 +537,9 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
538
537
|
}
|
539
538
|
configurator.insertKitten(roledesc, "roles")
|
540
539
|
|
541
|
-
function['dependencies'] ||= []
|
542
540
|
function['iam_role'] = function['name']+"execrole"
|
543
541
|
|
544
|
-
function['
|
545
|
-
"type" => "role",
|
546
|
-
"name" => function['name']+"execrole"
|
547
|
-
}
|
542
|
+
MU::Config.addDependency(function, function['name']+"execrole", "role")
|
548
543
|
end
|
549
544
|
|
550
545
|
ok
|
@@ -565,7 +560,7 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
|
|
565
560
|
role_name: name.to_s
|
566
561
|
})
|
567
562
|
return role['role']['arn']
|
568
|
-
rescue
|
563
|
+
rescue StandardError => e
|
569
564
|
MU.log "#{e}", MU::ERR
|
570
565
|
end
|
571
566
|
nil
|
@@ -39,7 +39,7 @@ module MU
|
|
39
39
|
if !@config['use_if_exists']
|
40
40
|
raise MuError, "IAM group #{@mu_name} already exists and use_if_exists is false"
|
41
41
|
end
|
42
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
42
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
43
43
|
@config['path'] ||= "/"+@deploy.deploy_id+"/"
|
44
44
|
MU.log "Creating IAM group #{@config['path']}#{@mu_name}"
|
45
45
|
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_group(
|
@@ -60,7 +60,7 @@ module MU
|
|
60
60
|
userid = user
|
61
61
|
userdesc = @deploy.findLitterMate(name: user, type: "users")
|
62
62
|
userid = userdesc.cloud_id if userdesc
|
63
|
-
found = MU::Cloud
|
63
|
+
found = MU::Cloud.resourceClass("AWS", "User").find(cloud_id: userid)
|
64
64
|
if found.size == 1
|
65
65
|
userdesc = found.values.first
|
66
66
|
MU.log "Adding IAM user #{userdesc.path}#{userdesc.user_name} to group #{@mu_name}", MU::NOTICE
|
@@ -88,7 +88,7 @@ module MU
|
|
88
88
|
# Create these if necessary, then append them to the list of
|
89
89
|
# attachable_policies
|
90
90
|
if @config['raw_policies']
|
91
|
-
pol_arns = MU::Cloud
|
91
|
+
pol_arns = MU::Cloud.resourceClass("AWS", "Role").manageRawPolicies(
|
92
92
|
@config['raw_policies'],
|
93
93
|
basename: @deploy.getResourceName(@config['name']),
|
94
94
|
credentials: @credentials
|
@@ -99,7 +99,7 @@ module MU
|
|
99
99
|
|
100
100
|
if @config['attachable_policies']
|
101
101
|
configured_policies = @config['attachable_policies'].map { |p|
|
102
|
-
|
102
|
+
if p.is_a?(MU::Config::Ref)
|
103
103
|
p.cloud_id
|
104
104
|
else
|
105
105
|
p = MU::Config::Ref.get(p)
|
@@ -114,7 +114,7 @@ module MU
|
|
114
114
|
attached_policies.each { |a|
|
115
115
|
if !configured_policies.include?(a.policy_arn)
|
116
116
|
MU.log "Removing IAM policy #{a.policy_arn} from group #{@mu_name}", MU::NOTICE
|
117
|
-
MU::Cloud
|
117
|
+
MU::Cloud.resourceClass("AWS", "Role").purgePolicy(a.policy_arn, @credentials)
|
118
118
|
else
|
119
119
|
configured_policies.delete(a.policy_arn)
|
120
120
|
end
|
@@ -131,7 +131,7 @@ module MU
|
|
131
131
|
end
|
132
132
|
|
133
133
|
if @config['inline_policies']
|
134
|
-
docs = MU::Cloud
|
134
|
+
docs = MU::Cloud.resourceClass("AWS", "Role").genPolicyDocument(@config['inline_policies'], deploy_obj: @deploy)
|
135
135
|
docs.each { |doc|
|
136
136
|
MU.log "Putting user policy #{doc.keys.first} to group #{@cloud_id} "
|
137
137
|
MU::Cloud::AWS.iam(credentials: @credentials).put_group_policy(
|
@@ -150,13 +150,15 @@ module MU
|
|
150
150
|
cloud_desc.arn
|
151
151
|
end
|
152
152
|
|
153
|
-
|
153
|
+
@cloud_desc_cache = nil
|
154
154
|
# Fetch the AWS API description of this group
|
155
155
|
# return [Struct]
|
156
|
-
def cloud_desc
|
157
|
-
|
156
|
+
def cloud_desc(use_cache: true)
|
157
|
+
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
158
|
+
@cloud_desc_cache = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_group(
|
158
159
|
group_name: @mu_name
|
159
160
|
)
|
161
|
+
@cloud_desc_cache
|
160
162
|
end
|
161
163
|
|
162
164
|
# Return the metadata for this group configuration
|
@@ -183,9 +185,11 @@ module MU
|
|
183
185
|
# Remove all groups associated with the currently loaded deployment.
|
184
186
|
# @param noop [Boolean]: If true, will only print what would be done
|
185
187
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
186
|
-
# @param region [String]: The cloud provider region
|
187
188
|
# @return [void]
|
188
|
-
def self.cleanup(noop: false, ignoremaster: false,
|
189
|
+
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
190
|
+
MU.log "AWS::Group.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
191
|
+
MU.log "Placeholder: AWS Group artifacts do not support tags, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: ignoremaster
|
192
|
+
|
189
193
|
resp = MU::Cloud::AWS.iam(credentials: credentials).list_groups(
|
190
194
|
path_prefix: "/"+MU.deploy_id+"/"
|
191
195
|
)
|
@@ -259,7 +263,7 @@ module MU
|
|
259
263
|
# Reverse-map our cloud description into a runnable config hash.
|
260
264
|
# We assume that any values we have in +@config+ are placeholders, and
|
261
265
|
# calculate our own accordingly based on what's live in the cloud.
|
262
|
-
def toKitten(
|
266
|
+
def toKitten(**_args)
|
263
267
|
bok = {
|
264
268
|
"cloud" => "AWS",
|
265
269
|
"credentials" => @config['credentials'],
|
@@ -287,7 +291,7 @@ module MU
|
|
287
291
|
resp.policy_names.each { |pol_name|
|
288
292
|
pol = MU::Cloud::AWS.iam(credentials: @credentials).get_group_policy(group_name: @cloud_id, policy_name: pol_name)
|
289
293
|
doc = JSON.parse(URI.decode(pol.policy_document))
|
290
|
-
bok["inline_policies"] = MU::Cloud
|
294
|
+
bok["inline_policies"] = MU::Cloud.resourceClass("AWS", "Role").doc2MuPolicies(pol.policy_name, doc, bok["inline_policies"])
|
291
295
|
}
|
292
296
|
end
|
293
297
|
|
@@ -315,12 +319,12 @@ module MU
|
|
315
319
|
end
|
316
320
|
|
317
321
|
# Cloud-specific configuration properties.
|
318
|
-
# @param
|
322
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
319
323
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
320
|
-
def self.schema(
|
324
|
+
def self.schema(_config)
|
321
325
|
toplevel_required = []
|
322
326
|
polschema = MU::Config::Role.schema["properties"]["policies"]
|
323
|
-
polschema.deep_merge!(MU::Cloud
|
327
|
+
polschema.deep_merge!(MU::Cloud.resourceClass("AWS", "Role").condition_schema)
|
324
328
|
|
325
329
|
schema = {
|
326
330
|
"inline_policies" => polschema,
|
@@ -360,7 +364,7 @@ style long name, like +IAMTESTS-DEV-2018112815-IS-GROUP-FOO+. This parameter wil
|
|
360
364
|
# If we're attaching some managed policies, make sure all of the ones
|
361
365
|
# that should already exist do indeed exist
|
362
366
|
if group['attachable_policies']
|
363
|
-
ok = false if !MU::Cloud
|
367
|
+
ok = false if !MU::Cloud.resourceClass("AWS", "Role").validateAttachablePolicies(
|
364
368
|
group['attachable_policies'],
|
365
369
|
credentials: group['credentials'],
|
366
370
|
region: group['region']
|
@@ -374,13 +378,9 @@ style long name, like +IAMTESTS-DEV-2018112815-IS-GROUP-FOO+. This parameter wil
|
|
374
378
|
if group['members']
|
375
379
|
group['members'].each { |user|
|
376
380
|
if configurator.haveLitterMate?(user, "users")
|
377
|
-
group
|
378
|
-
group["dependencies"] << {
|
379
|
-
"type" => "user",
|
380
|
-
"name" => user
|
381
|
-
}
|
381
|
+
MU::Config.addDependency(group, user, "user")
|
382
382
|
else
|
383
|
-
found = MU::Cloud
|
383
|
+
found = MU::Cloud.resourceClass("AWS", "User").find(cloud_id: user)
|
384
384
|
if found.nil? or found.empty?
|
385
385
|
MU.log "Error in members for group #{group['name']}: No such user #{user}", MU::ERR
|
386
386
|
ok = false
|
@@ -45,7 +45,6 @@ module MU
|
|
45
45
|
resp = MU::Cloud::AWS.orgs(credentials: @config['credentials']).describe_create_account_status(
|
46
46
|
create_account_request_id: createid
|
47
47
|
)
|
48
|
-
createstatus = resp.create_account_status.state
|
49
48
|
if !["SUCCEEDED", "IN_PROGRESS"].include?(resp.create_account_status.state)
|
50
49
|
raise MuError, "Failed to create account #{@mu_name}: #{resp.create_account_status.failure_reason}"
|
51
50
|
end
|
@@ -59,9 +58,12 @@ module MU
|
|
59
58
|
MU.log "Creation of account #{@mu_name} (#{resp.create_account_status.account_id}) complete"
|
60
59
|
end
|
61
60
|
|
61
|
+
@cloud_desc_cache = nil
|
62
62
|
# Return the cloud descriptor for the Habitat
|
63
|
-
def cloud_desc
|
64
|
-
|
63
|
+
def cloud_desc(use_cache: true)
|
64
|
+
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
65
|
+
@cloud_desc_cache = MU::Cloud::AWS::Habitat.find(cloud_id: @cloud_id).values.first
|
66
|
+
@cloud_desc_cache
|
65
67
|
end
|
66
68
|
|
67
69
|
# Canonical Amazon Resource Number for this resource
|
@@ -87,10 +89,11 @@ module MU
|
|
87
89
|
# Remove all AWS accounts associated with the currently loaded deployment. Try to, anyway.
|
88
90
|
# @param noop [Boolean]: If true, will only print what would be done
|
89
91
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
90
|
-
# @param region [String]: The cloud provider region
|
91
92
|
# @return [void]
|
92
|
-
def self.cleanup(noop: false, ignoremaster: false,
|
93
|
+
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
93
94
|
return if !orgMasterCreds?(credentials)
|
95
|
+
MU.log "AWS::Habitat.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
96
|
+
MU.log "Placeholder: AWS Habitat artifacts do not support tags, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: ignoremaster
|
94
97
|
|
95
98
|
resp = MU::Cloud::AWS.orgs(credentials: credentials).list_accounts
|
96
99
|
|
@@ -108,14 +111,14 @@ module MU
|
|
108
111
|
|
109
112
|
# Locate an existing account
|
110
113
|
# @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching account
|
111
|
-
def self.find(**
|
114
|
+
def self.find(**_args)
|
112
115
|
{}
|
113
116
|
end
|
114
117
|
|
115
118
|
# Cloud-specific configuration properties.
|
116
|
-
# @param
|
119
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
117
120
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
118
|
-
def self.schema(
|
121
|
+
def self.schema(_config)
|
119
122
|
toplevel_required = []
|
120
123
|
schema = {
|
121
124
|
"email" => {
|
@@ -126,9 +129,10 @@ module MU
|
|
126
129
|
[toplevel_required, schema]
|
127
130
|
end
|
128
131
|
|
129
|
-
# @param
|
132
|
+
# @param _account_number [String]
|
133
|
+
# @param _credentials [String]
|
130
134
|
# @return [Boolean]
|
131
|
-
def self.isLive?(
|
135
|
+
def self.isLive?(_account_number, _credentials = nil)
|
132
136
|
true
|
133
137
|
end
|
134
138
|
|
@@ -138,18 +142,17 @@ module MU
|
|
138
142
|
# @param credentials [String]
|
139
143
|
# @return [Boolean]
|
140
144
|
def self.orgMasterCreds?(credentials = nil)
|
141
|
-
user_list = MU::Cloud::AWS.iam(credentials: credentials).list_users.users
|
142
145
|
acct_num = MU::Cloud::AWS.iam(credentials: credentials).list_users.users.first.arn.split(/:/)[4]
|
143
146
|
|
144
|
-
parentorg = MU::Cloud
|
147
|
+
parentorg = MU::Cloud.resourceClass("AWS", "Folder").find(credentials: credentials).values.first
|
145
148
|
acct_num == parentorg.master_account_id
|
146
149
|
end
|
147
150
|
|
148
151
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::habitats}, bare and unvalidated.
|
149
152
|
# @param habitat [Hash]: The resource to process and validate
|
150
|
-
# @param
|
153
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
151
154
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
152
|
-
def self.validateConfig(habitat,
|
155
|
+
def self.validateConfig(habitat, _configurator)
|
153
156
|
ok = true
|
154
157
|
|
155
158
|
if !habitat["email"]
|
@@ -163,7 +163,7 @@ module MU
|
|
163
163
|
dnsthread = Thread.new {
|
164
164
|
if !MU::Cloud::AWS.isGovCloud?
|
165
165
|
MU.dupGlobals(parent_thread_id)
|
166
|
-
generic_mu_dns = MU::Cloud
|
166
|
+
generic_mu_dns = MU::Cloud.resourceClass("AWS", "DNSZone").genericMuDNSEntry(name: @mu_name, target: "#{lb.dns_name}.", cloudclass: MU::Cloud::LoadBalancer, sync_wait: @config['dns_sync_wait'])
|
167
167
|
end
|
168
168
|
}
|
169
169
|
|
@@ -239,16 +239,35 @@ module MU
|
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
242
|
+
redirect_block = Proc.new { |r|
|
243
|
+
{
|
244
|
+
:protocol => r['protocol'],
|
245
|
+
:port => r['port'].to_s,
|
246
|
+
:host => r['host'],
|
247
|
+
:path => r['path'],
|
248
|
+
:query => r['query'],
|
249
|
+
:status_code => "HTTP_"+r['status_code'].to_s
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
242
253
|
if !@config['classic']
|
243
254
|
@config["listeners"].each { |l|
|
244
|
-
if
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
255
|
+
action = if l['redirect']
|
256
|
+
{
|
257
|
+
:type => "redirect",
|
258
|
+
:redirect_config => redirect_block.call(l['redirect'])
|
259
|
+
}
|
260
|
+
else
|
261
|
+
if !@targetgroups.has_key?(l['targetgroup'])
|
262
|
+
raise MuError, "Listener in #{@mu_name} configured for target group #{l['targetgroup']}, but I don't have data on a targetgroup by that name"
|
263
|
+
end
|
264
|
+
{
|
249
265
|
:target_group_arn => @targetgroups[l['targetgroup']].target_group_arn,
|
250
266
|
:type => "forward"
|
251
|
-
}
|
267
|
+
}
|
268
|
+
end
|
269
|
+
listen_descriptor = {
|
270
|
+
:default_actions => [ action ],
|
252
271
|
:load_balancer_arn => lb.load_balancer_arn,
|
253
272
|
:port => l['lb_port'],
|
254
273
|
:protocol => l['lb_protocol']
|
@@ -276,10 +295,17 @@ module MU
|
|
276
295
|
:actions => []
|
277
296
|
}
|
278
297
|
rule['actions'].each { |a|
|
279
|
-
rule_descriptor[:actions] <<
|
280
|
-
|
281
|
-
|
282
|
-
|
298
|
+
rule_descriptor[:actions] << if a['action'] == "forward"
|
299
|
+
{
|
300
|
+
:target_group_arn => @targetgroups[a['targetgroup']].target_group_arn,
|
301
|
+
:type => a['action']
|
302
|
+
}
|
303
|
+
elsif a['action'] == "redirect"
|
304
|
+
{
|
305
|
+
:redirect_config => redirect_block.call(rule['redirect']),
|
306
|
+
:type => a['action']
|
307
|
+
}
|
308
|
+
end
|
283
309
|
}
|
284
310
|
MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).create_rule(rule_descriptor)
|
285
311
|
}
|
@@ -288,7 +314,7 @@ module MU
|
|
288
314
|
else
|
289
315
|
@config["listeners"].each { |l|
|
290
316
|
if l['ssl_certificate_id']
|
291
|
-
|
317
|
+
MU::Cloud::AWS.elb(region: @config['region'], credentials: @config['credentials']).set_load_balancer_policies_of_listener(
|
292
318
|
load_balancer_name: @cloud_id,
|
293
319
|
load_balancer_port: l['lb_port'],
|
294
320
|
policy_names: [
|
@@ -330,7 +356,7 @@ module MU
|
|
330
356
|
}
|
331
357
|
)
|
332
358
|
else
|
333
|
-
@targetgroups.
|
359
|
+
@targetgroups.values.each { |tg|
|
334
360
|
MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).modify_target_group_attributes(
|
335
361
|
target_group_arn: tg.target_group_arn,
|
336
362
|
attributes: [
|
@@ -400,7 +426,7 @@ module MU
|
|
400
426
|
timeout = 0
|
401
427
|
MU.log "Disabling connection draining on #{lb.dns_name}"
|
402
428
|
end
|
403
|
-
@targetgroups.
|
429
|
+
@targetgroups.values.each { |tg|
|
404
430
|
MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).modify_target_group_attributes(
|
405
431
|
target_group_arn: tg.target_group_arn,
|
406
432
|
attributes: [
|
@@ -473,7 +499,7 @@ module MU
|
|
473
499
|
end
|
474
500
|
end
|
475
501
|
else
|
476
|
-
@targetgroups.
|
502
|
+
@targetgroups.values.each { |tg|
|
477
503
|
MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).modify_target_group_attributes(
|
478
504
|
target_group_arn: tg.target_group_arn,
|
479
505
|
attributes: [
|
@@ -536,7 +562,7 @@ module MU
|
|
536
562
|
}
|
537
563
|
end
|
538
564
|
if !MU::Cloud::AWS.isGovCloud?
|
539
|
-
MU::Cloud
|
565
|
+
MU::Cloud.resourceClass("AWS", "DNSZone").createRecordsFromConfig(@config['dns_records'], target: cloud_desc.dns_name)
|
540
566
|
end
|
541
567
|
end
|
542
568
|
|
@@ -553,15 +579,17 @@ module MU
|
|
553
579
|
end
|
554
580
|
end
|
555
581
|
|
582
|
+
@cloud_desc_cache = nil
|
556
583
|
# Wrapper for cloud_desc method that deals with elb vs. elb2 resources.
|
557
|
-
def cloud_desc
|
584
|
+
def cloud_desc(use_cache: true)
|
585
|
+
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
558
586
|
if @config['classic']
|
559
|
-
|
587
|
+
@cloud_desc_cache = MU::Cloud::AWS.elb(region: @config['region'], credentials: @config['credentials']).describe_load_balancers(
|
560
588
|
load_balancer_names: [@cloud_id]
|
561
589
|
).load_balancer_descriptions.first
|
562
|
-
return
|
590
|
+
return @cloud_desc_cache
|
563
591
|
else
|
564
|
-
|
592
|
+
@cloud_desc_cache = MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).describe_load_balancers(
|
565
593
|
names: [@cloud_id]
|
566
594
|
).load_balancers.first
|
567
595
|
if @targetgroups.nil? and !@deploy.nil? and
|
@@ -573,7 +601,7 @@ module MU
|
|
573
601
|
}
|
574
602
|
end
|
575
603
|
|
576
|
-
return
|
604
|
+
return @cloud_desc_cache
|
577
605
|
end
|
578
606
|
end
|
579
607
|
|
@@ -692,7 +720,6 @@ module MU
|
|
692
720
|
classic = false
|
693
721
|
end
|
694
722
|
begin
|
695
|
-
tags = []
|
696
723
|
matched = false
|
697
724
|
if flags and flags['vpc_id']
|
698
725
|
matched = true if lb.vpc_id == flags['vpc_id']
|
@@ -705,7 +732,7 @@ module MU
|
|
705
732
|
end
|
706
733
|
if matched
|
707
734
|
if !MU::Cloud::AWS.isGovCloud?
|
708
|
-
MU::Cloud
|
735
|
+
MU::Cloud.resourceClass("AWS", "DNSZone").genericMuDNSEntry(name: lb.load_balancer_name, target: lb.dns_name, cloudclass: MU::Cloud::LoadBalancer, delete: true) if !noop
|
709
736
|
end
|
710
737
|
if classic
|
711
738
|
MU.log "Removing Elastic Load Balancer #{lb.load_balancer_name}"
|
@@ -773,9 +800,9 @@ module MU
|
|
773
800
|
end
|
774
801
|
|
775
802
|
# Cloud-specific configuration properties.
|
776
|
-
# @param
|
803
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
777
804
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
778
|
-
def self.schema(
|
805
|
+
def self.schema(_config)
|
779
806
|
toplevel_required = []
|
780
807
|
schema = {
|
781
808
|
"targetgroups" => {
|
@@ -792,35 +819,16 @@ module MU
|
|
792
819
|
}
|
793
820
|
}
|
794
821
|
},
|
795
|
-
"ingress_rules" =>
|
796
|
-
"items" => {
|
797
|
-
"properties" => {
|
798
|
-
"sgs" => {
|
799
|
-
"type" => "array",
|
800
|
-
"items" => {
|
801
|
-
"description" => "Other AWS Security Groups; resources that are associated with this group will have this rule applied to their traffic",
|
802
|
-
"type" => "string"
|
803
|
-
}
|
804
|
-
},
|
805
|
-
"lbs" => {
|
806
|
-
"type" => "array",
|
807
|
-
"items" => {
|
808
|
-
"description" => "AWS Load Balancers which will have this rule applied to their traffic",
|
809
|
-
"type" => "string"
|
810
|
-
}
|
811
|
-
}
|
812
|
-
}
|
813
|
-
}
|
814
|
-
}
|
822
|
+
"ingress_rules" => MU::Cloud.resourceClass("AWS", "FirewallRule").ingressRuleAddtlSchema
|
815
823
|
}
|
816
824
|
[toplevel_required, schema]
|
817
825
|
end
|
818
826
|
|
819
827
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::loadbalancers}, bare and unvalidated.
|
820
828
|
# @param lb [Hash]: The resource to process and validate
|
821
|
-
# @param
|
829
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
822
830
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
823
|
-
def self.validateConfig(lb,
|
831
|
+
def self.validateConfig(lb, _configurator)
|
824
832
|
ok = true
|
825
833
|
|
826
834
|
# XXX what about raw targetgroup ssl declarations?
|
@@ -830,7 +838,7 @@ module MU
|
|
830
838
|
if lb['cloud'] != "CloudFormation" # XXX or maybe do this anyway?
|
831
839
|
begin
|
832
840
|
listener["ssl_certificate_id"] = MU::Cloud::AWS.findSSLCertificate(name: listener["ssl_certificate_name"].to_s, id: listener["ssl_certificate_id"].to_s, region: lb['region'])
|
833
|
-
rescue MuError
|
841
|
+
rescue MuError
|
834
842
|
ok = false
|
835
843
|
next
|
836
844
|
end
|
@@ -922,6 +930,7 @@ module MU
|
|
922
930
|
return matches
|
923
931
|
|
924
932
|
end
|
933
|
+
|
925
934
|
end
|
926
935
|
end
|
927
936
|
end
|