cloud-mu 3.1.5 → 3.3.2
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 +5 -1
- 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/tasks/main.yml +16 -0
- data/bin/mu-adopt +16 -12
- 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 -1
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +37 -12
- data/cloud-mu.gemspec +3 -3
- 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 +1 -1
- 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/windows-client.rb +25 -22
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +2 -0
- data/extras/image-generators/AWS/win2k16.yaml +2 -0
- data/extras/image-generators/AWS/win2k19.yaml +2 -0
- data/modules/mommacat.ru +1 -1
- data/modules/mu.rb +86 -98
- data/modules/mu/adoption.rb +373 -58
- data/modules/mu/cleanup.rb +214 -303
- data/modules/mu/cloud.rb +128 -1733
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +44 -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 +929 -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 +169 -0
- data/modules/mu/config.rb +123 -81
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +32 -3
- data/modules/mu/config/cache_cluster.rb +2 -2
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/collection.rb +1 -1
- data/modules/mu/config/container_cluster.rb +7 -2
- data/modules/mu/config/database.rb +84 -105
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +5 -4
- data/modules/mu/config/doc_helpers.rb +5 -6
- data/modules/mu/config/endpoint.rb +2 -1
- data/modules/mu/config/firewall_rule.rb +3 -19
- data/modules/mu/config/folder.rb +1 -1
- data/modules/mu/config/function.rb +17 -8
- data/modules/mu/config/group.rb +1 -1
- data/modules/mu/config/habitat.rb +1 -1
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/loadbalancer.rb +57 -11
- data/modules/mu/config/log.rb +1 -1
- data/modules/mu/config/msg_queue.rb +1 -1
- data/modules/mu/config/nosqldb.rb +1 -1
- data/modules/mu/config/notifier.rb +8 -19
- data/modules/mu/config/ref.rb +92 -14
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +38 -37
- data/modules/mu/config/search_domain.rb +1 -1
- data/modules/mu/config/server.rb +12 -13
- data/modules/mu/config/server_pool.rb +3 -7
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +11 -0
- data/modules/mu/config/user.rb +1 -1
- data/modules/mu/config/vpc.rb +27 -23
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +90 -90
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +1 -0
- data/modules/mu/deploy.rb +34 -20
- data/modules/mu/groomer.rb +16 -1
- data/modules/mu/groomers/ansible.rb +69 -4
- data/modules/mu/groomers/chef.rb +51 -4
- data/modules/mu/logger.rb +120 -144
- data/modules/mu/master.rb +97 -4
- data/modules/mu/mommacat.rb +160 -874
- data/modules/mu/mommacat/daemon.rb +23 -14
- data/modules/mu/mommacat/naming.rb +110 -3
- data/modules/mu/mommacat/search.rb +497 -0
- data/modules/mu/mommacat/storage.rb +252 -194
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +258 -57
- data/modules/mu/{clouds → providers}/aws/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +275 -41
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +14 -50
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/{clouds → providers}/aws/collection.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +95 -84
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +26 -12
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +39 -32
- data/modules/mu/{clouds → providers}/aws/folder.rb +1 -1
- data/modules/mu/{clouds → providers}/aws/function.rb +289 -134
- data/modules/mu/{clouds → providers}/aws/group.rb +18 -20
- data/modules/mu/{clouds → providers}/aws/habitat.rb +3 -3
- data/modules/mu/providers/aws/job.rb +466 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +77 -47
- data/modules/mu/{clouds → providers}/aws/log.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +14 -11
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +96 -5
- data/modules/mu/{clouds → providers}/aws/notifier.rb +135 -63
- data/modules/mu/{clouds → providers}/aws/role.rb +76 -48
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +172 -41
- data/modules/mu/{clouds → providers}/aws/server.rb +66 -98
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +42 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +21 -38
- data/modules/mu/{clouds → providers}/aws/user.rb +12 -16
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/vpc.rb +143 -74
- data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
- data/modules/mu/{clouds → providers}/azure.rb +13 -0
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
- data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/server.rb +32 -24
- data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
- 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 +4 -6
- data/modules/mu/{clouds → providers}/cloudformation.rb +10 -0
- 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 +3 -3
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +29 -6
- data/modules/mu/{clouds → providers}/google/bucket.rb +4 -4
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +38 -20
- data/modules/mu/{clouds → providers}/google/database.rb +5 -12
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +5 -5
- data/modules/mu/{clouds → providers}/google/folder.rb +5 -9
- data/modules/mu/{clouds → providers}/google/function.rb +6 -6
- data/modules/mu/{clouds → providers}/google/group.rb +9 -17
- data/modules/mu/{clouds → providers}/google/habitat.rb +4 -8
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/google/role.rb +50 -31
- data/modules/mu/{clouds → providers}/google/server.rb +41 -24
- data/modules/mu/{clouds → providers}/google/server_pool.rb +14 -14
- data/modules/mu/{clouds → providers}/google/user.rb +34 -24
- 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 +45 -14
- data/modules/tests/aws-jobs-functions.yaml +46 -0
- data/modules/tests/centos6.yaml +15 -0
- data/modules/tests/centos7.yaml +15 -0
- data/modules/tests/centos8.yaml +12 -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 +108 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- 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 +3 -5
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +122 -92
- data/modules/mu/clouds/aws/database.rb +0 -1974
- data/modules/mu/clouds/aws/endpoint.rb +0 -596
|
@@ -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
|
|
@@ -156,8 +157,8 @@ module MU
|
|
|
156
157
|
begin
|
|
157
158
|
resp = MU::Cloud::AWS.iam(credentials: credentials).list_roles(marker: marker)
|
|
158
159
|
resp.roles.each{ |role|
|
|
159
|
-
# XXX Maybe we should have a more generic way to delete IAM profiles and policies. The call itself should be moved from MU::Cloud
|
|
160
|
-
# MU::Cloud
|
|
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").
|
|
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
|
},
|
|
@@ -378,9 +472,9 @@ module MU
|
|
|
378
472
|
|
|
379
473
|
if dom['slow_logs']
|
|
380
474
|
if configurator.haveLitterMate?(dom['slow_logs'], "log")
|
|
381
|
-
dom
|
|
475
|
+
MU::Config.addDependency(dom, dom['slow_logs'], "log")
|
|
382
476
|
else
|
|
383
|
-
log_group = MU::Cloud
|
|
477
|
+
log_group = MU::Cloud.resourceClass("AWS", "Log").find(cloud_id: dom['slow_logs'], region: dom['region']).values.first
|
|
384
478
|
if !log_group
|
|
385
479
|
MU.log "Specified slow_logs CloudWatch log group '#{dom['slow_logs']}' in SearchDomain '#{dom['name']}' doesn't appear to exist", MU::ERR
|
|
386
480
|
ok = false
|
|
@@ -395,7 +489,7 @@ module MU
|
|
|
395
489
|
"credentials" => dom['credentials']
|
|
396
490
|
}
|
|
397
491
|
ok = false if !configurator.insertKitten(log_group, "logs")
|
|
398
|
-
dom
|
|
492
|
+
MU::Config.addDependency(dom, dom['slow_logs'], "log")
|
|
399
493
|
end
|
|
400
494
|
|
|
401
495
|
if dom['advanced_options']
|
|
@@ -456,12 +550,7 @@ module MU
|
|
|
456
550
|
]
|
|
457
551
|
}
|
|
458
552
|
configurator.insertKitten(roledesc, "roles")
|
|
459
|
-
|
|
460
|
-
dom['dependencies'] ||= []
|
|
461
|
-
dom['dependencies'] << {
|
|
462
|
-
"type" => "role",
|
|
463
|
-
"name" => dom['name']+"cognitorole"
|
|
464
|
-
}
|
|
553
|
+
MU::Config.addDependency(dom, dom['name']+"cognitorole", "role")
|
|
465
554
|
end
|
|
466
555
|
|
|
467
556
|
end
|
|
@@ -514,9 +603,51 @@ module MU
|
|
|
514
603
|
params[:snapshot_options][:automated_snapshot_start_hour] = @config['snapshot_hour']
|
|
515
604
|
end
|
|
516
605
|
|
|
517
|
-
if
|
|
518
|
-
#
|
|
519
|
-
|
|
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
|
|
520
651
|
end
|
|
521
652
|
|
|
522
653
|
if @config['slow_logs']
|
|
@@ -525,7 +656,7 @@ module MU
|
|
|
525
656
|
arn = @config['slow_logs']
|
|
526
657
|
else
|
|
527
658
|
log_group = @deploy.findLitterMate(type: "log", name: @config['slow_logs'])
|
|
528
|
-
log_group = MU::Cloud
|
|
659
|
+
log_group = MU::Cloud.resourceClass("AWS", "Log").find(cloud_id: log_group.mu_name, region: log_group.cloudobj.config['region']).values.first
|
|
529
660
|
if log_group.nil? or log_group.arn.nil?
|
|
530
661
|
raise MuError, "Failed to retrieve ARN of sibling LogGroup '#{@config['slow_logs']}'"
|
|
531
662
|
end
|
|
@@ -552,7 +683,7 @@ module MU
|
|
|
552
683
|
params[:log_publishing_options]["SEARCH_SLOW_LOGS"] = {}
|
|
553
684
|
params[:log_publishing_options]["SEARCH_SLOW_LOGS"][:enabled] = true
|
|
554
685
|
params[:log_publishing_options]["SEARCH_SLOW_LOGS"][:cloud_watch_logs_log_group_arn] = arn
|
|
555
|
-
MU::Cloud
|
|
686
|
+
MU::Cloud.resourceClass("AWS", "Log").allowService("es.amazonaws.com", arn, @config['region'])
|
|
556
687
|
end
|
|
557
688
|
end
|
|
558
689
|
|
|
@@ -682,7 +813,7 @@ module MU
|
|
|
682
813
|
raise MU::MuError, "Can't tag ElasticSearch domain, cloud descriptor came back without an ARN"
|
|
683
814
|
end
|
|
684
815
|
|
|
685
|
-
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @
|
|
816
|
+
MU::Cloud::AWS.elasticsearch(region: @config['region'], credentials: @credentials).add_tags(
|
|
686
817
|
arn: domain.arn,
|
|
687
818
|
tag_list: tags
|
|
688
819
|
)
|
|
@@ -89,7 +89,7 @@ module MU
|
|
|
89
89
|
template_variables: {
|
|
90
90
|
"deployKey" => Base64.urlsafe_encode64(@deploy.public_key),
|
|
91
91
|
"deploySSHKey" => @deploy.ssh_public_key,
|
|
92
|
-
"muID" =>
|
|
92
|
+
"muID" => @deploy.deploy_id,
|
|
93
93
|
"muUser" => MU.mu_user,
|
|
94
94
|
"publicIP" => MU.mu_public_ip,
|
|
95
95
|
"mommaCatPort" => MU.mommaCatPort,
|
|
@@ -145,7 +145,7 @@ module MU
|
|
|
145
145
|
raise MuError, "My second argument should be a hash of variables to pass into ERB templates"
|
|
146
146
|
end
|
|
147
147
|
$mu = OpenStruct.new(template_variables)
|
|
148
|
-
userdata_dir = File.expand_path(MU.myRoot+"/modules/mu/
|
|
148
|
+
userdata_dir = File.expand_path(MU.myRoot+"/modules/mu/providers/aws/userdata")
|
|
149
149
|
platform = "linux" if %w{centos centos6 centos7 ubuntu ubuntu14 rhel rhel7 rhel71 amazon}.include? platform
|
|
150
150
|
platform = "windows" if %w{win2k12r2 win2k12 win2k8 win2k8r2 win2k16}.include? platform
|
|
151
151
|
erbfile = "#{userdata_dir}/#{platform}.erb"
|
|
@@ -299,7 +299,7 @@ module MU
|
|
|
299
299
|
raise MuError, "Got null subnet id out of #{@config['vpc']}"
|
|
300
300
|
end
|
|
301
301
|
MU.log "Deploying #{@mu_name} into VPC #{@vpc.cloud_id} Subnet #{subnet.cloud_id}"
|
|
302
|
-
|
|
302
|
+
allowBastionAccess
|
|
303
303
|
instance_descriptor[:subnet_id] = subnet.cloud_id
|
|
304
304
|
end
|
|
305
305
|
|
|
@@ -399,13 +399,13 @@ module MU
|
|
|
399
399
|
# Figure out what's needed to SSH into this server.
|
|
400
400
|
# @return [Array<String>]: nat_ssh_key, nat_ssh_user, nat_ssh_host, canonical_ip, ssh_user, ssh_key_name, alternate_names
|
|
401
401
|
def getSSHConfig
|
|
402
|
-
|
|
402
|
+
cloud_desc(use_cache: false) # make sure we're current
|
|
403
403
|
# XXX add some awesome alternate names from metadata and make sure they end
|
|
404
404
|
# up in MU::MommaCat's ssh config wangling
|
|
405
405
|
return nil if @config.nil? or @deploy.nil?
|
|
406
406
|
|
|
407
407
|
nat_ssh_key = nat_ssh_user = nat_ssh_host = nil
|
|
408
|
-
if !@config["vpc"].nil? and !MU::Cloud
|
|
408
|
+
if !@config["vpc"].nil? and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
|
|
409
409
|
if !@nat.nil?
|
|
410
410
|
if @nat.is_a?(Struct) && @nat.nat_gateway_id && @nat.nat_gateway_id.start_with?("nat-")
|
|
411
411
|
raise MuError, "Configured to use NAT Gateway, but I have no route to instance. Either use Bastion, or configure VPC peering"
|
|
@@ -444,8 +444,7 @@ module MU
|
|
|
444
444
|
# administravia for a new instance.
|
|
445
445
|
def postBoot(instance_id = nil)
|
|
446
446
|
@cloud_id ||= instance_id
|
|
447
|
-
|
|
448
|
-
@mu_name ||= node
|
|
447
|
+
_node, _config, deploydata = describe(cloud_id: @cloud_id)
|
|
449
448
|
|
|
450
449
|
raise MuError, "Couldn't find instance #{@mu_name} (#{@cloud_id})" if !cloud_desc
|
|
451
450
|
return false if !MU::MommaCat.lock(@cloud_id+"-orchestrate", true)
|
|
@@ -482,7 +481,7 @@ module MU
|
|
|
482
481
|
end
|
|
483
482
|
}
|
|
484
483
|
|
|
485
|
-
|
|
484
|
+
allowBastionAccess
|
|
486
485
|
|
|
487
486
|
setAlarms
|
|
488
487
|
|
|
@@ -615,7 +614,7 @@ module MU
|
|
|
615
614
|
return nil
|
|
616
615
|
end
|
|
617
616
|
|
|
618
|
-
asgs = MU::Cloud
|
|
617
|
+
asgs = MU::Cloud.resourceClass("AWS", "ServerPool").find(
|
|
619
618
|
instance_id: @cloud_id,
|
|
620
619
|
region: @config['region'],
|
|
621
620
|
credentials: @credentials
|
|
@@ -725,15 +724,15 @@ module MU
|
|
|
725
724
|
|
|
726
725
|
if int.groups.size > 0
|
|
727
726
|
|
|
728
|
-
require 'mu/
|
|
729
|
-
ifaces = MU::Cloud
|
|
727
|
+
require 'mu/providers/aws/firewall_rule'
|
|
728
|
+
ifaces = MU::Cloud.resourceClass("AWS", "FirewallRule").getAssociatedInterfaces(int.groups.map { |sg| sg.group_id }, credentials: @credentials, region: @config['region'])
|
|
730
729
|
done_local_rules = false
|
|
731
730
|
int.groups.each { |sg|
|
|
732
731
|
if !done_local_rules and ifaces[sg.group_id].size == 1
|
|
733
|
-
sg_desc = MU::Cloud
|
|
732
|
+
sg_desc = MU::Cloud.resourceClass("AWS", "FirewallRule").find(cloud_id: sg.group_id, credentials: @credentials, region: @config['region']).values.first
|
|
734
733
|
if sg_desc
|
|
735
|
-
bok["ingress_rules"] = MU::Cloud
|
|
736
|
-
bok["ingress_rules"].concat(MU::Cloud
|
|
734
|
+
bok["ingress_rules"] = MU::Cloud.resourceClass("AWS", "FirewallRule").rulesToBoK(sg_desc.ip_permissions)
|
|
735
|
+
bok["ingress_rules"].concat(MU::Cloud.resourceClass("AWS", "FirewallRule").rulesToBoK(sg_desc.ip_permissions_egress, egress: true))
|
|
737
736
|
done_local_rules = true
|
|
738
737
|
next
|
|
739
738
|
end
|
|
@@ -802,44 +801,13 @@ module MU
|
|
|
802
801
|
end
|
|
803
802
|
deploydata["region"] = @config['region'] if !@config['region'].nil?
|
|
804
803
|
if !@named
|
|
805
|
-
MU::MommaCat.nameKitten(self)
|
|
804
|
+
MU::MommaCat.nameKitten(self, no_dns: true)
|
|
806
805
|
@named = true
|
|
807
806
|
end
|
|
808
807
|
|
|
809
808
|
return deploydata
|
|
810
809
|
end
|
|
811
810
|
|
|
812
|
-
# If the specified server is in a VPC, and has a NAT, make sure we'll
|
|
813
|
-
# be letting ssh traffic in from said NAT.
|
|
814
|
-
def punchAdminNAT
|
|
815
|
-
if @config['vpc'].nil? or
|
|
816
|
-
(
|
|
817
|
-
!@config['vpc'].has_key?("nat_host_id") and
|
|
818
|
-
!@config['vpc'].has_key?("nat_host_tag") and
|
|
819
|
-
!@config['vpc'].has_key?("nat_host_ip") and
|
|
820
|
-
!@config['vpc'].has_key?("nat_host_name")
|
|
821
|
-
)
|
|
822
|
-
return nil
|
|
823
|
-
end
|
|
824
|
-
|
|
825
|
-
return nil if @nat.is_a?(Struct) && @nat.nat_gateway_id && @nat.nat_gateway_id.start_with?("nat-")
|
|
826
|
-
|
|
827
|
-
dependencies if @nat.nil?
|
|
828
|
-
if @nat.nil? or @nat.cloud_desc.nil?
|
|
829
|
-
raise MuError, "#{@mu_name} (#{MU.deploy_id}) is configured to use #{@config['vpc']} but I can't find the cloud descriptor for a matching NAT instance"
|
|
830
|
-
end
|
|
831
|
-
MU.log "Adding administrative holes for NAT host #{@nat.cloud_desc.private_ip_address} to #{@mu_name}"
|
|
832
|
-
if !@deploy.kittens['firewall_rules'].nil?
|
|
833
|
-
@deploy.kittens['firewall_rules'].values.each { |acl|
|
|
834
|
-
if acl.config["admin"]
|
|
835
|
-
acl.addRule([@nat.cloud_desc.private_ip_address], proto: "tcp")
|
|
836
|
-
acl.addRule([@nat.cloud_desc.private_ip_address], proto: "udp")
|
|
837
|
-
acl.addRule([@nat.cloud_desc.private_ip_address], proto: "icmp")
|
|
838
|
-
end
|
|
839
|
-
}
|
|
840
|
-
end
|
|
841
|
-
end
|
|
842
|
-
|
|
843
811
|
# Called automatically by {MU::Deploy#createResources}
|
|
844
812
|
def groom
|
|
845
813
|
MU::MommaCat.lock(@cloud_id+"-groom")
|
|
@@ -851,7 +819,7 @@ module MU
|
|
|
851
819
|
end
|
|
852
820
|
end
|
|
853
821
|
|
|
854
|
-
|
|
822
|
+
allowBastionAccess
|
|
855
823
|
|
|
856
824
|
tagVolumes
|
|
857
825
|
|
|
@@ -883,12 +851,25 @@ module MU
|
|
|
883
851
|
|
|
884
852
|
begin
|
|
885
853
|
getIAMProfile
|
|
854
|
+
|
|
855
|
+
dbs = @deploy.findLitterMate(type: "database", return_all: true)
|
|
856
|
+
if dbs
|
|
857
|
+
dbs.each_pair { |sib_name, sib|
|
|
858
|
+
@groomer.groomer_class.grantSecretAccess(@mu_name, sib_name, "database_credentials")
|
|
859
|
+
if sib.config and sib.config['auth_vault']
|
|
860
|
+
@groomer.groomer_class.grantSecretAccess(@mu_name, sib.config['auth_vault']['vault'], sib.config['auth_vault']['item'])
|
|
861
|
+
end
|
|
862
|
+
}
|
|
863
|
+
end
|
|
864
|
+
|
|
886
865
|
if @config['groom'].nil? or @config['groom']
|
|
887
866
|
@groomer.run(purpose: "Full Initial Run", max_retries: 15, reboot_first_fail: (windows? and @config['groomer'] != "Ansible"), timeout: @config['groomer_timeout'])
|
|
888
867
|
end
|
|
889
868
|
rescue MU::Groomer::RunError => e
|
|
869
|
+
raise e if !@config['create_image'].nil? and !@config['image_created']
|
|
890
870
|
MU.log "Proceeding after failed initial Groomer run, but #{@mu_name} may not behave as expected!", MU::WARN, details: e.message
|
|
891
871
|
rescue StandardError => e
|
|
872
|
+
raise e if !@config['create_image'].nil? and !@config['image_created']
|
|
892
873
|
MU.log "Caught #{e.inspect} on #{@mu_name} in an unexpected place (after @groomer.run on Full Initial Run)", MU::ERR
|
|
893
874
|
end
|
|
894
875
|
|
|
@@ -910,6 +891,7 @@ module MU
|
|
|
910
891
|
# @return [Openstruct]
|
|
911
892
|
def cloud_desc(use_cache: true)
|
|
912
893
|
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
|
894
|
+
return nil if !@cloud_id
|
|
913
895
|
max_retries = 5
|
|
914
896
|
retries = 0
|
|
915
897
|
if !@cloud_id.nil?
|
|
@@ -961,7 +943,7 @@ module MU
|
|
|
961
943
|
# Our deploydata gets corrupted often with server pools, this will cause us to use the wrong IP to identify a node
|
|
962
944
|
# which will cause us to create certificates, DNS records and other artifacts with incorrect information which will cause our deploy to fail.
|
|
963
945
|
# The cloud_id is always correct so lets use 'cloud_desc' to get the correct IPs
|
|
964
|
-
if MU::Cloud
|
|
946
|
+
if MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials']) or @deploydata["public_ip_address"].nil?
|
|
965
947
|
@config['canonical_ip'] = cloud_desc.private_ip_address
|
|
966
948
|
@deploydata["private_ip_address"] = cloud_desc.private_ip_address
|
|
967
949
|
return cloud_desc.private_ip_address
|
|
@@ -1181,10 +1163,7 @@ module MU
|
|
|
1181
1163
|
end
|
|
1182
1164
|
end
|
|
1183
1165
|
|
|
1184
|
-
|
|
1185
|
-
describe
|
|
1186
|
-
@cloud_id = cloud_desc.instance_id
|
|
1187
|
-
end
|
|
1166
|
+
@cloud_id ||= cloud_desc(use_cache: false).instance_id
|
|
1188
1167
|
ssh_keydir = "#{Etc.getpwuid(Process.uid).dir}/.ssh"
|
|
1189
1168
|
ssh_key_name = @deploy.ssh_key_name
|
|
1190
1169
|
|
|
@@ -1318,7 +1297,7 @@ module MU
|
|
|
1318
1297
|
|
|
1319
1298
|
if @deploy
|
|
1320
1299
|
MU::Cloud::AWS.createStandardTags(
|
|
1321
|
-
|
|
1300
|
+
creation.volume_id,
|
|
1322
1301
|
region: @config['region'],
|
|
1323
1302
|
credentials: @config['credentials'],
|
|
1324
1303
|
optional: @config['optional_tags'],
|
|
@@ -1476,11 +1455,11 @@ module MU
|
|
|
1476
1455
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
1477
1456
|
# @param region [String]: The cloud provider region
|
|
1478
1457
|
# @return [void]
|
|
1479
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
1458
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
1480
1459
|
onlycloud = flags["onlycloud"]
|
|
1481
1460
|
skipsnapshots = flags["skipsnapshots"]
|
|
1482
1461
|
tagfilters = [
|
|
1483
|
-
{name: "tag:MU-ID", values: [
|
|
1462
|
+
{name: "tag:MU-ID", values: [deploy_id]}
|
|
1484
1463
|
]
|
|
1485
1464
|
if !ignoremaster
|
|
1486
1465
|
tagfilters << {name: "tag:MU-MASTER-IP", values: [MU.mu_public_ip]}
|
|
@@ -1514,7 +1493,7 @@ module MU
|
|
|
1514
1493
|
threads << Thread.new(instance) { |myinstance|
|
|
1515
1494
|
MU.dupGlobals(parent_thread_id)
|
|
1516
1495
|
Thread.abort_on_exception = true
|
|
1517
|
-
MU::Cloud::AWS::Server.terminateInstance(id: myinstance.instance_id, noop: noop, onlycloud: onlycloud, region: region, deploy_id:
|
|
1496
|
+
MU::Cloud::AWS::Server.terminateInstance(id: myinstance.instance_id, noop: noop, onlycloud: onlycloud, region: region, deploy_id: deploy_id, credentials: credentials)
|
|
1518
1497
|
}
|
|
1519
1498
|
}
|
|
1520
1499
|
|
|
@@ -1525,7 +1504,7 @@ module MU
|
|
|
1525
1504
|
threads << Thread.new(volume) { |myvolume|
|
|
1526
1505
|
MU.dupGlobals(parent_thread_id)
|
|
1527
1506
|
Thread.abort_on_exception = true
|
|
1528
|
-
delete_volume(myvolume, noop, skipsnapshots, credentials: credentials)
|
|
1507
|
+
delete_volume(myvolume, noop, skipsnapshots, credentials: credentials, deploy_id: deploy_id)
|
|
1529
1508
|
}
|
|
1530
1509
|
}
|
|
1531
1510
|
|
|
@@ -1577,7 +1556,11 @@ module MU
|
|
|
1577
1556
|
return if !instance
|
|
1578
1557
|
|
|
1579
1558
|
id ||= instance.instance_id
|
|
1580
|
-
|
|
1559
|
+
begin
|
|
1560
|
+
MU::MommaCat.lock(".cleanup-"+id)
|
|
1561
|
+
rescue Errno::ENOENT => e
|
|
1562
|
+
MU.log "No lock for terminating instance #{id} due to missing metadata", MU::DEBUG
|
|
1563
|
+
end
|
|
1581
1564
|
|
|
1582
1565
|
ips, names = getAddresses(instance, region: region, credentials: credentials)
|
|
1583
1566
|
targets = ips +names
|
|
@@ -1632,7 +1615,11 @@ module MU
|
|
|
1632
1615
|
end
|
|
1633
1616
|
|
|
1634
1617
|
MU.log "#{instance.instance_id}#{server_obj ? " ("+server_obj.mu_name+")" : ""} terminated" if !noop
|
|
1635
|
-
|
|
1618
|
+
begin
|
|
1619
|
+
MU::MommaCat.unlock(".cleanup-"+id)
|
|
1620
|
+
rescue Errno::ENOENT => e
|
|
1621
|
+
MU.log "No lock for terminating instance #{id} due to missing metadata", MU::DEBUG
|
|
1622
|
+
end
|
|
1636
1623
|
|
|
1637
1624
|
end
|
|
1638
1625
|
|
|
@@ -1690,26 +1677,7 @@ module MU
|
|
|
1690
1677
|
"type" => "object"
|
|
1691
1678
|
}
|
|
1692
1679
|
},
|
|
1693
|
-
"ingress_rules" =>
|
|
1694
|
-
"items" => {
|
|
1695
|
-
"properties" => {
|
|
1696
|
-
"sgs" => {
|
|
1697
|
-
"type" => "array",
|
|
1698
|
-
"items" => {
|
|
1699
|
-
"description" => "Other AWS Security Groups; resources that are associated with this group will have this rule applied to their traffic",
|
|
1700
|
-
"type" => "string"
|
|
1701
|
-
}
|
|
1702
|
-
},
|
|
1703
|
-
"lbs" => {
|
|
1704
|
-
"type" => "array",
|
|
1705
|
-
"items" => {
|
|
1706
|
-
"description" => "AWS Load Balancers which will have this rule applied to their traffic",
|
|
1707
|
-
"type" => "string"
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
},
|
|
1680
|
+
"ingress_rules" => MU::Cloud.resourceClass("AWS", "FirewallRule").ingressRuleAddtlSchema,
|
|
1713
1681
|
"ssh_user" => {
|
|
1714
1682
|
"type" => "string",
|
|
1715
1683
|
"default" => "root",
|
|
@@ -1777,8 +1745,7 @@ module MU
|
|
|
1777
1745
|
|
|
1778
1746
|
MU::Cloud.availableClouds.each { |cloud|
|
|
1779
1747
|
next if cloud == "AWS"
|
|
1780
|
-
|
|
1781
|
-
foreign_types = (cloudbase.listInstanceTypes).values.first
|
|
1748
|
+
foreign_types = (MU::Cloud.cloudClass(cloud).listInstanceTypes).values.first
|
|
1782
1749
|
if foreign_types.size == 1
|
|
1783
1750
|
foreign_types = foreign_types.values.first
|
|
1784
1751
|
end
|
|
@@ -1845,12 +1812,7 @@ module MU
|
|
|
1845
1812
|
end
|
|
1846
1813
|
|
|
1847
1814
|
configurator.insertKitten(role, "roles")
|
|
1848
|
-
|
|
1849
|
-
server["dependencies"] ||= []
|
|
1850
|
-
server["dependencies"] << {
|
|
1851
|
-
"type" => "role",
|
|
1852
|
-
"name" => server["name"]
|
|
1853
|
-
}
|
|
1815
|
+
MU::Config.addDependency(server, server["name"], "role")
|
|
1854
1816
|
end
|
|
1855
1817
|
|
|
1856
1818
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::servers}, bare and unvalidated.
|
|
@@ -1901,10 +1863,7 @@ module MU
|
|
|
1901
1863
|
server["loadbalancers"].each { |lb|
|
|
1902
1864
|
lb["name"] ||= lb["concurrent_load_balancer"]
|
|
1903
1865
|
if lb["name"]
|
|
1904
|
-
server["
|
|
1905
|
-
"type" => "loadbalancer",
|
|
1906
|
-
"name" => lb["name"]
|
|
1907
|
-
}
|
|
1866
|
+
MU::Config.addDependency(server, lb["name"], "loadbalancer")
|
|
1908
1867
|
end
|
|
1909
1868
|
}
|
|
1910
1869
|
end
|
|
@@ -1931,7 +1890,7 @@ module MU
|
|
|
1931
1890
|
# @param volume [OpenStruct]: The cloud provider's description of the volume.
|
|
1932
1891
|
# @param region [String]: The cloud provider region
|
|
1933
1892
|
# @return [void]
|
|
1934
|
-
def self.delete_volume(volume, noop, skipsnapshots, region: MU.curRegion, credentials: nil)
|
|
1893
|
+
def self.delete_volume(volume, noop, skipsnapshots, region: MU.curRegion, credentials: nil, deploy_id: MU.deploy_id)
|
|
1935
1894
|
if !volume.nil?
|
|
1936
1895
|
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_volumes(volume_ids: [volume.volume_id])
|
|
1937
1896
|
volume = resp.data.volumes.first
|
|
@@ -1946,9 +1905,9 @@ module MU
|
|
|
1946
1905
|
if !noop
|
|
1947
1906
|
if !skipsnapshots
|
|
1948
1907
|
if !name.nil? and !name.empty?
|
|
1949
|
-
desc = "#{
|
|
1908
|
+
desc = "#{deploy_id}-MUfinal (#{name})"
|
|
1950
1909
|
else
|
|
1951
|
-
desc = "#{
|
|
1910
|
+
desc = "#{deploy_id}-MUfinal"
|
|
1952
1911
|
end
|
|
1953
1912
|
|
|
1954
1913
|
begin
|
|
@@ -2019,6 +1978,13 @@ module MU
|
|
|
2019
1978
|
configured_storage
|
|
2020
1979
|
end
|
|
2021
1980
|
|
|
1981
|
+
# Return all of the IP addresses, public and private, from all of our
|
|
1982
|
+
# network interfaces.
|
|
1983
|
+
# @return [Array<String>]
|
|
1984
|
+
def listIPs
|
|
1985
|
+
MU::Cloud::AWS::Server.getAddresses(cloud_desc).first
|
|
1986
|
+
end
|
|
1987
|
+
|
|
2022
1988
|
private
|
|
2023
1989
|
|
|
2024
1990
|
def bootstrapGroomer
|
|
@@ -2144,7 +2110,7 @@ module MU
|
|
|
2144
2110
|
subnet = @vpc.getSubnet(cloud_id: cloud_desc.subnet_id)
|
|
2145
2111
|
|
|
2146
2112
|
_nat_ssh_key, _nat_ssh_user, nat_ssh_host, _canonical_ip, _ssh_user, _ssh_key_name = getSSHConfig
|
|
2147
|
-
if subnet.private? and !nat_ssh_host and !MU::Cloud
|
|
2113
|
+
if subnet.private? and !nat_ssh_host and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
|
|
2148
2114
|
raise MuError, "#{@mu_name} is in a private subnet (#{subnet}), but has no bastion host configured, and I have no other route to it"
|
|
2149
2115
|
end
|
|
2150
2116
|
|
|
@@ -2236,15 +2202,17 @@ module MU
|
|
|
2236
2202
|
alarm["dimensions"] = [{:name => "InstanceId", :value => @cloud_id}]
|
|
2237
2203
|
|
|
2238
2204
|
if alarm["enable_notifications"]
|
|
2239
|
-
|
|
2240
|
-
|
|
2205
|
+
# XXX vile, this should be a sibling resource generated by the
|
|
2206
|
+
# parser
|
|
2207
|
+
topic_arn = MU::Cloud.resourceClass("AWS", "Notification").createTopic(alarm["notification_group"], region: @config["region"], credentials: @config['credentials'])
|
|
2208
|
+
MU::Cloud.resourceClass("AWS", "Notification").subscribe(topic_arn, alarm["notification_endpoint"], alarm["notification_type"], region: @config["region"], credentials: @config["credentials"])
|
|
2241
2209
|
alarm["alarm_actions"] = [topic_arn]
|
|
2242
2210
|
alarm["ok_actions"] = [topic_arn]
|
|
2243
2211
|
end
|
|
2244
2212
|
|
|
2245
2213
|
alarm_name = alarm_obj ? alarm_obj.cloud_id : "#{@mu_name}-#{alarm['name']}".upcase
|
|
2246
2214
|
|
|
2247
|
-
MU::Cloud
|
|
2215
|
+
MU::Cloud.resourceClass("AWS", "Alarm").setAlarm(
|
|
2248
2216
|
name: alarm_name,
|
|
2249
2217
|
ok_actions: alarm["ok_actions"],
|
|
2250
2218
|
alarm_actions: alarm["alarm_actions"],
|