cloud-mu 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/bin/mu-adopt +12 -1
- data/bin/mu-load-config.rb +2 -1
- data/bin/mu-run-tests +14 -2
- data/cloud-mu.gemspec +3 -3
- data/modules/mu.rb +2 -2
- data/modules/mu/adoption.rb +5 -5
- data/modules/mu/cleanup.rb +47 -25
- data/modules/mu/cloud.rb +29 -1
- data/modules/mu/cloud/dnszone.rb +0 -2
- data/modules/mu/cloud/resource_base.rb +9 -3
- data/modules/mu/cloud/wrappers.rb +4 -0
- data/modules/mu/config.rb +1 -1
- data/modules/mu/config/bucket.rb +31 -2
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/container_cluster.rb +1 -1
- data/modules/mu/config/database.rb +1 -1
- data/modules/mu/config/dnszone.rb +4 -3
- data/modules/mu/config/endpoint.rb +1 -0
- data/modules/mu/config/function.rb +16 -7
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/notifier.rb +7 -18
- data/modules/mu/config/ref.rb +53 -7
- data/modules/mu/config/server.rb +1 -1
- data/modules/mu/config/vpc.rb +1 -0
- data/modules/mu/defaults/AWS.yaml +26 -26
- data/modules/mu/deploy.rb +13 -0
- data/modules/mu/master.rb +21 -0
- data/modules/mu/mommacat.rb +1 -0
- data/modules/mu/mommacat/daemon.rb +13 -7
- data/modules/mu/providers/aws.rb +115 -16
- data/modules/mu/providers/aws/alarm.rb +2 -2
- data/modules/mu/providers/aws/bucket.rb +274 -40
- data/modules/mu/providers/aws/cache_cluster.rb +4 -4
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/providers/aws/collection.rb +2 -2
- data/modules/mu/providers/aws/container_cluster.rb +57 -37
- data/modules/mu/providers/aws/database.rb +11 -11
- data/modules/mu/providers/aws/dnszone.rb +24 -7
- data/modules/mu/providers/aws/endpoint.rb +535 -50
- data/modules/mu/providers/aws/firewall_rule.rb +6 -3
- data/modules/mu/providers/aws/folder.rb +1 -1
- data/modules/mu/providers/aws/function.rb +288 -125
- data/modules/mu/providers/aws/group.rb +9 -7
- data/modules/mu/providers/aws/habitat.rb +2 -2
- data/modules/mu/providers/aws/job.rb +466 -0
- data/modules/mu/providers/aws/loadbalancer.rb +9 -8
- data/modules/mu/providers/aws/log.rb +3 -3
- data/modules/mu/providers/aws/msg_queue.rb +12 -3
- data/modules/mu/providers/aws/nosqldb.rb +96 -5
- data/modules/mu/providers/aws/notifier.rb +135 -63
- data/modules/mu/providers/aws/role.rb +51 -37
- data/modules/mu/providers/aws/search_domain.rb +165 -29
- data/modules/mu/providers/aws/server.rb +12 -9
- data/modules/mu/providers/aws/server_pool.rb +26 -13
- data/modules/mu/providers/aws/storage_pool.rb +2 -2
- data/modules/mu/providers/aws/user.rb +4 -4
- data/modules/mu/providers/aws/userdata/linux.erb +5 -4
- data/modules/mu/providers/aws/vpc.rb +3 -3
- data/modules/mu/providers/azure/server.rb +2 -1
- data/modules/mu/providers/google.rb +1 -0
- data/modules/mu/providers/google/bucket.rb +1 -1
- data/modules/mu/providers/google/container_cluster.rb +1 -1
- data/modules/mu/providers/google/database.rb +1 -1
- data/modules/mu/providers/google/firewall_rule.rb +1 -1
- data/modules/mu/providers/google/folder.rb +1 -1
- data/modules/mu/providers/google/function.rb +1 -1
- data/modules/mu/providers/google/group.rb +1 -1
- data/modules/mu/providers/google/habitat.rb +1 -1
- data/modules/mu/providers/google/loadbalancer.rb +1 -1
- data/modules/mu/providers/google/role.rb +4 -2
- data/modules/mu/providers/google/server.rb +1 -1
- data/modules/mu/providers/google/server_pool.rb +1 -1
- data/modules/mu/providers/google/user.rb +1 -1
- data/modules/mu/providers/google/vpc.rb +1 -1
- data/modules/tests/aws-jobs-functions.yaml +46 -0
- data/modules/tests/centos6.yaml +4 -0
- data/modules/tests/centos7.yaml +4 -0
- data/modules/tests/ecs.yaml +2 -2
- data/modules/tests/eks.yaml +1 -1
- data/modules/tests/functions/node-function/lambda_function.js +10 -0
- data/modules/tests/functions/python-function/lambda_function.py +12 -0
- data/modules/tests/microservice_app.yaml +288 -0
- data/modules/tests/rds.yaml +5 -5
- data/modules/tests/regrooms/rds.yaml +5 -5
- data/modules/tests/server-with-scrub-muisms.yaml +1 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +2 -2
- metadata +12 -4
@@ -30,7 +30,7 @@ module MU
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
@mu_name ||= @deploy.getResourceName(@config["name"])
|
33
|
+
@mu_name ||= @deploy.getResourceName(@config["name"], max_length: 64)
|
34
34
|
end
|
35
35
|
|
36
36
|
# Called automatically by {MU::Deploy#createResources}
|
@@ -216,7 +216,22 @@ module MU
|
|
216
216
|
# populated with one or both depending on what this resource has
|
217
217
|
# defined.
|
218
218
|
def cloud_desc(use_cache: true)
|
219
|
-
|
219
|
+
|
220
|
+
# we might inherit a naive cached description from the base cloud
|
221
|
+
# layer; rearrange it to our tastes
|
222
|
+
if @cloud_desc_cache.is_a?(::Aws::IAM::Types::Role)
|
223
|
+
new_desc = {
|
224
|
+
"role" => @cloud_desc_cache
|
225
|
+
}
|
226
|
+
@cloud_desc_cache = new_desc
|
227
|
+
elsif @cloud_desc_cache.is_a?(::Aws::IAM::Types::Policy)
|
228
|
+
new_desc = {
|
229
|
+
"policies" => [@cloud_desc_cache]
|
230
|
+
}
|
231
|
+
@cloud_desc_cache = new_desc
|
232
|
+
end
|
233
|
+
|
234
|
+
return @cloud_desc_cache if @cloud_desc_cache and !@cloud_desc_cache.empty? and use_cache
|
220
235
|
|
221
236
|
@cloud_desc_cache = {}
|
222
237
|
if @config['bare_policies']
|
@@ -419,14 +434,14 @@ end
|
|
419
434
|
# @param noop [Boolean]: If true, will only print what would be done
|
420
435
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
421
436
|
# @return [void]
|
422
|
-
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
437
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, credentials: nil, flags: {})
|
423
438
|
|
424
439
|
resp = MU::Cloud::AWS.iam(credentials: credentials).list_policies(
|
425
|
-
path_prefix: "/"+
|
440
|
+
path_prefix: "/"+deploy_id+"/"
|
426
441
|
)
|
427
442
|
if resp and resp.policies
|
428
443
|
resp.policies.each { |policy|
|
429
|
-
MU.log "Deleting IAM policy /#{
|
444
|
+
MU.log "Deleting IAM policy /#{deploy_id}/#{policy.policy_name}"
|
430
445
|
if !noop
|
431
446
|
purgePolicy(policy.arn, credentials)
|
432
447
|
end
|
@@ -437,19 +452,23 @@ end
|
|
437
452
|
roles = MU::Cloud::AWS::Role.find(credentials: credentials).values
|
438
453
|
roles.each { |r|
|
439
454
|
next if !r.respond_to?(:role_name)
|
440
|
-
if r.path.match(/^\/#{Regexp.quote(
|
455
|
+
if r.path.match(/^\/#{Regexp.quote(deploy_id)}/)
|
441
456
|
deleteme << r
|
442
457
|
next
|
443
458
|
end
|
444
459
|
# For some dumb reason, the list output that .find gets doesn't
|
445
460
|
# include the tags, so we need to fetch each role individually to
|
446
461
|
# check tags. Hardly seems efficient.
|
447
|
-
desc =
|
462
|
+
desc = begin
|
463
|
+
MU::Cloud::AWS.iam(credentials: credentials).get_role(role_name: r.role_name)
|
464
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
465
|
+
next
|
466
|
+
end
|
448
467
|
if desc.role and desc.role.tags and desc.role.tags
|
449
468
|
master_match = false
|
450
469
|
deploy_match = false
|
451
470
|
desc.role.tags.each { |t|
|
452
|
-
if t.key == "MU-ID" and t.value ==
|
471
|
+
if t.key == "MU-ID" and t.value == deploy_id
|
453
472
|
deploy_match = true
|
454
473
|
elsif t.key == "MU-MASTER-IP" and t.value == MU.mu_public_ip
|
455
474
|
master_match = true
|
@@ -516,7 +535,7 @@ end
|
|
516
535
|
|
517
536
|
begin
|
518
537
|
# managed policies get fetched by ARN, roles by plain name. Ok!
|
519
|
-
if args[:cloud_id].match(/^arn
|
538
|
+
if args[:cloud_id].match(/^arn:.*?:policy\//)
|
520
539
|
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).get_policy(
|
521
540
|
policy_arn: args[:cloud_id]
|
522
541
|
)
|
@@ -525,39 +544,26 @@ end
|
|
525
544
|
end
|
526
545
|
else
|
527
546
|
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).get_role(
|
528
|
-
role_name: args[:cloud_id]
|
547
|
+
role_name: args[:cloud_id].sub(/^arn:.*?\/([^:\/]+)$/, '\1') # XXX if it's an ARN, actually parse it and look in the correct account when applicable
|
529
548
|
)
|
549
|
+
|
530
550
|
if resp and resp.role
|
531
|
-
found[
|
551
|
+
found[resp.role.role_name] = resp.role
|
532
552
|
end
|
533
553
|
end
|
534
554
|
rescue ::Aws::IAM::Errors::NoSuchEntity
|
535
555
|
end
|
536
556
|
|
537
557
|
else
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
)
|
543
|
-
break if !resp or !resp.roles
|
544
|
-
resp.roles.each { |role|
|
545
|
-
found[role.role_name] = role
|
546
|
-
}
|
547
|
-
marker = resp.marker
|
548
|
-
end while marker
|
558
|
+
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).list_roles
|
559
|
+
resp.roles.each { |role|
|
560
|
+
found[role.role_name] = role
|
561
|
+
}
|
549
562
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
)
|
555
|
-
break if !resp or !resp.policies
|
556
|
-
resp.policies.each { |pol|
|
557
|
-
found[pol.arn] = pol
|
558
|
-
}
|
559
|
-
marker = resp.marker
|
560
|
-
end while marker
|
563
|
+
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).list_policies(scope: "Local")
|
564
|
+
resp.policies.each { |pol|
|
565
|
+
found[pol.arn] = pol
|
566
|
+
}
|
561
567
|
end
|
562
568
|
|
563
569
|
found
|
@@ -1091,7 +1097,7 @@ end
|
|
1091
1097
|
role['policies'].each { |policy|
|
1092
1098
|
policy['targets'].each { |target|
|
1093
1099
|
if target['type']
|
1094
|
-
MU::Config.addDependency(role, target['identifier'], target['type'])
|
1100
|
+
MU::Config.addDependency(role, target['identifier'], target['type'], no_create_wait: true)
|
1095
1101
|
end
|
1096
1102
|
}
|
1097
1103
|
}
|
@@ -1107,13 +1113,14 @@ end
|
|
1107
1113
|
# @param policies [Array<Hash>]: One or more policy chunks
|
1108
1114
|
# @param deploy_obj [MU::MommaCat]: Deployment object to use when looking up sibling Mu resources
|
1109
1115
|
# @return [Array<Hash>]
|
1110
|
-
def self.genPolicyDocument(policies, deploy_obj: nil, bucket_style: false)
|
1116
|
+
def self.genPolicyDocument(policies, deploy_obj: nil, bucket_style: false, version: "2012-10-17", doc_id: nil)
|
1111
1117
|
if policies
|
1112
1118
|
name = nil
|
1113
1119
|
doc = {
|
1114
|
-
"Version" =>
|
1120
|
+
"Version" => version,
|
1115
1121
|
"Statement" => []
|
1116
1122
|
}
|
1123
|
+
doc["Id"] = doc_id if doc_id
|
1117
1124
|
policies.each { |policy|
|
1118
1125
|
policy["flag"] ||= "Allow"
|
1119
1126
|
statement = {
|
@@ -1154,7 +1161,14 @@ end
|
|
1154
1161
|
raise MuError, "Couldn't find a #{grantee["type"]} named #{grantee["identifier"]} when generating IAM policy"
|
1155
1162
|
end
|
1156
1163
|
else
|
1157
|
-
bucket_prefix = grantee["identifier"].match(/^[^\.]+\.amazonaws\.com$/)
|
1164
|
+
bucket_prefix = if grantee["identifier"].match(/^[^\.]+\.amazonaws\.com$/)
|
1165
|
+
"Service"
|
1166
|
+
elsif grantee["identifier"] =~ /^[a-f0-9]+$/
|
1167
|
+
"CanonicalUser"
|
1168
|
+
else
|
1169
|
+
"AWS"
|
1170
|
+
end
|
1171
|
+
|
1158
1172
|
if bucket_style
|
1159
1173
|
statement["Principal"] << { bucket_prefix => grantee["identifier"] }
|
1160
1174
|
else
|
@@ -22,9 +22,9 @@ module MU
|
|
22
22
|
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
23
23
|
def initialize(**args)
|
24
24
|
super
|
25
|
-
if @
|
26
|
-
|
27
|
-
|
25
|
+
describe if @mu_name and !@deploydata
|
26
|
+
@cloud_id ||= @deploydata['domain_name'] if @deploydata
|
27
|
+
|
28
28
|
@mu_name ||= @deploy.getResourceName(@config["name"])
|
29
29
|
end
|
30
30
|
|
@@ -35,7 +35,8 @@ module MU
|
|
35
35
|
params = genParams
|
36
36
|
|
37
37
|
MU.log "Creating ElasticSearch domain #{@config['domain_name']}", details: params
|
38
|
-
|
38
|
+
@cloud_id = @config['domain_name']
|
39
|
+
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).create_elasticsearch_domain(params).domain_status
|
39
40
|
|
40
41
|
tagDomain
|
41
42
|
|
@@ -44,17 +45,18 @@ module MU
|
|
44
45
|
# Called automatically by {MU::Deploy#createResources}
|
45
46
|
def groom
|
46
47
|
tagDomain
|
47
|
-
@config['domain_name'] ||= @
|
48
|
+
@config['domain_name'] ||= @cloud_id
|
48
49
|
params = genParams(cloud_desc) # get parameters that would change only
|
49
50
|
|
50
51
|
if params.size > 1
|
51
52
|
waitWhileProcessing # wait until the create finishes, if still going
|
52
53
|
|
53
54
|
MU.log "Updating ElasticSearch domain #{@config['domain_name']}", MU::NOTICE, details: params
|
54
|
-
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @
|
55
|
+
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).update_elasticsearch_domain_config(params)
|
55
56
|
end
|
56
57
|
|
57
58
|
waitWhileProcessing # don't return until creation/updating is complete
|
59
|
+
MU.log "Search Domain #{@config['name']}: #{cloud_desc.endpoint}", MU::SUMMARY
|
58
60
|
end
|
59
61
|
|
60
62
|
@cloud_desc_cache = nil
|
@@ -63,31 +65,30 @@ module MU
|
|
63
65
|
# our druthers.
|
64
66
|
def cloud_desc(use_cache: true)
|
65
67
|
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
66
|
-
@
|
67
|
-
|
68
|
-
|
68
|
+
@cloud_id ||= @config['domain_name']
|
69
|
+
return nil if !@cloud_id
|
70
|
+
MU.retrier([::Aws::ElasticsearchService::Errors::ResourceNotFoundException], wait: 10, max: 12) {
|
71
|
+
@cloud_desc_cache = MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).describe_elasticsearch_domain(
|
72
|
+
domain_name: @cloud_id
|
69
73
|
).domain_status
|
70
|
-
|
71
|
-
|
72
|
-
domain_name: @deploydata['domain_name']
|
73
|
-
).domain_status
|
74
|
-
else
|
75
|
-
raise MuError, "#{@mu_name} can't find its official Elasticsearch domain name!"
|
76
|
-
end
|
74
|
+
}
|
75
|
+
|
77
76
|
@cloud_desc_cache
|
78
77
|
end
|
79
78
|
|
80
79
|
# Canonical Amazon Resource Number for this resource
|
81
80
|
# @return [String]
|
82
81
|
def arn
|
83
|
-
cloud_desc
|
82
|
+
return nil if !cloud_desc
|
83
|
+
cloud_desc.arn.dup
|
84
84
|
end
|
85
85
|
|
86
86
|
# Return the metadata for this SearchDomain rule
|
87
87
|
# @return [Hash]
|
88
88
|
def notify
|
89
|
-
|
90
|
-
|
89
|
+
return nil if !cloud_desc(use_cache: false)
|
90
|
+
deploy_struct = MU.structToHash(cloud_desc, stringify_keys: true)
|
91
|
+
tags = MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).list_tags(arn: arn).tag_list
|
91
92
|
deploy_struct['tags'] = tags.map { |t| { t.key => t.value } }
|
92
93
|
if deploy_struct['endpoint']
|
93
94
|
deploy_struct['kibana'] = deploy_struct['endpoint']+"/_plugin/kibana/"
|
@@ -119,7 +120,7 @@ module MU
|
|
119
120
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
120
121
|
# @param region [String]: The cloud provider region
|
121
122
|
# @return [void]
|
122
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
123
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
123
124
|
MU.log "AWS::SearchDomain.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
124
125
|
|
125
126
|
list = MU::Cloud::AWS.elasticsearch(region: region, credentials: credentials).list_domain_names
|
@@ -135,7 +136,7 @@ module MU
|
|
135
136
|
deploy_match = false
|
136
137
|
master_match = false
|
137
138
|
tags.tag_list.each { |tag|
|
138
|
-
if tag.key == "MU-ID" and tag.value ==
|
139
|
+
if tag.key == "MU-ID" and tag.value == deploy_id
|
139
140
|
deploy_match = true
|
140
141
|
elsif tag.key == "MU-MASTER-IP" and tag.value == MU.mu_public_ip
|
141
142
|
master_match = true
|
@@ -157,7 +158,7 @@ module MU
|
|
157
158
|
resp = MU::Cloud::AWS.iam(credentials: credentials).list_roles(marker: marker)
|
158
159
|
resp.roles.each{ |role|
|
159
160
|
# XXX Maybe we should have a more generic way to delete IAM profiles and policies. The call itself should be moved from MU::Cloud.resourceClass("AWS", "Server").
|
160
|
-
# MU::Cloud.resourceClass("AWS", "Server").removeIAMProfile(role.role_name) if role.role_name.match(/^#{Regexp.quote(
|
161
|
+
# MU::Cloud.resourceClass("AWS", "Server").removeIAMProfile(role.role_name) if role.role_name.match(/^#{Regexp.quote(deploy_id)}/)
|
161
162
|
}
|
162
163
|
marker = resp.marker
|
163
164
|
end while resp.is_truncated
|
@@ -191,6 +192,96 @@ module MU
|
|
191
192
|
found
|
192
193
|
end
|
193
194
|
|
195
|
+
# Reverse-map our cloud description into a runnable config hash.
|
196
|
+
# We assume that any values we have in +@config+ are placeholders, and
|
197
|
+
# calculate our own accordingly based on what's live in the cloud.
|
198
|
+
def toKitten(**_args)
|
199
|
+
bok = {
|
200
|
+
"cloud" => "AWS",
|
201
|
+
"credentials" => @credentials,
|
202
|
+
"cloud_id" => @cloud_id,
|
203
|
+
"region" => @config['region']
|
204
|
+
}
|
205
|
+
|
206
|
+
if !cloud_desc
|
207
|
+
MU.log "toKitten failed to load a cloud_desc from #{@cloud_id}", MU::ERR, details: @config
|
208
|
+
return nil
|
209
|
+
end
|
210
|
+
|
211
|
+
bok['name'] = cloud_desc.domain_name
|
212
|
+
bok['elasticsearch_version'] = cloud_desc.elasticsearch_version
|
213
|
+
bok['instance_count'] = cloud_desc.elasticsearch_cluster_config.instance_count
|
214
|
+
bok['instance_type'] = cloud_desc.elasticsearch_cluster_config.instance_type
|
215
|
+
bok['zone_aware'] = cloud_desc.elasticsearch_cluster_config.zone_awareness_enabled
|
216
|
+
|
217
|
+
if cloud_desc.elasticsearch_cluster_config.dedicated_master_enabled
|
218
|
+
bok['dedicated_masters'] = cloud_desc.elasticsearch_cluster_config.dedicated_master_count
|
219
|
+
bok['master_instance_type'] = cloud_desc.elasticsearch_cluster_config.dedicated_master_type
|
220
|
+
end
|
221
|
+
|
222
|
+
if cloud_desc.access_policies and !cloud_desc.access_policies.empty?
|
223
|
+
bok['access_policies'] = JSON.parse(cloud_desc.access_policies)
|
224
|
+
end
|
225
|
+
|
226
|
+
if cloud_desc.advanced_options and !cloud_desc.advanced_options.empty?
|
227
|
+
bok['advanced_options'] = cloud_desc.advanced_options
|
228
|
+
end
|
229
|
+
|
230
|
+
bok['ebs_size'] = cloud_desc.ebs_options.volume_size
|
231
|
+
bok['ebs_type'] = cloud_desc.ebs_options.volume_type
|
232
|
+
bok['ebs_iops'] = cloud_desc.ebs_options.iops if cloud_desc.ebs_options.iops
|
233
|
+
|
234
|
+
if cloud_desc.snapshot_options and cloud_desc.snapshot_options.automated_snapshot_start_hour
|
235
|
+
bok['snapshot_hour'] = cloud_desc.snapshot_options.automated_snapshot_start_hour
|
236
|
+
end
|
237
|
+
|
238
|
+
if cloud_desc.cognito_options.user_pool_id and
|
239
|
+
cloud_desc.cognito_options.identity_pool_id
|
240
|
+
bok['user_pool_id'] = cloud_desc.cognito_options.user_pool_id
|
241
|
+
bok['identity_pool_id'] = cloud_desc.cognito_options.identity_pool_id
|
242
|
+
end
|
243
|
+
|
244
|
+
tags = MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).list_tags(arn: cloud_desc.arn).tag_list
|
245
|
+
if tags and !tags.empty?
|
246
|
+
bok['tags'] = MU.structToHash(tags)
|
247
|
+
end
|
248
|
+
|
249
|
+
if cloud_desc.vpc_options
|
250
|
+
bok['vpc'] = MU::Config::Ref.get(
|
251
|
+
id: cloud_desc.vpc_options.vpc_id,
|
252
|
+
cloud: "AWS",
|
253
|
+
credentials: @credentials,
|
254
|
+
type: "vpcs",
|
255
|
+
region: @config['region'],
|
256
|
+
subnets: cloud_desc.vpc_options.subnet_ids.map { |s| { "subnet_id" => s } }
|
257
|
+
)
|
258
|
+
if cloud_desc.vpc_options.security_group_ids and
|
259
|
+
!cloud_desc.vpc_options.security_group_ids.empty?
|
260
|
+
bok['add_firewall_rules'] = cloud_desc.vpc_options.security_group_ids.map { |sg|
|
261
|
+
MU::Config::Ref.get(
|
262
|
+
id: sg,
|
263
|
+
cloud: "AWS",
|
264
|
+
credentials: @credentials,
|
265
|
+
region: @config['region'],
|
266
|
+
type: "firewall_rules",
|
267
|
+
)
|
268
|
+
}
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
if cloud_desc.log_publishing_options
|
273
|
+
# XXX this is primitive... there are multiple other log types now,
|
274
|
+
# and this should be a Ref blob, not a flat string
|
275
|
+
cloud_desc.log_publishing_options.each_pair { |type, whither|
|
276
|
+
if type == "SEARCH_SLOW_LOGS"
|
277
|
+
bok['slow_logs'] = whither.cloud_watch_logs_log_group_arn
|
278
|
+
end
|
279
|
+
}
|
280
|
+
end
|
281
|
+
|
282
|
+
bok
|
283
|
+
end
|
284
|
+
|
194
285
|
# Cloud-specific configuration properties.
|
195
286
|
# @param _config [MU::Config]: The calling MU::Config object
|
196
287
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
@@ -200,7 +291,7 @@ module MU
|
|
200
291
|
versions = begin
|
201
292
|
MU::Cloud::AWS.elasticsearch.list_elasticsearch_versions.elasticsearch_versions
|
202
293
|
rescue MuError
|
203
|
-
["7.1", "6.8", "6.7", "6.5", "6.4", "6.3", "6.2", "6.0", "5.6"]
|
294
|
+
["7.4", "7.1", "6.8", "6.7", "6.5", "6.4", "6.3", "6.2", "6.0", "5.6"]
|
204
295
|
end
|
205
296
|
instance_types = begin
|
206
297
|
MU::Cloud::AWS.elasticsearch.list_elasticsearch_instance_types(
|
@@ -215,6 +306,8 @@ module MU
|
|
215
306
|
).elasticsearch_instance_types
|
216
307
|
end
|
217
308
|
|
309
|
+
polschema = MU::Config::Role.schema["properties"]["policies"]
|
310
|
+
polschema.deep_merge!(MU::Cloud.resourceClass("AWS", "Role").condition_schema)
|
218
311
|
|
219
312
|
schema = {
|
220
313
|
"name" => {
|
@@ -236,9 +329,10 @@ module MU
|
|
236
329
|
"default" => 0,
|
237
330
|
"description" => "Separate, dedicated master node(s), over and above the search instances specified in instance_count."
|
238
331
|
},
|
332
|
+
"policies" => polschema,
|
239
333
|
"access_policies" => {
|
240
334
|
"type" => "object",
|
241
|
-
"description" => "An IAM policy document for access to ElasticSearch. Our parser expects this to be defined inline like the rest of your YAML/JSON Basket of Kittens, not as raw JSON. For guidance on ElasticSearch IAM capabilities, see: https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html"
|
335
|
+
"description" => "An IAM policy document for access to ElasticSearch (see {policies} for setting complex access policies with runtime dependencies). Our parser expects this to be defined inline like the rest of your YAML/JSON Basket of Kittens, not as raw JSON. For guidance on ElasticSearch IAM capabilities, see: https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html"
|
242
336
|
},
|
243
337
|
"master_instance_type" => {
|
244
338
|
"type" => "string",
|
@@ -246,7 +340,7 @@ module MU
|
|
246
340
|
},
|
247
341
|
"ebs_type" => {
|
248
342
|
"type" => "string",
|
249
|
-
"default" => "
|
343
|
+
"default" => "gp2",
|
250
344
|
"description" => "Type of EBS storage to use for cluster nodes. If 'none' is specified, EBS storage will not be used, but this is only valid for certain instance types.",
|
251
345
|
"enum" => ["standard", "gp2", "io1", "none"]
|
252
346
|
},
|
@@ -509,9 +603,51 @@ module MU
|
|
509
603
|
params[:snapshot_options][:automated_snapshot_start_hour] = @config['snapshot_hour']
|
510
604
|
end
|
511
605
|
|
512
|
-
if
|
513
|
-
#
|
514
|
-
|
606
|
+
if ext
|
607
|
+
# Despite being called access_policies, this parameter actually
|
608
|
+
# only accepts one policy. So, we'll munge everything we have
|
609
|
+
# together into one policy with multiple Statements.
|
610
|
+
policy = nil
|
611
|
+
# TODO check against ext.access_policy.options
|
612
|
+
|
613
|
+
if @config['access_policies']
|
614
|
+
policy = @config['access_policies']
|
615
|
+
# ensure the "Statement" key is cased in a predictable way
|
616
|
+
statement_key = nil
|
617
|
+
policy.each_pair { |k, v|
|
618
|
+
if k.downcase == "statement" and k != "Statement"
|
619
|
+
statement_key = k
|
620
|
+
break
|
621
|
+
end
|
622
|
+
}
|
623
|
+
if statement_key
|
624
|
+
policy["Statement"] = policy.delete(statement_key)
|
625
|
+
end
|
626
|
+
if !policy["Statement"].is_a?(Array)
|
627
|
+
policy["Statement"] = [policy["Statement"]]
|
628
|
+
end
|
629
|
+
end
|
630
|
+
|
631
|
+
if @config['policies']
|
632
|
+
@config['policies'].each { |p|
|
633
|
+
p['targets'].each { |t|
|
634
|
+
if t['path']
|
635
|
+
t['path'].gsub!(/#SELF/, @mu_name.downcase)
|
636
|
+
end
|
637
|
+
}
|
638
|
+
parsed = MU::Cloud.resourceClass("AWS", "Role").genPolicyDocument([p], deploy_obj: @deploy, bucket_style: true).first.values.first
|
639
|
+
|
640
|
+
if policy and policy["Statement"]
|
641
|
+
policy["Statement"].concat(parsed["Statement"])
|
642
|
+
else
|
643
|
+
policy = parsed
|
644
|
+
end
|
645
|
+
}
|
646
|
+
end
|
647
|
+
|
648
|
+
if policy
|
649
|
+
params[:access_policies] = JSON.generate(policy)
|
650
|
+
end
|
515
651
|
end
|
516
652
|
|
517
653
|
if @config['slow_logs']
|
@@ -677,7 +813,7 @@ module MU
|
|
677
813
|
raise MU::MuError, "Can't tag ElasticSearch domain, cloud descriptor came back without an ARN"
|
678
814
|
end
|
679
815
|
|
680
|
-
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @
|
816
|
+
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).add_tags(
|
681
817
|
arn: domain.arn,
|
682
818
|
tag_list: tags
|
683
819
|
)
|