cloud-mu 3.1.2 → 3.2.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 +15 -3
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +10 -13
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +135 -37
- data/cloud-mu.gemspec +22 -20
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +3 -2
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +6 -16
- data/modules/mu.rb +165 -111
- data/modules/mu/adoption.rb +401 -68
- data/modules/mu/cleanup.rb +199 -306
- data/modules/mu/cloud.rb +100 -1632
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +46 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +920 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +165 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +4 -4
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +83 -104
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +6 -6
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +4 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +3 -3
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/loadbalancer.rb +60 -14
- data/modules/mu/config/log.rb +4 -4
- data/modules/mu/config/msg_queue.rb +4 -4
- data/modules/mu/config/nosqldb.rb +4 -4
- data/modules/mu/config/notifier.rb +3 -3
- data/modules/mu/config/ref.rb +365 -0
- data/modules/mu/config/role.rb +4 -4
- data/modules/mu/config/schema_helpers.rb +509 -0
- data/modules/mu/config/search_domain.rb +4 -4
- data/modules/mu/config/server.rb +97 -70
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +5 -9
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +200 -0
- data/modules/mu/config/user.rb +4 -4
- data/modules/mu/config/vpc.rb +70 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +83 -60
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +30 -26
- data/modules/mu/groomer.rb +17 -2
- data/modules/mu/groomers/ansible.rb +188 -41
- data/modules/mu/groomers/chef.rb +116 -55
- data/modules/mu/logger.rb +127 -148
- data/modules/mu/master.rb +389 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -3
- data/modules/mu/mommacat.rb +217 -2612
- data/modules/mu/mommacat/daemon.rb +397 -0
- data/modules/mu/mommacat/naming.rb +473 -0
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +722 -0
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +271 -112
- data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
- data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
- data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
- data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
- data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
- data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
- data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
- data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
- data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
- data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
- data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +29 -9
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
- data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
- data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
- data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
- data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +67 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
- data/modules/mu/{clouds → providers}/google/database.rb +10 -20
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
- data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
- data/modules/mu/{clouds → providers}/google/function.rb +139 -167
- data/modules/mu/{clouds → providers}/google/group.rb +29 -34
- data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
- data/modules/mu/{clouds → providers}/google/role.rb +92 -58
- data/modules/mu/{clouds → providers}/google/server.rb +242 -155
- data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
- data/modules/mu/{clouds → providers}/google/user.rb +95 -31
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +11 -0
- data/modules/tests/centos7.yaml +11 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -0
- data/modules/tests/super_simple_bok.yml +1 -3
- data/modules/tests/win2k12.yaml +17 -5
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +232 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
data/modules/mu/cleanup.rb
CHANGED
|
@@ -25,13 +25,15 @@ module MU
|
|
|
25
25
|
# Routines for removing cloud resources.
|
|
26
26
|
class Cleanup
|
|
27
27
|
|
|
28
|
-
home = Etc.getpwuid(Process.uid).dir
|
|
29
|
-
|
|
30
28
|
@deploy_id = nil
|
|
31
29
|
@noop = false
|
|
32
30
|
@onlycloud = false
|
|
33
31
|
@skipcloud = false
|
|
34
32
|
|
|
33
|
+
# Resource types, in the order in which we generally have to clean them up
|
|
34
|
+
# to disentangle them from one another.
|
|
35
|
+
TYPES_IN_ORDER = ["Collection", "Endpoint", "Function", "ServerPool", "ContainerCluster", "SearchDomain", "Server", "MsgQueue", "Database", "CacheCluster", "StoragePool", "LoadBalancer", "NoSQLDB", "FirewallRule", "Alarm", "Notifier", "Log", "VPC", "Role", "Group", "User", "Bucket", "DNSZone", "Collection"]
|
|
36
|
+
|
|
35
37
|
# Purge all resources associated with a deployment.
|
|
36
38
|
# @param deploy_id [String]: The identifier of the deployment to remove (typically seen in the MU-ID tag on a resource).
|
|
37
39
|
# @param noop [Boolean]: Do not delete resources, merely list what would be deleted.
|
|
@@ -56,14 +58,7 @@ module MU
|
|
|
56
58
|
@noop = true
|
|
57
59
|
end
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
MU.setVar("dataDir", Etc.getpwnam(MU.mu_user).dir+"/.mu/var")
|
|
61
|
-
else
|
|
62
|
-
MU.setVar("dataDir", MU.mainDataDir)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
types_in_order = ["Collection", "Endpoint", "Function", "ServerPool", "ContainerCluster", "SearchDomain", "Server", "MsgQueue", "Database", "CacheCluster", "StoragePool", "LoadBalancer", "NoSQLDB", "FirewallRule", "Alarm", "Notifier", "Log", "VPC", "Role", "Group", "User", "Bucket", "DNSZone", "Collection"]
|
|
61
|
+
MU.setVar("dataDir", (MU.mu_user == "mu" ? MU.mainDataDir : Etc.getpwnam(MU.mu_user).dir+"/.mu/var"))
|
|
67
62
|
|
|
68
63
|
# Load up our deployment metadata
|
|
69
64
|
if !mommacat.nil?
|
|
@@ -81,174 +76,27 @@ module MU
|
|
|
81
76
|
MU.log "Searching for remnants of #{deploy_id}, though this may be an invalid MU-ID.", MU::WARN
|
|
82
77
|
end
|
|
83
78
|
@mommacat = MU::MommaCat.new(deploy_id, mu_user: MU.mu_user, delay_descriptor_load: true)
|
|
84
|
-
rescue
|
|
79
|
+
rescue StandardError => e
|
|
85
80
|
MU.log "Can't load a deploy record for #{deploy_id} (#{e.inspect}), cleaning up resources by guesswork", MU::WARN, details: e.backtrace
|
|
86
81
|
MU.setVar("deploy_id", deploy_id)
|
|
87
|
-
|
|
88
82
|
end
|
|
89
83
|
end
|
|
90
84
|
|
|
91
|
-
regionsused = @mommacat.regionsUsed if @mommacat
|
|
92
|
-
credsused = @mommacat.credsUsed if @mommacat
|
|
85
|
+
@regionsused = @mommacat.regionsUsed if @mommacat
|
|
86
|
+
@credsused = @mommacat.credsUsed if @mommacat
|
|
87
|
+
@habitatsused = @mommacat.habitatsUsed if @mommacat
|
|
93
88
|
|
|
94
89
|
if !@skipcloud
|
|
95
|
-
creds =
|
|
96
|
-
MU::Cloud.availableClouds.each { |cloud|
|
|
97
|
-
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
|
|
98
|
-
if $MU_CFG[cloud.downcase] and $MU_CFG[cloud.downcase].size > 0
|
|
99
|
-
creds[cloud] ||= {}
|
|
100
|
-
cloudclass.listCredentials.each { |credset|
|
|
101
|
-
next if credsets and credsets.size > 0 and !credsets.include?(credset)
|
|
102
|
-
next if credsused and credsused.size > 0 and !credsused.include?(credset)
|
|
103
|
-
MU.log "Will scan #{cloud} with credentials #{credset}"
|
|
104
|
-
creds[cloud][credset] = cloudclass.listRegions(credentials: credset)
|
|
105
|
-
}
|
|
106
|
-
else
|
|
107
|
-
if cloudclass.hosted?
|
|
108
|
-
creds[cloud] ||= {}
|
|
109
|
-
creds[cloud]["#default"] = cloudclass.listRegions
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
}
|
|
90
|
+
creds = listUsedCredentials(credsets)
|
|
113
91
|
|
|
114
|
-
parent_thread_id = Thread.current.object_id
|
|
115
|
-
deleted_nodes = 0
|
|
116
92
|
cloudthreads = []
|
|
117
|
-
|
|
93
|
+
|
|
118
94
|
had_failures = false
|
|
119
95
|
|
|
120
96
|
creds.each_pair { |provider, credsets_outer|
|
|
121
97
|
cloudthreads << Thread.new(provider, credsets_outer) { |cloud, credsets_inner|
|
|
122
|
-
MU.dupGlobals(parent_thread_id)
|
|
123
98
|
Thread.abort_on_exception = false
|
|
124
|
-
|
|
125
|
-
habitatclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get("Habitat")
|
|
126
|
-
credsets_inner.each_pair { |credset, acct_regions|
|
|
127
|
-
next if credsused and !credsused.include?(credset)
|
|
128
|
-
global_vs_region_semaphore = Mutex.new
|
|
129
|
-
global_done = {}
|
|
130
|
-
habitats_done = {}
|
|
131
|
-
regionthreads = []
|
|
132
|
-
acct_regions.each { |r|
|
|
133
|
-
if regionsused
|
|
134
|
-
if regionsused.size > 0
|
|
135
|
-
next if !regionsused.include?(r)
|
|
136
|
-
else
|
|
137
|
-
next if r != cloudclass.myRegion(credset)
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
if regions and !regions.empty?
|
|
141
|
-
next if !regions.include?(r)
|
|
142
|
-
MU.log "Checking for #{cloud}/#{credset} resources from #{MU.deploy_id} in #{r}...", MU::NOTICE
|
|
143
|
-
end
|
|
144
|
-
regionthreads << Thread.new {
|
|
145
|
-
MU.dupGlobals(parent_thread_id)
|
|
146
|
-
Thread.abort_on_exception = false
|
|
147
|
-
MU.setVar("curRegion", r)
|
|
148
|
-
projects = []
|
|
149
|
-
if habitats
|
|
150
|
-
projects = habitats
|
|
151
|
-
else
|
|
152
|
-
if $MU_CFG and $MU_CFG[cloud.downcase] and
|
|
153
|
-
$MU_CFG[cloud.downcase][credset] and
|
|
154
|
-
$MU_CFG[cloud.downcase][credset]["project"]
|
|
155
|
-
# XXX GCP credential schema needs an array for projects
|
|
156
|
-
projects << $MU_CFG[cloud.downcase][credset]["project"]
|
|
157
|
-
end
|
|
158
|
-
begin
|
|
159
|
-
projects.concat(cloudclass.listProjects(credset))
|
|
160
|
-
rescue NoMethodError
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
if projects == []
|
|
165
|
-
projects << "" # dummy
|
|
166
|
-
MU.log "Checking for #{cloud}/#{credset} resources from #{MU.deploy_id} in #{r}", MU::NOTICE
|
|
167
|
-
end
|
|
168
|
-
projects.uniq!
|
|
169
|
-
|
|
170
|
-
# We do these in an order that unrolls dependent resources
|
|
171
|
-
# sensibly, and we hit :Collection twice because AWS
|
|
172
|
-
# CloudFormation sometimes fails internally.
|
|
173
|
-
projectthreads = []
|
|
174
|
-
projects.each { |project|
|
|
175
|
-
next if !habitatclass.isLive?(project, credset)
|
|
176
|
-
if habitats and !habitats.empty? and project != ""
|
|
177
|
-
next if !habitats.include?(project)
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
projectthreads << Thread.new {
|
|
181
|
-
MU.dupGlobals(parent_thread_id)
|
|
182
|
-
MU.setVar("curRegion", r)
|
|
183
|
-
Thread.abort_on_exception = false
|
|
184
|
-
if project != ""
|
|
185
|
-
MU.log "Checking for #{cloud}/#{credset} resources from #{MU.deploy_id} in #{r}, project #{project}", MU::NOTICE
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
MU.dupGlobals(parent_thread_id)
|
|
189
|
-
flags = {
|
|
190
|
-
"project" => project,
|
|
191
|
-
"onlycloud" => @onlycloud,
|
|
192
|
-
"skipsnapshots" => @skipsnapshots,
|
|
193
|
-
}
|
|
194
|
-
types_in_order.each { |t|
|
|
195
|
-
shortclass, cfg_name, cfg_plural, classname = MU::Cloud.getResourceNames(t)
|
|
196
|
-
begin
|
|
197
|
-
skipme = false
|
|
198
|
-
global_vs_region_semaphore.synchronize {
|
|
199
|
-
MU::Cloud.loadCloudType(cloud, t)
|
|
200
|
-
if Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get(t).isGlobal?
|
|
201
|
-
global_done[project] ||= []
|
|
202
|
-
if !global_done[project].include?(t)
|
|
203
|
-
global_done[project] << t
|
|
204
|
-
flags['global'] = true
|
|
205
|
-
else
|
|
206
|
-
skipme = true
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
}
|
|
210
|
-
next if skipme
|
|
211
|
-
rescue MU::Cloud::MuDefunctHabitat, MU::Cloud::MuCloudResourceNotImplemented => e
|
|
212
|
-
next
|
|
213
|
-
rescue MU::MuError, NoMethodError => e
|
|
214
|
-
MU.log "While checking mu/clouds/#{cloud.downcase}/#{cloudclass.cfg_name} for global-ness in cleanup: "+e.message, MU::WARN
|
|
215
|
-
next
|
|
216
|
-
rescue ::Aws::EC2::Errors::AuthFailure, ::Google::Apis::ClientError => e
|
|
217
|
-
MU.log e.message+" in "+r, MU::ERR
|
|
218
|
-
next
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
begin
|
|
222
|
-
if !self.call_cleanup(t, credset, cloud, flags, r)
|
|
223
|
-
had_failures = true
|
|
224
|
-
end
|
|
225
|
-
rescue MU::Cloud::MuDefunctHabitat, MU::Cloud::MuCloudResourceNotImplemented => e
|
|
226
|
-
next
|
|
227
|
-
end
|
|
228
|
-
}
|
|
229
|
-
} # types_in_order.each { |t|
|
|
230
|
-
} # projects.each { |project|
|
|
231
|
-
projectthreads.each do |t|
|
|
232
|
-
t.join
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
# XXX move to MU::AWS
|
|
236
|
-
if cloud == "AWS"
|
|
237
|
-
resp = MU::Cloud::AWS.ec2(region: r, credentials: credset).describe_key_pairs(
|
|
238
|
-
filters: [{name: "key-name", values: [keyname]}]
|
|
239
|
-
)
|
|
240
|
-
resp.data.key_pairs.each { |keypair|
|
|
241
|
-
MU.log "Deleting key pair #{keypair.key_name} from #{r}"
|
|
242
|
-
MU::Cloud::AWS.ec2(region: r, credentials: credset).delete_key_pair(key_name: keypair.key_name) if !@noop
|
|
243
|
-
}
|
|
244
|
-
end
|
|
245
|
-
} # regionthreads << Thread.new {
|
|
246
|
-
} # acct_regions.each { |r|
|
|
247
|
-
regionthreads.each do |t|
|
|
248
|
-
t.join
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
} # credsets.each_pair { |credset, acct_regions|
|
|
99
|
+
cleanCloud(cloud, habitats, regions, credsets_inner)
|
|
252
100
|
} # cloudthreads << Thread.new(provider, credsets) { |cloud, credsets_outer|
|
|
253
101
|
cloudthreads.each do |t|
|
|
254
102
|
t.join
|
|
@@ -260,24 +108,21 @@ module MU
|
|
|
260
108
|
# once they're all done.
|
|
261
109
|
creds.each_pair { |provider, credsets_inner|
|
|
262
110
|
credsets_inner.keys.each { |credset|
|
|
263
|
-
next if credsused and
|
|
111
|
+
next if @credsused and !@credsused.include?(credset)
|
|
264
112
|
["Habitat", "Folder"].each { |t|
|
|
265
113
|
flags = {
|
|
266
114
|
"onlycloud" => @onlycloud,
|
|
267
115
|
"skipsnapshots" => @skipsnapshots
|
|
268
116
|
}
|
|
269
|
-
if !
|
|
117
|
+
if !call_cleanup(t, credset, provider, flags, nil)
|
|
270
118
|
had_failures = true
|
|
271
119
|
end
|
|
272
120
|
}
|
|
273
121
|
}
|
|
274
122
|
}
|
|
275
123
|
|
|
276
|
-
MU::Cloud::Google.removeDeploySecretsAndRoles(MU.deploy_id)
|
|
277
|
-
# XXX port AWS equivalent behavior and add a MU::Cloud wrapper
|
|
278
|
-
|
|
279
124
|
creds.each_pair { |provider, credsets_inner|
|
|
280
|
-
cloudclass =
|
|
125
|
+
cloudclass = MU::Cloud.cloudClass(provider)
|
|
281
126
|
credsets_inner.keys.each { |c|
|
|
282
127
|
cloudclass.cleanDeploy(MU.deploy_id, credentials: c, noop: @noop)
|
|
283
128
|
}
|
|
@@ -285,44 +130,16 @@ module MU
|
|
|
285
130
|
end
|
|
286
131
|
|
|
287
132
|
# Scrub any residual Chef records with matching tags
|
|
288
|
-
if !@onlycloud and (@mommacat.nil? or @mommacat.numKittens(types: ["Server", "ServerPool"]) > 0) and
|
|
289
|
-
|
|
290
|
-
MU::Groomer
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
end
|
|
294
|
-
deadnodes = []
|
|
295
|
-
Chef::Config[:environment] = MU.environment
|
|
296
|
-
q = Chef::Search::Query.new
|
|
297
|
-
begin
|
|
298
|
-
q.search("node", "tags_MU-ID:#{MU.deploy_id}").each { |item|
|
|
299
|
-
next if item.is_a?(Integer)
|
|
300
|
-
item.each { |node|
|
|
301
|
-
deadnodes << node.name
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
rescue Net::HTTPServerException
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
begin
|
|
308
|
-
q.search("node", "name:#{MU.deploy_id}-*").each { |item|
|
|
309
|
-
next if item.is_a?(Integer)
|
|
310
|
-
item.each { |node|
|
|
311
|
-
deadnodes << node.name
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
rescue Net::HTTPServerException
|
|
315
|
-
end
|
|
316
|
-
MU.log "Missed some Chef resources in node cleanup, purging now", MU::NOTICE if deadnodes.size > 0
|
|
317
|
-
deadnodes.uniq.each { |node|
|
|
318
|
-
MU::Groomer::Chef.cleanup(node, [], noop)
|
|
319
|
-
}
|
|
320
|
-
rescue LoadError
|
|
321
|
-
end
|
|
133
|
+
if !@onlycloud and (@mommacat.nil? or @mommacat.numKittens(types: ["Server", "ServerPool"]) > 0) and !@noop
|
|
134
|
+
MU.supportedGroomers.each { |g|
|
|
135
|
+
groomer = MU::Groomer.loadGroomer(g)
|
|
136
|
+
groomer.cleanup(MU.deploy_id, @noop)
|
|
137
|
+
}
|
|
322
138
|
end
|
|
323
139
|
|
|
324
140
|
if had_failures
|
|
325
141
|
MU.log "Had cleanup failures, exiting", MU::ERR
|
|
142
|
+
File.unlink("#{deploy_dir}/.cleanup") if !@noop
|
|
326
143
|
exit 1
|
|
327
144
|
end
|
|
328
145
|
|
|
@@ -330,134 +147,210 @@ module MU
|
|
|
330
147
|
@mommacat.purge!
|
|
331
148
|
end
|
|
332
149
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
ssharchive = "#{sshdir}/archive"
|
|
337
|
-
|
|
338
|
-
Dir.mkdir(sshdir, 0700) if !Dir.exist?(sshdir) and !@noop
|
|
339
|
-
Dir.mkdir(ssharchive, 0700) if !Dir.exist?(ssharchive) and !@noop
|
|
150
|
+
if !@onlycloud
|
|
151
|
+
MU::Master.purgeDeployFromSSH(MU.deploy_id, noop: @noop)
|
|
152
|
+
end
|
|
340
153
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
MU.log "Moving #{sshdir}/#{keyname} to #{ssharchive}/#{keyname}"
|
|
344
|
-
if !@noop
|
|
345
|
-
File.rename("#{sshdir}/#{keyname}", "#{ssharchive}/#{keyname}")
|
|
346
|
-
end
|
|
154
|
+
if !@noop and !@skipcloud and (@mommacat.nil? or @mommacat.numKittens(types: ["Server", "ServerPool"]) > 0)
|
|
155
|
+
# MU::Master.syncMonitoringConfig
|
|
347
156
|
end
|
|
348
157
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
end
|
|
363
|
-
newlines << line if !delete_block
|
|
364
|
-
}
|
|
365
|
-
f.rewind
|
|
366
|
-
f.truncate(0)
|
|
367
|
-
f.puts(newlines)
|
|
368
|
-
f.flush
|
|
369
|
-
f.flock(File::LOCK_UN)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def self.listUsedCredentials(credsets)
|
|
161
|
+
creds = {}
|
|
162
|
+
MU::Cloud.availableClouds.each { |cloud|
|
|
163
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
164
|
+
if $MU_CFG[cloud.downcase] and $MU_CFG[cloud.downcase].size > 0
|
|
165
|
+
creds[cloud] ||= {}
|
|
166
|
+
cloudclass.listCredentials.each { |credset|
|
|
167
|
+
next if credsets and credsets.size > 0 and !credsets.include?(credset)
|
|
168
|
+
next if @credsused and @credsused.size > 0 and !@credsused.include?(credset)
|
|
169
|
+
MU.log "Will scan #{cloud} with credentials #{credset}"
|
|
170
|
+
creds[cloud][credset] = cloudclass.listRegions(credentials: credset)
|
|
370
171
|
}
|
|
172
|
+
else
|
|
173
|
+
if cloudclass.hosted?
|
|
174
|
+
creds[cloud] ||= {}
|
|
175
|
+
creds[cloud]["#default"] = cloudclass.listRegions
|
|
176
|
+
end
|
|
371
177
|
end
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
f.flock(File::LOCK_UN)
|
|
392
|
-
}
|
|
178
|
+
}
|
|
179
|
+
creds
|
|
180
|
+
end
|
|
181
|
+
private_class_method :listUsedCredentials
|
|
182
|
+
|
|
183
|
+
def self.cleanCloud(cloud, habitats, regions, credsets)
|
|
184
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
185
|
+
credsets.each_pair { |credset, acct_regions|
|
|
186
|
+
next if @credsused and !@credsused.include?(credset)
|
|
187
|
+
global_vs_region_semaphore = Mutex.new
|
|
188
|
+
global_done = {}
|
|
189
|
+
regionthreads = []
|
|
190
|
+
acct_regions.each { |r|
|
|
191
|
+
if @regionsused
|
|
192
|
+
if @regionsused.size > 0
|
|
193
|
+
next if !@regionsused.include?(r)
|
|
194
|
+
else
|
|
195
|
+
next if r != cloudclass.myRegion(credset)
|
|
196
|
+
end
|
|
393
197
|
end
|
|
394
|
-
|
|
395
|
-
|
|
198
|
+
if regions and !regions.empty?
|
|
199
|
+
next if !regions.include?(r)
|
|
200
|
+
MU.log "Checking for #{cloud}/#{credset} resources from #{MU.deploy_id} in #{r}...", MU::NOTICE
|
|
201
|
+
end
|
|
202
|
+
regionthreads << Thread.new {
|
|
203
|
+
Thread.abort_on_exception = false
|
|
204
|
+
MU.setVar("curRegion", r)
|
|
205
|
+
cleanRegion(cloud, credset, r, global_vs_region_semaphore, global_done, habitats)
|
|
206
|
+
} # regionthreads << Thread.new {
|
|
207
|
+
} # acct_regions.each { |r|
|
|
208
|
+
regionthreads.each do |t|
|
|
209
|
+
t.join
|
|
396
210
|
end
|
|
397
|
-
|
|
211
|
+
}
|
|
212
|
+
end
|
|
213
|
+
private_class_method :cleanCloud
|
|
398
214
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
raise e if !e.message.match(/^notFound: /)
|
|
414
|
-
end
|
|
215
|
+
def self.cleanRegion(cloud, credset, region, global_vs_region_semaphore, global_done, habitats)
|
|
216
|
+
had_failures = false
|
|
217
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
218
|
+
habitatclass = MU::Cloud.resourceClass(cloud, "Habitat")
|
|
219
|
+
|
|
220
|
+
projects = []
|
|
221
|
+
if habitats
|
|
222
|
+
projects = habitats
|
|
223
|
+
else
|
|
224
|
+
if $MU_CFG and $MU_CFG[cloud.downcase] and
|
|
225
|
+
$MU_CFG[cloud.downcase][credset] and
|
|
226
|
+
$MU_CFG[cloud.downcase][credset]["project"]
|
|
227
|
+
# XXX GCP credential schema needs an array for projects
|
|
228
|
+
projects << $MU_CFG[cloud.downcase][credset]["project"]
|
|
415
229
|
end
|
|
416
|
-
|
|
417
|
-
|
|
230
|
+
begin
|
|
231
|
+
projects.concat(cloudclass.listHabitats(credset, use_cache: false))
|
|
232
|
+
rescue NoMethodError
|
|
418
233
|
end
|
|
419
234
|
end
|
|
420
235
|
|
|
421
|
-
if
|
|
422
|
-
#
|
|
236
|
+
if projects == []
|
|
237
|
+
projects << "" # dummy
|
|
238
|
+
MU.log "Checking for #{cloud}/#{credset} resources from #{MU.deploy_id} in #{region}", MU::NOTICE
|
|
239
|
+
end
|
|
240
|
+
projects.uniq!
|
|
241
|
+
|
|
242
|
+
# We do these in an order that unrolls dependent resources
|
|
243
|
+
# sensibly, and we hit :Collection twice because AWS
|
|
244
|
+
# CloudFormation sometimes fails internally.
|
|
245
|
+
projectthreads = []
|
|
246
|
+
projects.each { |project|
|
|
247
|
+
if habitats and !habitats.empty? and project != ""
|
|
248
|
+
next if !habitats.include?(project)
|
|
249
|
+
end
|
|
250
|
+
if @habitatsused and !@habitatsused.empty? and project != ""
|
|
251
|
+
next if !@habitatsused.include?(project)
|
|
252
|
+
end
|
|
253
|
+
next if !habitatclass.isLive?(project, credset)
|
|
254
|
+
|
|
255
|
+
projectthreads << Thread.new {
|
|
256
|
+
Thread.abort_on_exception = false
|
|
257
|
+
if !cleanHabitat(cloud, credset, region, project, global_vs_region_semaphore, global_done)
|
|
258
|
+
had_failures = true
|
|
259
|
+
end
|
|
260
|
+
} # TYPES_IN_ORDER.each { |t|
|
|
261
|
+
} # projects.each { |project|
|
|
262
|
+
projectthreads.each do |t|
|
|
263
|
+
t.join
|
|
423
264
|
end
|
|
424
265
|
|
|
266
|
+
had_failures
|
|
425
267
|
end
|
|
268
|
+
private_class_method :cleanRegion
|
|
269
|
+
|
|
270
|
+
def self.cleanHabitat(cloud, credset, region, habitat, global_vs_region_semaphore, global_done)
|
|
271
|
+
had_failures = false
|
|
272
|
+
if habitat != ""
|
|
273
|
+
MU.log "Checking for #{cloud}/#{credset} resources from #{MU.deploy_id} in #{region}, habitat #{habitat}", MU::NOTICE
|
|
274
|
+
end
|
|
426
275
|
|
|
427
|
-
|
|
276
|
+
flags = {
|
|
277
|
+
"habitat" => habitat,
|
|
278
|
+
"onlycloud" => @onlycloud,
|
|
279
|
+
"skipsnapshots" => @skipsnapshots,
|
|
280
|
+
}
|
|
281
|
+
TYPES_IN_ORDER.each { |t|
|
|
282
|
+
begin
|
|
283
|
+
skipme = false
|
|
284
|
+
global_vs_region_semaphore.synchronize {
|
|
285
|
+
if MU::Cloud.resourceClass(cloud, t).isGlobal?
|
|
286
|
+
global_done[habitat] ||= []
|
|
287
|
+
if !global_done[habitat].include?(t)
|
|
288
|
+
global_done[habitat] << t
|
|
289
|
+
flags['global'] = true
|
|
290
|
+
else
|
|
291
|
+
skipme = true
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
}
|
|
295
|
+
next if skipme
|
|
296
|
+
rescue MU::Cloud::MuDefunctHabitat, MU::Cloud::MuCloudResourceNotImplemented
|
|
297
|
+
next
|
|
298
|
+
rescue MU::MuError, NoMethodError => e
|
|
299
|
+
MU.log "While checking mu/providers/#{cloud.downcase}/#{cloudclass.cfg_name} for global-ness in cleanup: "+e.message, MU::WARN
|
|
300
|
+
next
|
|
301
|
+
rescue ::Aws::EC2::Errors::AuthFailure, ::Google::Apis::ClientError => e
|
|
302
|
+
MU.log e.message+" in "+region, MU::ERR
|
|
303
|
+
next
|
|
304
|
+
end
|
|
428
305
|
|
|
306
|
+
begin
|
|
307
|
+
if !call_cleanup(t, credset, cloud, flags, region)
|
|
308
|
+
had_failures = true
|
|
309
|
+
end
|
|
310
|
+
rescue MU::Cloud::MuDefunctHabitat, MU::Cloud::MuCloudResourceNotImplemented
|
|
311
|
+
next
|
|
312
|
+
end
|
|
313
|
+
}
|
|
314
|
+
had_failures = true
|
|
315
|
+
end
|
|
316
|
+
private_class_method :cleanHabitat
|
|
317
|
+
|
|
318
|
+
# Wrapper for dynamically invoking resource type cleanup methods.
|
|
319
|
+
# @param type [String]:
|
|
320
|
+
# @param credset [String]:
|
|
321
|
+
# @param provider [String]:
|
|
322
|
+
# @param flags [Hash]:
|
|
323
|
+
# @param region [String]:
|
|
429
324
|
def self.call_cleanup(type, credset, provider, flags, region)
|
|
430
325
|
if @mommacat.nil? or @mommacat.numKittens(types: [type]) > 0
|
|
431
326
|
if @mommacat
|
|
327
|
+
|
|
432
328
|
found = @mommacat.findLitterMate(type: type, return_all: true, credentials: credset)
|
|
433
|
-
|
|
434
|
-
if found
|
|
435
|
-
found.
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
329
|
+
|
|
330
|
+
if found
|
|
331
|
+
flags['known'] = if found.is_a?(Array)
|
|
332
|
+
found.map { |k| k.cloud_id }
|
|
333
|
+
elsif found.is_a?(Hash)
|
|
334
|
+
found.each_value.map { |k| k.cloud_id }
|
|
335
|
+
else
|
|
336
|
+
[found.cloud_id]
|
|
337
|
+
end
|
|
442
338
|
end
|
|
443
339
|
end
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
credentials: credset
|
|
454
|
-
)
|
|
455
|
-
# rescue ::Seahorse::Client::NetworkingError => e
|
|
456
|
-
# MU.log "Service not available in AWS region #{r}, skipping", MU::DEBUG, details: e.message
|
|
457
|
-
# end
|
|
340
|
+
|
|
341
|
+
MU::Cloud.loadBaseType(type).cleanup(
|
|
342
|
+
noop: @noop,
|
|
343
|
+
ignoremaster: @ignoremaster,
|
|
344
|
+
region: region,
|
|
345
|
+
cloud: provider,
|
|
346
|
+
flags: flags,
|
|
347
|
+
credentials: credset
|
|
348
|
+
)
|
|
458
349
|
else
|
|
459
350
|
true
|
|
460
351
|
end
|
|
461
352
|
end
|
|
353
|
+
private_class_method :call_cleanup
|
|
354
|
+
|
|
462
355
|
end #class
|
|
463
356
|
end #module
|