cloud-mu 3.2.0 → 3.3.0
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 +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
|
)
|