cloud-mu 1.9.0.pre.beta → 2.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Berksfile +16 -54
- data/Berksfile.lock +14 -62
- data/bin/mu-aws-setup +131 -108
- data/bin/mu-configure +311 -74
- data/bin/mu-gcp-setup +84 -62
- data/bin/mu-load-config.rb +46 -2
- data/bin/mu-self-update +11 -9
- data/bin/mu-upload-chef-artifacts +4 -4
- data/{mu.gemspec → cloud-mu.gemspec} +2 -2
- data/cookbooks/awscli/Berksfile +8 -0
- data/cookbooks/mu-activedirectory/Berksfile +11 -0
- data/cookbooks/mu-firewall/Berksfile +9 -0
- data/cookbooks/mu-firewall/metadata.rb +1 -1
- data/cookbooks/mu-glusterfs/Berksfile +10 -0
- data/cookbooks/mu-jenkins/Berksfile +14 -0
- data/cookbooks/mu-master/Berksfile +23 -0
- data/cookbooks/mu-master/attributes/default.rb +1 -1
- data/cookbooks/mu-master/metadata.rb +2 -2
- data/cookbooks/mu-master/recipes/default.rb +1 -1
- data/cookbooks/mu-master/recipes/init.rb +7 -3
- data/cookbooks/mu-master/recipes/ssl-certs.rb +1 -0
- data/cookbooks/mu-mongo/Berksfile +10 -0
- data/cookbooks/mu-openvpn/Berksfile +11 -0
- data/cookbooks/mu-php54/Berksfile +13 -0
- data/cookbooks/mu-splunk/Berksfile +10 -0
- data/cookbooks/mu-tools/Berksfile +21 -0
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +15 -15
- data/cookbooks/mu-utility/Berksfile +9 -0
- data/cookbooks/mu-utility/metadata.rb +2 -1
- data/cookbooks/nagios/Berksfile +7 -4
- data/cookbooks/s3fs/Berksfile +9 -0
- data/environments/dev.json +6 -6
- data/environments/prod.json +6 -6
- data/modules/mu.rb +20 -42
- data/modules/mu/cleanup.rb +102 -100
- data/modules/mu/cloud.rb +90 -28
- data/modules/mu/clouds/aws.rb +449 -218
- data/modules/mu/clouds/aws/alarm.rb +29 -17
- data/modules/mu/clouds/aws/cache_cluster.rb +78 -64
- data/modules/mu/clouds/aws/collection.rb +25 -18
- data/modules/mu/clouds/aws/container_cluster.rb +73 -66
- data/modules/mu/clouds/aws/database.rb +124 -116
- data/modules/mu/clouds/aws/dnszone.rb +27 -20
- data/modules/mu/clouds/aws/firewall_rule.rb +30 -22
- data/modules/mu/clouds/aws/folder.rb +18 -3
- data/modules/mu/clouds/aws/function.rb +77 -23
- data/modules/mu/clouds/aws/group.rb +19 -12
- data/modules/mu/clouds/aws/habitat.rb +153 -0
- data/modules/mu/clouds/aws/loadbalancer.rb +59 -52
- data/modules/mu/clouds/aws/log.rb +30 -23
- data/modules/mu/clouds/aws/msg_queue.rb +29 -20
- data/modules/mu/clouds/aws/notifier.rb +222 -0
- data/modules/mu/clouds/aws/role.rb +178 -90
- data/modules/mu/clouds/aws/search_domain.rb +40 -24
- data/modules/mu/clouds/aws/server.rb +169 -137
- data/modules/mu/clouds/aws/server_pool.rb +60 -83
- data/modules/mu/clouds/aws/storage_pool.rb +59 -31
- data/modules/mu/clouds/aws/user.rb +36 -27
- data/modules/mu/clouds/aws/userdata/linux.erb +101 -93
- data/modules/mu/clouds/aws/vpc.rb +250 -189
- data/modules/mu/clouds/azure.rb +132 -0
- data/modules/mu/clouds/cloudformation.rb +65 -1
- data/modules/mu/clouds/cloudformation/alarm.rb +8 -0
- data/modules/mu/clouds/cloudformation/cache_cluster.rb +7 -0
- data/modules/mu/clouds/cloudformation/collection.rb +7 -0
- data/modules/mu/clouds/cloudformation/database.rb +7 -0
- data/modules/mu/clouds/cloudformation/dnszone.rb +7 -0
- data/modules/mu/clouds/cloudformation/firewall_rule.rb +9 -2
- data/modules/mu/clouds/cloudformation/loadbalancer.rb +7 -0
- data/modules/mu/clouds/cloudformation/log.rb +7 -0
- data/modules/mu/clouds/cloudformation/server.rb +7 -0
- data/modules/mu/clouds/cloudformation/server_pool.rb +7 -0
- data/modules/mu/clouds/cloudformation/vpc.rb +7 -0
- data/modules/mu/clouds/google.rb +214 -110
- data/modules/mu/clouds/google/container_cluster.rb +42 -24
- data/modules/mu/clouds/google/database.rb +15 -6
- data/modules/mu/clouds/google/firewall_rule.rb +17 -25
- data/modules/mu/clouds/google/group.rb +13 -5
- data/modules/mu/clouds/google/habitat.rb +105 -0
- data/modules/mu/clouds/google/loadbalancer.rb +28 -20
- data/modules/mu/clouds/google/server.rb +93 -354
- data/modules/mu/clouds/google/server_pool.rb +18 -10
- data/modules/mu/clouds/google/user.rb +22 -14
- data/modules/mu/clouds/google/vpc.rb +97 -69
- data/modules/mu/config.rb +133 -38
- data/modules/mu/config/alarm.rb +25 -0
- data/modules/mu/config/cache_cluster.rb +5 -3
- data/modules/mu/config/cache_cluster.yml +23 -0
- data/modules/mu/config/database.rb +25 -16
- data/modules/mu/config/database.yml +3 -3
- data/modules/mu/config/function.rb +1 -2
- data/modules/mu/config/{project.rb → habitat.rb} +10 -10
- data/modules/mu/config/notifier.rb +85 -0
- data/modules/mu/config/notifier.yml +9 -0
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/search_domain.yml +2 -2
- data/modules/mu/config/server.rb +13 -1
- data/modules/mu/config/server.yml +3 -3
- data/modules/mu/config/server_pool.rb +3 -1
- data/modules/mu/config/storage_pool.rb +3 -1
- data/modules/mu/config/storage_pool.yml +19 -0
- data/modules/mu/config/vpc.rb +70 -8
- data/modules/mu/groomers/chef.rb +2 -3
- data/modules/mu/kittens.rb +500 -122
- data/modules/mu/master.rb +5 -5
- data/modules/mu/mommacat.rb +151 -91
- data/modules/tests/super_complex_bok.yml +12 -0
- data/modules/tests/super_simple_bok.yml +12 -0
- data/spec/mu/clouds/azure_spec.rb +82 -0
- data/spec/spec_helper.rb +105 -0
- metadata +26 -5
- data/modules/mu/clouds/aws/notification.rb +0 -139
- data/modules/mu/config/notification.rb +0 -44
@@ -40,7 +40,7 @@ module MU
|
|
40
40
|
def create
|
41
41
|
|
42
42
|
begin
|
43
|
-
MU::Cloud::AWS.iam.get_user(user_name: @mu_name, path: @config['path'])
|
43
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_user(user_name: @mu_name, path: @config['path'])
|
44
44
|
if !@config['use_if_exists']
|
45
45
|
raise MuError, "IAM user #{@mu_name} already exists and use_if_exists is false"
|
46
46
|
end
|
@@ -48,7 +48,7 @@ module MU
|
|
48
48
|
@config['path'] ||= "/"+@deploy.deploy_id+"/"
|
49
49
|
MU.log "Creating IAM user #{@config['path']}/#{@mu_name}"
|
50
50
|
tags = get_tag_params
|
51
|
-
MU::Cloud::AWS.iam.create_user(
|
51
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_user(
|
52
52
|
user_name: @mu_name,
|
53
53
|
path: @config['path'],
|
54
54
|
tags: tags
|
@@ -59,7 +59,7 @@ module MU
|
|
59
59
|
|
60
60
|
# Called automatically by {MU::Deploy#createResources}
|
61
61
|
def groom
|
62
|
-
resp = MU::Cloud::AWS.iam.list_user_tags(user_name: @mu_name)
|
62
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_user_tags(user_name: @mu_name)
|
63
63
|
|
64
64
|
ext_tags = resp.tags.map { |t| t.to_h }
|
65
65
|
tag_param = get_tag_params(true)
|
@@ -67,7 +67,7 @@ module MU
|
|
67
67
|
|
68
68
|
if tag_param.size > 0
|
69
69
|
MU.log "Updating tags on IAM user #{@mu_name}", MU::NOTICE, details: tag_param
|
70
|
-
MU::Cloud::AWS.iam.tag_user(user_name: @mu_name, tags: tag_param)
|
70
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).tag_user(user_name: @mu_name, tags: tag_param)
|
71
71
|
end
|
72
72
|
# Note: We don't delete tags, because we often share user accounts
|
73
73
|
# managed outside of Mu. We have no way of know what tags might come
|
@@ -76,12 +76,12 @@ module MU
|
|
76
76
|
|
77
77
|
if @config['create_console_password']
|
78
78
|
begin
|
79
|
-
MU::Cloud::AWS.iam.get_login_profile(user_name: @mu_name)
|
79
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_login_profile(user_name: @mu_name)
|
80
80
|
rescue Aws::IAM::Errors::NoSuchEntity
|
81
81
|
pw = Password.pronounceable(12..14)
|
82
82
|
retries = 0
|
83
83
|
begin
|
84
|
-
MU::Cloud::AWS.iam.create_login_profile(
|
84
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_login_profile(
|
85
85
|
user_name: @mu_name,
|
86
86
|
password: pw
|
87
87
|
)
|
@@ -101,11 +101,11 @@ module MU
|
|
101
101
|
end
|
102
102
|
|
103
103
|
if @config['create_api_keys']
|
104
|
-
resp = MU::Cloud::AWS.iam.list_access_keys(
|
104
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_access_keys(
|
105
105
|
user_name: @mu_name
|
106
106
|
)
|
107
107
|
if resp.access_key_metadata.size == 0
|
108
|
-
resp = MU::Cloud::AWS.iam.create_access_key(
|
108
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).create_access_key(
|
109
109
|
user_name: @mu_name
|
110
110
|
)
|
111
111
|
scratchitem = MU::Master.storeScratchPadSecret("AWS Access Key and Secret for user #{@mu_name}:\nKEY: #{resp.access_key.access_key_id}\nSECRET: #{resp.access_key.secret_access_key}")
|
@@ -124,61 +124,68 @@ module MU
|
|
124
124
|
# Return the metadata for this user cofiguration
|
125
125
|
# @return [Hash]
|
126
126
|
def notify
|
127
|
-
descriptor = MU.structToHash(MU::Cloud::AWS.iam.get_user(user_name: @mu_name).user)
|
127
|
+
descriptor = MU.structToHash(MU::Cloud::AWS.iam(credentials: @config['credentials']).get_user(user_name: @mu_name).user)
|
128
128
|
descriptor["cloud_id"] = @mu_name
|
129
129
|
descriptor
|
130
130
|
end
|
131
131
|
|
132
|
+
# Does this resource type exist as a global (cloud-wide) artifact, or
|
133
|
+
# is it localized to a region/zone?
|
134
|
+
# @return [Boolean]
|
135
|
+
def self.isGlobal?
|
136
|
+
true
|
137
|
+
end
|
138
|
+
|
132
139
|
# Remove all users associated with the currently loaded deployment.
|
133
140
|
# @param noop [Boolean]: If true, will only print what would be done
|
134
141
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
135
142
|
# @param region [String]: The cloud provider region
|
136
143
|
# @return [void]
|
137
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, flags: {})
|
144
|
+
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
138
145
|
|
139
146
|
# XXX this doesn't belong here; maybe under roles, maybe as its own stupid first-class resource
|
140
|
-
resp = MU::Cloud::AWS.iam.list_policies(
|
147
|
+
resp = MU::Cloud::AWS.iam(credentials: credentials).list_policies(
|
141
148
|
path_prefix: "/"+MU.deploy_id+"/"
|
142
149
|
)
|
143
150
|
if resp and resp.policies
|
144
151
|
resp.policies.each { |policy|
|
145
152
|
MU.log "Deleting policy /#{MU.deploy_id}/#{policy.policy_name}"
|
146
153
|
if !noop
|
147
|
-
attachments = MU::Cloud::AWS.iam.list_entities_for_policy(
|
154
|
+
attachments = MU::Cloud::AWS.iam(credentials: credentials).list_entities_for_policy(
|
148
155
|
policy_arn: policy.arn
|
149
156
|
)
|
150
157
|
attachments.policy_users.each { |u|
|
151
|
-
MU::Cloud::AWS.iam.detach_user_policy(
|
158
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_user_policy(
|
152
159
|
user_name: u.user_name,
|
153
160
|
policy_arn: policy.arn
|
154
161
|
)
|
155
162
|
}
|
156
163
|
attachments.policy_groups.each { |g|
|
157
|
-
MU::Cloud::AWS.iam.detach_role_policy(
|
164
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_role_policy(
|
158
165
|
group_name: g.group_name,
|
159
166
|
policy_arn: policy.arn
|
160
167
|
)
|
161
168
|
}
|
162
169
|
attachments.policy_roles.each { |r|
|
163
|
-
MU::Cloud::AWS.iam.detach_role_policy(
|
170
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_role_policy(
|
164
171
|
role_name: r.role_name,
|
165
172
|
policy_arn: policy.arn
|
166
173
|
)
|
167
174
|
}
|
168
|
-
MU::Cloud::AWS.iam.delete_policy(
|
175
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_policy(
|
169
176
|
policy_arn: policy.arn
|
170
177
|
)
|
171
178
|
end
|
172
179
|
}
|
173
180
|
end
|
174
181
|
|
175
|
-
resp = MU::Cloud::AWS.iam.list_users
|
182
|
+
resp = MU::Cloud::AWS.iam(credentials: credentials).list_users
|
176
183
|
|
177
184
|
# XXX this response includes a tags attribute, but it's always empty,
|
178
185
|
# even when the user is tagged. So we go through the extra call for
|
179
186
|
# each user. Inefficient. Probably Amazon's bug.
|
180
187
|
resp.users.each { |u|
|
181
|
-
tags = MU::Cloud::AWS.iam.list_user_tags(
|
188
|
+
tags = MU::Cloud::AWS.iam(credentials: credentials).list_user_tags(
|
182
189
|
user_name: u.user_name
|
183
190
|
).tags
|
184
191
|
has_nodelete = false
|
@@ -194,43 +201,45 @@ module MU
|
|
194
201
|
MU.log "Deleting IAM user #{u.path}#{u.user_name}"
|
195
202
|
if !@noop
|
196
203
|
begin
|
197
|
-
groups = MU::Cloud::AWS.iam.list_groups_for_user(
|
204
|
+
groups = MU::Cloud::AWS.iam(credentials: credentials).list_groups_for_user(
|
198
205
|
user_name: u.user_name
|
199
206
|
).groups
|
200
207
|
|
201
208
|
groups.each { |g|
|
202
|
-
MU::Cloud::AWS.iam.remove_user_from_group(
|
209
|
+
MU::Cloud::AWS.iam(credentials: credentials).remove_user_from_group(
|
203
210
|
user_name: u.user_name,
|
204
211
|
group_name: g.group_name
|
205
212
|
)
|
206
213
|
}
|
207
|
-
profile = MU::Cloud::AWS.iam.get_login_profile(
|
214
|
+
profile = MU::Cloud::AWS.iam(credentials: credentials).get_login_profile(
|
208
215
|
user_name: u.user_name
|
209
216
|
)
|
210
217
|
MU.log "Deleting IAM login profile for #{u.user_name}"
|
211
|
-
MU::Cloud::AWS.iam.delete_login_profile(
|
218
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_login_profile(
|
212
219
|
user_name: u.user_name
|
213
220
|
)
|
221
|
+
rescue Aws::IAM::Errors::EntityTemporarilyUnmodifiable
|
222
|
+
sleep 10
|
223
|
+
retry
|
214
224
|
rescue Aws::IAM::Errors::NoSuchEntity
|
215
225
|
end
|
216
|
-
keys = MU::Cloud::AWS.iam.list_access_keys(
|
226
|
+
keys = MU::Cloud::AWS.iam(credentials: credentials).list_access_keys(
|
217
227
|
user_name: u.user_name
|
218
228
|
)
|
219
229
|
if keys.access_key_metadata.size > 0
|
220
230
|
keys.access_key_metadata.each { |key|
|
221
231
|
MU.log "Deleting IAM access key #{key.access_key_id} for #{u.user_name}"
|
222
|
-
keys = MU::Cloud::AWS.iam.delete_access_key(
|
232
|
+
keys = MU::Cloud::AWS.iam(credentials: credentials).delete_access_key(
|
223
233
|
user_name: u.user_name,
|
224
234
|
access_key_id: key.access_key_id
|
225
235
|
)
|
226
236
|
}
|
227
237
|
end
|
228
|
-
MU::Cloud::AWS.iam.delete_user(user_name: u.user_name)
|
238
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_user(user_name: u.user_name)
|
229
239
|
end
|
230
240
|
end
|
231
241
|
}
|
232
242
|
|
233
|
-
# MU.log "CLEANUP CALLED ON AWS::USER", MU::WARN, details: resp
|
234
243
|
end
|
235
244
|
|
236
245
|
# Canonical Amazon Resource Number for this resource
|
@@ -244,7 +253,7 @@ module MU
|
|
244
253
|
# @param region [String]: The cloud provider region.
|
245
254
|
# @param flags [Hash]: Optional flags
|
246
255
|
# @return [OpenStruct]: The cloud provider's complete descriptions of matching user group.
|
247
|
-
def self.find(cloud_id: nil, region: MU.curRegion, flags: {})
|
256
|
+
def self.find(cloud_id: nil, region: MU.curRegion, credentials: nil, flags: {})
|
248
257
|
found = nil
|
249
258
|
|
250
259
|
begin
|
@@ -20,94 +20,99 @@ region="`curl -s http://169.254.169.254/latest/meta-data/placement/availability-
|
|
20
20
|
|
21
21
|
# cleanse inherited ephemeral devices that don't actually exist
|
22
22
|
for d in r s t u ;do
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
if [ ! -f "/dev/xvd$d" ];then
|
24
|
+
sed -Ein "s'^(/dev/xvd$d)'#\\1'" /etc/fstab
|
25
|
+
fi
|
26
26
|
done
|
27
27
|
|
28
|
-
if
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
if ping -c 5 8.8.8.8 > /dev/null; then
|
29
|
+
if [ -f /etc/debian_version ];then
|
30
|
+
if ! grep '^/bin/sh /var/lib/cloud/instance/user-data.txt$' /etc/rc.local > /dev/null;then
|
31
|
+
echo "/bin/sh /var/lib/cloud/instance/user-data.txt" >> /etc/rc.local
|
32
|
+
fi
|
33
|
+
apt-get update -y
|
34
|
+
if [ ! -f /usr/bin/pip ] ;then /usr/bin/apt-get --fix-missing -y install python-pip;fi
|
35
|
+
if [ ! -f /usr/bin/curl ] ;then /usr/bin/apt-get --fix-missing -y install curl;fi
|
36
|
+
AWSCLI=/usr/local/bin/aws
|
36
37
|
<% if !$mu.skipApplyUpdates %>
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
if [ ! -f /.mu-installer-ran-updates ];then
|
39
|
+
service ssh stop
|
40
|
+
apt-get --fix-missing -y upgrade
|
41
|
+
if [ $? -eq 0 ]
|
42
|
+
then
|
43
|
+
echo "Successfully updated packages"
|
44
|
+
updates_run=1
|
45
|
+
else
|
46
|
+
echo "FAILED PACKAGE UPDATE" >&2
|
47
|
+
fi
|
48
|
+
# Proceed regardless
|
49
|
+
touch /.mu-installer-ran-updates
|
50
|
+
|
51
|
+
# XXX this logic works on Ubuntu, is it Debian-friendly?
|
52
|
+
latest_kernel="`ls -1 /boot/vmlinuz-* | sed -r 's/^\/boot\/vmlinuz-//' | tail -1`"
|
53
|
+
running_kernel="`uname -r`"
|
54
|
+
if [ "$running_kernel" != "$latest_kernel" -a "$latest_kernel" != "" ];then
|
55
|
+
need_reboot=1
|
56
|
+
else
|
57
|
+
service ssh start
|
58
|
+
fi
|
59
|
+
fi
|
59
60
|
<% end %>
|
60
|
-
elif [ -x /usr/bin/yum ];then
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
61
|
+
elif [ -x /usr/bin/yum ];then
|
62
|
+
version=`/bin/rpm -qa \*-release | grep -Ei "redhat|centos" | cut -d"-" -f3`
|
63
|
+
if [ -z "$version" ];then
|
64
|
+
amazon_version=`/bin/rpm -qa \*-release | grep -Ei "system-release"| cut -d"-" -f3 | cut -d"." -f1`
|
65
|
+
if [ "$amazon_version" == "2014" ] || [ "$amazon_version" == "2015" ] || [ "$amazon_version" == "2016" ];then
|
66
|
+
version=6
|
67
|
+
fi
|
68
|
+
fi
|
69
|
+
if [ $version -eq 7 ];then
|
70
|
+
userdata_dir="/var/lib/cloud/instances/$instance_id"
|
71
|
+
else
|
72
|
+
userdata_dir="/var/lib/cloud/instance"
|
73
|
+
fi
|
74
|
+
if ! grep "^/bin/sh $userdata_dir/user-data.txt$" /etc/rc.d/rc.local > /dev/null;then
|
75
|
+
cat /etc/rc.d/rc.local | grep -v '^/bin/sh /var/lib/cloud/instances/' >> /tmp/rc.local.$$
|
76
|
+
echo "/bin/sh $userdata_dir/user-data.txt" >> /tmp/rc.local.$$
|
77
|
+
mv /tmp/rc.local.$$ /etc/rc.d/rc.local
|
78
|
+
fi
|
79
|
+
|
80
|
+
sed -i 's/^Defaults.*requiretty$/Defaults !requiretty/' /etc/sudoers
|
81
|
+
|
82
|
+
if [ $version == 7 ];then
|
83
|
+
chmod 755 /etc/rc.d/rc.local
|
84
|
+
systemctl reset-failed sshd.service
|
85
|
+
fi
|
86
|
+
if [ ! -f /usr/bin/curl ] ;then /usr/bin/yum -y install curl;fi
|
87
|
+
# Ugh, rando EPEL mirror
|
88
|
+
if [ ! -f /etc/yum.repos.d/epel.repo ];then
|
89
|
+
/bin/rpm -ivh http://mirror.metrocast.net/fedora/epel/epel-release-latest-$version.noarch.rpm
|
90
|
+
fi
|
90
91
|
<% if !$mu.skipApplyUpdates %>
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
92
|
+
if [ ! -f /.mu-installer-ran-updates ];then
|
93
|
+
service sshd stop
|
94
|
+
kernel_update=`yum list updates | grep kernel`
|
95
|
+
yum -y update
|
96
|
+
if [ $? -eq 0 ]
|
97
|
+
then
|
98
|
+
echo "Successfully updated packages"
|
99
|
+
updates_run=1
|
100
|
+
else
|
101
|
+
echo "FAILED PACKAGE UPDATE" >&2
|
102
|
+
fi
|
103
|
+
# Proceed regardless
|
104
|
+
touch /.mu-installer-ran-updates
|
105
|
+
if [ -n "$kernel_update" ]; then
|
106
|
+
need_reboot=1
|
107
|
+
else
|
108
|
+
service sshd start
|
109
|
+
fi
|
110
|
+
fi
|
111
|
+
fi
|
110
112
|
<% end %>
|
113
|
+
else
|
114
|
+
/bin/logger "***** Unable to verify internet connectivity, skipping package updates from userdata"
|
115
|
+
touch /.mu-installer-ran-updates
|
111
116
|
fi
|
112
117
|
|
113
118
|
AWSCLI='command -v aws'
|
@@ -140,24 +145,27 @@ umask 0077
|
|
140
145
|
|
141
146
|
# Install Chef now, because why not?
|
142
147
|
if [ ! -f /opt/chef/embedded/bin/ruby ];then
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
148
|
+
curl https://www.chef.io/chef/install.sh > chef-install.sh
|
149
|
+
set +e
|
150
|
+
# We may run afoul of a synchronous bootstrap process doing the same thing. So
|
151
|
+
# wait until we've managed to run successfully.
|
152
|
+
while ! sh chef-install.sh -v <%= MU.chefVersion %>;do
|
153
|
+
sleep 10
|
154
|
+
done
|
155
|
+
touch /opt/mu_installed_chef
|
156
|
+
set -e
|
152
157
|
fi
|
153
158
|
|
154
159
|
<% if !$mu.skipApplyUpdates %>
|
155
160
|
if [ "$need_reboot" == "1" ];then
|
156
|
-
|
161
|
+
shutdown -r now "Applying new kernel"
|
157
162
|
fi
|
158
163
|
<% end %>
|
164
|
+
fi
|
159
165
|
|
160
|
-
|
166
|
+
if [ "$AWSCLI" != "" ];then
|
167
|
+
$AWSCLI --region="$region" s3 cp s3://<%= MU.adminBucketName %>/<%= $mu.muID %>-secret .
|
168
|
+
fi
|
161
169
|
|
162
170
|
echo '
|
163
171
|
require "openssl"
|
@@ -46,21 +46,21 @@ module MU
|
|
46
46
|
# Called automatically by {MU::Deploy#createResources}
|
47
47
|
def create
|
48
48
|
MU.log "Creating VPC #{@mu_name}", details: @config
|
49
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_vpc(cidr_block: @config['ip_block']).vpc
|
49
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_vpc(cidr_block: @config['ip_block']).vpc
|
50
50
|
vpc_id = @config['vpc_id'] = resp.vpc_id
|
51
51
|
|
52
|
-
MU::MommaCat.createStandardTags(vpc_id, region: @config['region'])
|
53
|
-
MU::MommaCat.createTag(vpc_id, "Name", @mu_name, region: @config['region'])
|
52
|
+
MU::MommaCat.createStandardTags(vpc_id, region: @config['region'], credentials: @config['credentials'])
|
53
|
+
MU::MommaCat.createTag(vpc_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
|
54
54
|
|
55
55
|
if @config['tags']
|
56
56
|
@config['tags'].each { |tag|
|
57
|
-
MU::MommaCat.createTag(vpc_id, tag['key'], tag['value'], region: @config['region'])
|
57
|
+
MU::MommaCat.createTag(vpc_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
|
58
58
|
}
|
59
59
|
end
|
60
60
|
|
61
61
|
if @config['optional_tags']
|
62
62
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
63
|
-
MU::MommaCat.createTag(vpc_id, key, value, region: @config['region'])
|
63
|
+
MU::MommaCat.createTag(vpc_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
64
64
|
}
|
65
65
|
end
|
66
66
|
|
@@ -68,10 +68,10 @@ module MU
|
|
68
68
|
begin
|
69
69
|
MU.log "Waiting for VPC #{@mu_name} (#{vpc_id}) to be available", MU::NOTICE
|
70
70
|
sleep 5
|
71
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_vpcs(vpc_ids: [vpc_id]).vpcs.first
|
71
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_vpcs(vpc_ids: [vpc_id]).vpcs.first
|
72
72
|
end while resp.state != "available"
|
73
73
|
# There's a default route table that comes with. Let's tag it.
|
74
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_route_tables(
|
74
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
75
75
|
filters: [
|
76
76
|
{
|
77
77
|
name: "vpc-id",
|
@@ -80,18 +80,18 @@ module MU
|
|
80
80
|
]
|
81
81
|
)
|
82
82
|
resp.route_tables.each { |rtb|
|
83
|
-
MU::MommaCat.createTag(rtb.route_table_id, "Name", @mu_name+"-#DEFAULTPRIV", region: @config['region'])
|
83
|
+
MU::MommaCat.createTag(rtb.route_table_id, "Name", @mu_name+"-#DEFAULTPRIV", region: @config['region'], credentials: @config['credentials'])
|
84
84
|
if @config['tags']
|
85
85
|
@config['tags'].each { |tag|
|
86
|
-
MU::MommaCat.createTag(rtb.route_table_id, tag['key'], tag['value'], region: @config['region'])
|
86
|
+
MU::MommaCat.createTag(rtb.route_table_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
|
87
87
|
}
|
88
88
|
end
|
89
89
|
|
90
|
-
MU::MommaCat.createStandardTags(rtb.route_table_id, region: @config['region'])
|
90
|
+
MU::MommaCat.createStandardTags(rtb.route_table_id, region: @config['region'], credentials: @config['credentials'])
|
91
91
|
|
92
92
|
if @config['optional_tags']
|
93
93
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
94
|
-
MU::MommaCat.createTag(rtb.route_table_id, key, value, region: @config['region'])
|
94
|
+
MU::MommaCat.createTag(rtb.route_table_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
95
95
|
}
|
96
96
|
end
|
97
97
|
}
|
@@ -101,24 +101,24 @@ module MU
|
|
101
101
|
|
102
102
|
if @config['create_internet_gateway']
|
103
103
|
MU.log "Creating Internet Gateway #{@mu_name}"
|
104
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_internet_gateway
|
104
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_internet_gateway
|
105
105
|
internet_gateway_id = resp.internet_gateway.internet_gateway_id
|
106
106
|
sleep 5
|
107
|
-
MU::MommaCat.createStandardTags(internet_gateway_id, region: @config['region'])
|
108
|
-
MU::MommaCat.createTag(internet_gateway_id, "Name", @mu_name, region: @config['region'])
|
107
|
+
MU::MommaCat.createStandardTags(internet_gateway_id, region: @config['region'], credentials: @config['credentials'])
|
108
|
+
MU::MommaCat.createTag(internet_gateway_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
|
109
109
|
if @config['tags']
|
110
110
|
@config['tags'].each { |tag|
|
111
|
-
MU::MommaCat.createTag(internet_gateway_id, tag['key'], tag['value'], region: @config['region'])
|
111
|
+
MU::MommaCat.createTag(internet_gateway_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
|
112
112
|
}
|
113
113
|
end
|
114
114
|
|
115
115
|
if @config['optional_tags']
|
116
116
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
117
|
-
MU::MommaCat.createTag(internet_gateway_id, key, value, region: @config['region'])
|
117
|
+
MU::MommaCat.createTag(internet_gateway_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
118
118
|
}
|
119
119
|
end
|
120
120
|
|
121
|
-
MU::Cloud::AWS.ec2(@config['region']).attach_internet_gateway(vpc_id: vpc_id, internet_gateway_id: internet_gateway_id)
|
121
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).attach_internet_gateway(vpc_id: vpc_id, internet_gateway_id: internet_gateway_id)
|
122
122
|
@config['internet_gateway_id'] = internet_gateway_id
|
123
123
|
end
|
124
124
|
|
@@ -142,7 +142,7 @@ module MU
|
|
142
142
|
config[:policy_document] = statement.to_json
|
143
143
|
end
|
144
144
|
|
145
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_vpc_endpoint(config).vpc_endpoint
|
145
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_vpc_endpoint(config).vpc_endpoint
|
146
146
|
endpoint_id = resp.vpc_endpoint_id
|
147
147
|
MU.log "Creating VPC endpoint #{endpoint_id}"
|
148
148
|
attempts = 0
|
@@ -151,7 +151,7 @@ module MU
|
|
151
151
|
MU.log "Waiting for VPC endpoint #{endpoint_id} to become available" if attempts % 5 == 0
|
152
152
|
sleep 10
|
153
153
|
begin
|
154
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_vpc_endpoints(vpc_endpoint_ids: [endpoint_id]).vpc_endpoints.first
|
154
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_vpc_endpoints(vpc_endpoint_ids: [endpoint_id]).vpc_endpoints.first
|
155
155
|
rescue Aws::EmptyStructure, NoMethodError
|
156
156
|
sleep 5
|
157
157
|
retry
|
@@ -168,7 +168,7 @@ module MU
|
|
168
168
|
logrole = @deploy.findLitterMate(name: @config['name']+"logrole", type: "roles")
|
169
169
|
|
170
170
|
MU.log "Enabling traffic logging on VPC #{@mu_name} to log group #{loggroup.mu_name}"
|
171
|
-
MU::Cloud::AWS.ec2(@config['region']).create_flow_logs(
|
171
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_flow_logs(
|
172
172
|
resource_ids: [@cloud_id],
|
173
173
|
resource_type: "VPC",
|
174
174
|
traffic_type: "ALL",
|
@@ -187,7 +187,7 @@ module MU
|
|
187
187
|
@config['subnets'].each { |subnet|
|
188
188
|
subnet_name = @config['name']+"-"+subnet['name']
|
189
189
|
MU.log "Creating Subnet #{subnet_name} (#{subnet['ip_block']})", details: subnet
|
190
|
-
azs = MU::Cloud::AWS.listAZs if azs.size == 0
|
190
|
+
azs = MU::Cloud::AWS.listAZs(region: @config['region'], credentials: @config['credentials']) if azs.size == 0
|
191
191
|
if !subnet['availability_zone'].nil?
|
192
192
|
az = subnet['availability_zone']
|
193
193
|
else
|
@@ -196,23 +196,23 @@ module MU
|
|
196
196
|
|
197
197
|
subnetthreads << Thread.new {
|
198
198
|
MU.dupGlobals(parent_thread_id)
|
199
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_subnet(
|
199
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_subnet(
|
200
200
|
vpc_id: vpc_id,
|
201
201
|
cidr_block: subnet['ip_block'],
|
202
202
|
availability_zone: az
|
203
203
|
).subnet
|
204
204
|
subnet_id = subnet['subnet_id'] = resp.subnet_id
|
205
|
-
MU::MommaCat.createStandardTags(subnet_id, region: @config['region'])
|
206
|
-
MU::MommaCat.createTag(subnet_id, "Name", @mu_name+"-"+subnet['name'], region: @config['region'])
|
205
|
+
MU::MommaCat.createStandardTags(subnet_id, region: @config['region'], credentials: @config['credentials'])
|
206
|
+
MU::MommaCat.createTag(subnet_id, "Name", @mu_name+"-"+subnet['name'], region: @config['region'], credentials: @config['credentials'])
|
207
207
|
if @config['tags']
|
208
208
|
@config['tags'].each { |tag|
|
209
|
-
MU::MommaCat.createTag(subnet_id, tag['key'], tag['value'], region: @config['region'])
|
209
|
+
MU::MommaCat.createTag(subnet_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
|
210
210
|
}
|
211
211
|
end
|
212
212
|
|
213
213
|
if @config['optional_tags']
|
214
214
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
215
|
-
MU::MommaCat.createTag(subnet_id, key, value, region: @config['region'])
|
215
|
+
MU::MommaCat.createTag(subnet_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
216
216
|
}
|
217
217
|
end
|
218
218
|
|
@@ -222,7 +222,7 @@ module MU
|
|
222
222
|
begin
|
223
223
|
MU.log "Waiting for Subnet #{subnet_name} (#{subnet_id}) to be available", MU::NOTICE
|
224
224
|
sleep 5
|
225
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
225
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
226
226
|
rescue Aws::EC2::Errors::InvalidSubnetIDNotFound => e
|
227
227
|
sleep 10
|
228
228
|
retry
|
@@ -233,7 +233,7 @@ module MU
|
|
233
233
|
MU.log "Got bogus Aws::EmptyResponse error on #{subnet_id} (retries used: #{retries}/3)", MU::WARN
|
234
234
|
retries = retries + 1
|
235
235
|
sleep 5
|
236
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
236
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
237
237
|
retry
|
238
238
|
else
|
239
239
|
raise e
|
@@ -252,7 +252,7 @@ module MU
|
|
252
252
|
MU.log "Associating Route Table '#{subnet['route_table']}' (#{routes[subnet['route_table']]['route_table_id']}) with #{subnet_name}"
|
253
253
|
retries = 0
|
254
254
|
begin
|
255
|
-
MU::Cloud::AWS.ec2(@config['region']).associate_route_table(
|
255
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).associate_route_table(
|
256
256
|
route_table_id: routes[subnet['route_table']]['route_table_id'],
|
257
257
|
subnet_id: subnet_id
|
258
258
|
)
|
@@ -268,7 +268,7 @@ module MU
|
|
268
268
|
end
|
269
269
|
retries = 0
|
270
270
|
begin
|
271
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
271
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
272
272
|
rescue Aws::EC2::Errors::InvalidSubnetIDNotFound => e
|
273
273
|
if retries < 10
|
274
274
|
MU.log "Got #{e.inspect}, waiting and retrying", MU::WARN
|
@@ -282,7 +282,7 @@ module MU
|
|
282
282
|
if subnet['is_public'] && subnet['create_nat_gateway']
|
283
283
|
MU::MommaCat.lock("nat-gateway-eipalloc")
|
284
284
|
filters = [{name: "domain", values: ["vpc"]}]
|
285
|
-
eips = MU::Cloud::AWS.ec2(@config['region']).describe_addresses(filters: filters).addresses
|
285
|
+
eips = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_addresses(filters: filters).addresses
|
286
286
|
allocation_id = nil
|
287
287
|
eips.each { |eip|
|
288
288
|
next if !eip.association_id.nil? and !eip.association_id.empty?
|
@@ -295,12 +295,12 @@ module MU
|
|
295
295
|
}
|
296
296
|
|
297
297
|
if allocation_id.nil?
|
298
|
-
allocation_id = MU::Cloud::AWS.ec2(@config['region']).allocate_address(domain: "vpc").allocation_id
|
298
|
+
allocation_id = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).allocate_address(domain: "vpc").allocation_id
|
299
299
|
MU::MommaCat.lock(allocation_id, false, true)
|
300
300
|
end
|
301
301
|
|
302
302
|
allocation_ids << allocation_id
|
303
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_nat_gateway(
|
303
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_nat_gateway(
|
304
304
|
subnet_id: subnet['subnet_id'],
|
305
305
|
allocation_id: allocation_id
|
306
306
|
).nat_gateway
|
@@ -312,7 +312,7 @@ module MU
|
|
312
312
|
MU.log "Waiting for nat gateway #{nat_gateway_id} () to become available (EIP allocation: #{allocation_id})" if attempts % 5 == 0
|
313
313
|
sleep 30
|
314
314
|
begin
|
315
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_nat_gateways(nat_gateway_ids: [nat_gateway_id]).nat_gateways.first
|
315
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_nat_gateways(nat_gateway_ids: [nat_gateway_id]).nat_gateways.first
|
316
316
|
rescue Aws::EmptyStructure, NoMethodError
|
317
317
|
sleep 5
|
318
318
|
retry
|
@@ -332,7 +332,7 @@ module MU
|
|
332
332
|
if subnet.has_key?("map_public_ips")
|
333
333
|
retries = 0
|
334
334
|
begin
|
335
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).modify_subnet_attribute(
|
335
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).modify_subnet_attribute(
|
336
336
|
subnet_id: subnet_id,
|
337
337
|
map_public_ip_on_launch: {
|
338
338
|
value: subnet['map_public_ips'],
|
@@ -353,7 +353,7 @@ module MU
|
|
353
353
|
loggroup = @deploy.findLitterMate(name: @config['name']+"loggroup", type: "logs")
|
354
354
|
logrole = @deploy.findLitterMate(name: @config['name']+"logrole", type: "roles")
|
355
355
|
MU.log "Enabling traffic logging on Subnet #{subnet_name} in VPC #{@mu_name} to log group #{loggroup.mu_name}"
|
356
|
-
MU::Cloud::AWS.ec2(@config['region']).create_flow_logs(
|
356
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_flow_logs(
|
357
357
|
resource_ids: [subnet_id],
|
358
358
|
resource_type: "Subnet",
|
359
359
|
traffic_type: subnet["traffic_type_to_log"],
|
@@ -387,7 +387,7 @@ module MU
|
|
387
387
|
|
388
388
|
MU.log "Creating route for #{route['destination_network']} through NAT gatway #{gateway['id']}", details: route_config
|
389
389
|
begin
|
390
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_route(route_config)
|
390
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(route_config)
|
391
391
|
rescue Aws::EC2::Errors::RouteAlreadyExists => e
|
392
392
|
MU.log "Attempt to create duplicate route to #{route['destination_network']} for #{gateway['id']} in #{rtb['route_table_id']}", MU::WARN
|
393
393
|
end
|
@@ -402,14 +402,14 @@ module MU
|
|
402
402
|
|
403
403
|
if @config['enable_dns_support']
|
404
404
|
MU.log "Enabling DNS support in #{@mu_name}"
|
405
|
-
MU::Cloud::AWS.ec2(@config['region']).modify_vpc_attribute(
|
405
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).modify_vpc_attribute(
|
406
406
|
vpc_id: vpc_id,
|
407
407
|
enable_dns_support: {value: @config['enable_dns_support']}
|
408
408
|
)
|
409
409
|
end
|
410
410
|
if @config['enable_dns_hostnames']
|
411
411
|
MU.log "Enabling DNS hostnames in #{@mu_name}"
|
412
|
-
MU::Cloud::AWS.ec2(@config['region']).modify_vpc_attribute(
|
412
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).modify_vpc_attribute(
|
413
413
|
vpc_id: vpc_id,
|
414
414
|
enable_dns_hostnames: {value: @config['enable_dns_hostnames']}
|
415
415
|
)
|
@@ -435,33 +435,33 @@ module MU
|
|
435
435
|
dhcpopts << {key: "netbios-name-servers", values: @config['dhcp']['netbios_servers']}
|
436
436
|
end
|
437
437
|
|
438
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_dhcp_options(
|
438
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_dhcp_options(
|
439
439
|
dhcp_configurations: dhcpopts
|
440
440
|
)
|
441
441
|
dhcpopt_id = resp.dhcp_options.dhcp_options_id
|
442
|
-
MU::MommaCat.createStandardTags(dhcpopt_id, region: @config['region'])
|
443
|
-
MU::MommaCat.createTag(dhcpopt_id, "Name", @mu_name, region: @config['region'])
|
442
|
+
MU::MommaCat.createStandardTags(dhcpopt_id, region: @config['region'], credentials: @config['credentials'])
|
443
|
+
MU::MommaCat.createTag(dhcpopt_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
|
444
444
|
|
445
445
|
if @config['tags']
|
446
446
|
@config['tags'].each { |tag|
|
447
|
-
MU::MommaCat.createTag(dhcpopt_id, tag['key'], tag['value'], region: @config['region'])
|
447
|
+
MU::MommaCat.createTag(dhcpopt_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
|
448
448
|
}
|
449
449
|
end
|
450
450
|
|
451
451
|
if @config['optional_tags']
|
452
452
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
453
|
-
MU::MommaCat.createTag(dhcpopt_id, key, value, region: @config['region'])
|
453
|
+
MU::MommaCat.createTag(dhcpopt_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
454
454
|
}
|
455
455
|
end
|
456
456
|
|
457
|
-
MU::Cloud::AWS.ec2(@config['region']).associate_dhcp_options(dhcp_options_id: dhcpopt_id, vpc_id: vpc_id)
|
457
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).associate_dhcp_options(dhcp_options_id: dhcpopt_id, vpc_id: vpc_id)
|
458
458
|
end
|
459
459
|
notify
|
460
460
|
|
461
461
|
if !MU::Cloud::AWS.isGovCloud?(@config['region'])
|
462
|
-
mu_zone = MU::Cloud::DNSZone.find(cloud_id: "platform-mu").values.first
|
462
|
+
mu_zone = MU::Cloud::DNSZone.find(cloud_id: "platform-mu", credentials: @config['credentials']).values.first
|
463
463
|
if !mu_zone.nil?
|
464
|
-
MU::Cloud::AWS::DNSZone.toggleVPCAccess(id: mu_zone.id, vpc_id: vpc_id, region: @config['region'])
|
464
|
+
MU::Cloud::AWS::DNSZone.toggleVPCAccess(id: mu_zone.id, vpc_id: vpc_id, region: @config['region'], credentials: @config['credentials'])
|
465
465
|
end
|
466
466
|
end
|
467
467
|
loadSubnets
|
@@ -472,7 +472,7 @@ module MU
|
|
472
472
|
# Canonical Amazon Resource Number for this resource
|
473
473
|
# @return [String]
|
474
474
|
def arn
|
475
|
-
"arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":ec2:"+@config['region']+":"+MU.
|
475
|
+
"arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":ec2:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":vpc/"+@cloud_id
|
476
476
|
end
|
477
477
|
|
478
478
|
# Describe this VPC
|
@@ -489,73 +489,99 @@ module MU
|
|
489
489
|
if !@config['peers'].nil? and @config['peers'].size > 0
|
490
490
|
@config['peers'].each { |peer|
|
491
491
|
peer_obj = nil
|
492
|
+
peer_id = nil
|
493
|
+
|
492
494
|
begin
|
493
|
-
|
495
|
+
# If we know this to be a sibling VPC elsewhere in our stack,
|
496
|
+
# go fetch it, and fix it if we've been misconfigured with a
|
497
|
+
# duplicate peering connection
|
498
|
+
if peer['vpc']['vpc_name'] and !peer['account']
|
499
|
+
peer_obj = @deploy.findLitterMate(name: peer['vpc']['vpc_name'], type: "vpcs")
|
500
|
+
if peer_obj
|
501
|
+
if peer_obj.config['peers']
|
502
|
+
skipme = false
|
503
|
+
peer_obj.config['peers'].each { |peerpeer|
|
504
|
+
if peerpeer['vpc']['vpc_name'] == @config['name'] and
|
505
|
+
(peer['vpc']['vpc_name'] <=> @config['name']) == -1
|
506
|
+
skipme = true
|
507
|
+
MU.log "VPCs #{peer['vpc']['vpc_name']} and #{@config['name']} both declare mutual peering connection, ignoring #{@config['name']}'s redundant declaration", MU::DEBUG
|
508
|
+
# XXX and if deploy_id matches or is unset
|
509
|
+
end
|
510
|
+
}
|
511
|
+
end
|
512
|
+
next if skipme
|
513
|
+
peer['account'] = MU::Cloud::AWS.credToAcct(peer_obj.credentials)
|
514
|
+
peer['vpc']['vpc_id'] = peer_obj.cloud_id
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
# If we still don't know our peer's vpc identifier, go fishing
|
519
|
+
if !peer_obj
|
494
520
|
tag_key, tag_value = peer['vpc']['tag'].split(/=/, 2) if !peer['vpc']['tag'].nil?
|
495
521
|
if peer['vpc']['deploy_id'].nil? and peer['vpc']['vpc_id'].nil? and tag_key.nil?
|
496
522
|
peer['vpc']['deploy_id'] = @deploy.deploy_id
|
497
523
|
end
|
498
524
|
peer_obj = MU::MommaCat.findStray(
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
525
|
+
"AWS",
|
526
|
+
"vpcs",
|
527
|
+
deploy_id: peer['vpc']['deploy_id'],
|
528
|
+
cloud_id: peer['vpc']['vpc_id'],
|
529
|
+
# XXX we need a credentials argument here... maybe
|
530
|
+
name: peer['vpc']['vpc_name'],
|
531
|
+
tag_key: tag_key,
|
532
|
+
tag_value: tag_value,
|
533
|
+
dummy_ok: true,
|
534
|
+
region: peer['vpc']['region']
|
508
535
|
)
|
509
536
|
raise MuError, "No result looking for #{@mu_name}'s peer VPCs (#{peer['vpc']})" if peer_obj.nil? or peer_obj.first.nil?
|
510
537
|
peer_obj = peer_obj.first
|
511
|
-
|
512
|
-
|
513
|
-
MU.log "Setting peering connection from VPC #{@config['name']} (#{@cloud_id}) to #{peer_id}"
|
514
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_vpc_peering_connection(
|
515
|
-
vpc_id: @cloud_id,
|
516
|
-
peer_vpc_id: peer_id
|
517
|
-
)
|
518
|
-
else
|
519
|
-
peer_id = peer['vpc']['vpc_id']
|
520
|
-
MU.log "Setting peering connection from VPC #{@config['name']} (#{@cloud_id}) to #{peer_id} in account #{peer['account']}", MU::INFO, details: peer
|
521
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_vpc_peering_connection(
|
522
|
-
vpc_id: @cloud_id,
|
523
|
-
peer_vpc_id: peer_id,
|
524
|
-
peer_owner_id: peer['account']
|
525
|
-
)
|
538
|
+
peer['account'] ||= MU::Cloud::AWS.credToAcct(peer_obj.credentials)
|
539
|
+
peer['vpc']['vpc_id'] ||= peer_obj.cloud_id
|
526
540
|
end
|
541
|
+
|
542
|
+
peer_id = peer['vpc']['vpc_id']
|
543
|
+
peer['account'] ||= MU::Cloud::AWS.account_number
|
544
|
+
|
545
|
+
MU.log "Setting peering connection from VPC #{@config['name']} (#{@cloud_id} in account #{MU::Cloud::AWS.credToAcct(@config['credentials'])}) to #{peer_id} in account #{peer['account']}", MU::INFO, details: peer
|
546
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_vpc_peering_connection(
|
547
|
+
vpc_id: @cloud_id,
|
548
|
+
peer_vpc_id: peer_id,
|
549
|
+
peer_owner_id: peer['account']
|
550
|
+
)
|
551
|
+
|
527
552
|
rescue Aws::EC2::Errors::VpcPeeringConnectionAlreadyExists => e
|
528
553
|
MU.log "Attempt to create duplicate peering connection to #{peer_id} from VPC #{@config['name']}", MU::WARN
|
529
554
|
end
|
530
|
-
peering_name = @deploy.getResourceName(@config['name']+"-PEER-"+
|
555
|
+
peering_name = @deploy.getResourceName(@config['name']+"-PEER-"+peer['vpc']['vpc_id'])
|
531
556
|
|
532
557
|
peering_id = resp.vpc_peering_connection.vpc_peering_connection_id
|
533
|
-
MU::MommaCat.createStandardTags(peering_id, region: @config['region'])
|
534
|
-
MU::MommaCat.createTag(peering_id, "Name", peering_name, region: @config['region'])
|
558
|
+
MU::MommaCat.createStandardTags(peering_id, region: @config['region'], credentials: @config['credentials'])
|
559
|
+
MU::MommaCat.createTag(peering_id, "Name", peering_name, region: @config['region'], credentials: @config['credentials'])
|
535
560
|
|
536
561
|
if @config['optional_tags']
|
537
562
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
538
|
-
MU::MommaCat.createTag(peering_id, key, value, region: @config['region'])
|
563
|
+
MU::MommaCat.createTag(peering_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
539
564
|
}
|
540
565
|
end
|
541
566
|
|
542
567
|
if @config['tags']
|
543
568
|
@config['tags'].each { |tag|
|
544
|
-
MU::MommaCat.createTag(peering_id, tag['key'], tag['value'], region: @config['region'])
|
569
|
+
MU::MommaCat.createTag(peering_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
|
545
570
|
}
|
546
571
|
end
|
547
572
|
|
548
573
|
# Create routes to our new friend.
|
549
|
-
MU::Cloud::AWS::VPC.listAllSubnetRouteTables(@cloud_id, region: @config['region']).each { |rtb_id|
|
574
|
+
MU::Cloud::AWS::VPC.listAllSubnetRouteTables(@cloud_id, region: @config['region'], credentials: @config['credentials']).each { |rtb_id|
|
550
575
|
my_route_config = {
|
551
576
|
:route_table_id => rtb_id,
|
552
577
|
:destination_cidr_block => peer_obj.cloud_desc.cidr_block,
|
553
578
|
:vpc_peering_connection_id => peering_id
|
554
579
|
}
|
555
580
|
begin
|
556
|
-
|
581
|
+
MU.log "Creating peering route to #{peer_obj.cloud_desc.cidr_block} from VPC #{@config['name']}"
|
582
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(my_route_config)
|
557
583
|
rescue Aws::EC2::Errors::RouteAlreadyExists => e
|
558
|
-
rtbdesc = MU::Cloud::AWS.ec2(@config['region']).describe_route_tables(
|
584
|
+
rtbdesc = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
559
585
|
route_table_ids: [rtb_id]
|
560
586
|
).route_tables.first
|
561
587
|
rtbdesc.routes.each { |r|
|
@@ -569,35 +595,51 @@ module MU
|
|
569
595
|
end
|
570
596
|
}
|
571
597
|
end
|
572
|
-
}
|
598
|
+
} # MU::Cloud::AWS::VPC.listAllSubnetRouteTables
|
573
599
|
|
574
600
|
begin
|
575
|
-
cnxn = MU::Cloud::AWS.ec2(@config['region']).describe_vpc_peering_connections(
|
576
|
-
|
601
|
+
cnxn = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_vpc_peering_connections(
|
602
|
+
vpc_peering_connection_ids: [peering_id]
|
577
603
|
).vpc_peering_connections.first
|
578
604
|
|
579
605
|
if cnxn.status.code == "pending-acceptance"
|
580
606
|
if ((!peer_obj.nil? and !peer_obj.deploydata.nil? and peer_obj.deploydata['auto_accept_peers']) or $MU_CFG['allow_invade_foreign_vpcs'])
|
581
607
|
MU.log "Auto-accepting peering connection from VPC #{@config['name']} (#{@cloud_id}) to #{peer_id}", MU::NOTICE
|
582
608
|
begin
|
583
|
-
MU::Cloud::AWS.ec2(@config['region']).accept_vpc_peering_connection(
|
584
|
-
|
609
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: peer['account']).accept_vpc_peering_connection(
|
610
|
+
vpc_peering_connection_id: peering_id
|
585
611
|
)
|
612
|
+
if peer['account'] != MU::Cloud::AWS.credToAcct(@config['credentials'])
|
613
|
+
# this seems to take a while across accounts
|
614
|
+
sleep 5
|
615
|
+
end
|
616
|
+
cnxn = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_vpc_peering_connections(
|
617
|
+
vpc_peering_connection_ids: [peering_id]
|
618
|
+
).vpc_peering_connections.first
|
586
619
|
rescue Aws::EC2::Errors::VpcPeeringConnectionAlreadyExists => e
|
587
620
|
MU.log "Attempt to create duplicate peering connection to #{peer_id} from VPC #{@config['name']}", MU::WARN
|
588
621
|
end
|
589
622
|
|
590
623
|
# Create routes back from our new friend to us.
|
591
|
-
MU::Cloud::AWS::VPC.listAllSubnetRouteTables(peer_id, region: peer['vpc']['region']).each { |rtb_id|
|
624
|
+
MU::Cloud::AWS::VPC.listAllSubnetRouteTables(peer_id, region: peer['vpc']['region'], credentials: peer['account']).uniq.each { |rtb_id|
|
592
625
|
peer_route_config = {
|
593
|
-
|
594
|
-
|
595
|
-
|
626
|
+
:route_table_id => rtb_id,
|
627
|
+
:destination_cidr_block => @config['ip_block'],
|
628
|
+
:vpc_peering_connection_id => peering_id
|
596
629
|
}
|
597
630
|
begin
|
598
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_route(peer_route_config)
|
631
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: peer['account']).create_route(peer_route_config)
|
599
632
|
rescue Aws::EC2::Errors::RouteAlreadyExists => e
|
600
|
-
MU.
|
633
|
+
rtbdesc = MU::Cloud::AWS.ec2(region: @config['region'], credentials: peer['account']).describe_route_tables(
|
634
|
+
route_table_ids: [rtb_id]
|
635
|
+
).route_tables.first
|
636
|
+
rtbdesc.routes.each { |r|
|
637
|
+
if r.destination_cidr_block == @config['ip_block']
|
638
|
+
if r.vpc_peering_connection_id != peering_id
|
639
|
+
MU.log "Attempt to create duplicate route to VPC #{@config['name']} (#{@config['ip_block']}) from peer VPC #{peer_id}'s route table #{rtb_id}", MU::ERR
|
640
|
+
end
|
641
|
+
end
|
642
|
+
}
|
601
643
|
end
|
602
644
|
}
|
603
645
|
else
|
@@ -608,15 +650,16 @@ module MU
|
|
608
650
|
if cnxn.status.code == "failed" or cnxn.status.code == "rejected" or cnxn.status.code == "expired" or cnxn.status.code == "deleted"
|
609
651
|
MU.log "VPC peering connection from VPC #{@config['name']} (#{@cloud_id}) to #{peer_id} #{cnxn.status.code}: #{cnxn.status.message}", MU::ERR
|
610
652
|
begin
|
611
|
-
MU::Cloud::AWS.ec2(@config['region']).delete_vpc_peering_connection(
|
612
|
-
|
653
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).delete_vpc_peering_connection(
|
654
|
+
vpc_peering_connection_id: peering_id
|
613
655
|
)
|
614
656
|
rescue Aws::EC2::Errors::InvalidStateTransition => e
|
615
657
|
# XXX apparently this is normal?
|
616
658
|
end
|
617
659
|
raise MuError, "VPC peering connection from VPC #{@config['name']} (#{@cloud_id}) to #{peer_id} #{cnxn.status.code}: #{cnxn.status.message}"
|
618
660
|
end
|
619
|
-
|
661
|
+
|
662
|
+
end while cnxn.status.code != "active" and !((peer_obj.nil? or peer_obj.deploydata.nil? or !peer_obj.deploydata['auto_accept_peers']) and cnxn.status.code == "pending-acceptance")
|
620
663
|
|
621
664
|
}
|
622
665
|
end
|
@@ -644,7 +687,7 @@ module MU
|
|
644
687
|
route_config[:instance_id] = nat_instance.cloud_id
|
645
688
|
|
646
689
|
MU.log "Creating route for #{route['destination_network']} through NAT host #{nat_instance.cloud_id}", details: route_config
|
647
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).create_route(route_config)
|
690
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(route_config)
|
648
691
|
end
|
649
692
|
}
|
650
693
|
|
@@ -659,7 +702,7 @@ module MU
|
|
659
702
|
# @param tag_key [String]: A tag key to search.
|
660
703
|
# @param tag_value [String]: The value of the tag specified by tag_key to match when searching by tag.
|
661
704
|
# @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching VPCs
|
662
|
-
def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, flags: {})
|
705
|
+
def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, credentials: nil, flags: {})
|
663
706
|
|
664
707
|
retries = 0
|
665
708
|
map = {}
|
@@ -668,7 +711,7 @@ module MU
|
|
668
711
|
|
669
712
|
if tag_value
|
670
713
|
MU.log "Searching for VPC by tag:#{tag_key}=#{tag_value}", MU::DEBUG
|
671
|
-
resp = MU::Cloud::AWS.ec2(region).describe_vpcs(
|
714
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs(
|
672
715
|
filters: [
|
673
716
|
{name: "tag:#{tag_key}", values: [tag_value]}
|
674
717
|
]
|
@@ -686,7 +729,7 @@ module MU
|
|
686
729
|
if !cloud_id.nil?
|
687
730
|
MU.log "Searching for VPC id '#{cloud_id}' in #{region}", MU::DEBUG
|
688
731
|
begin
|
689
|
-
resp = MU::Cloud::AWS.ec2(region).describe_vpcs(vpc_ids: [cloud_id.to_s])
|
732
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs(vpc_ids: [cloud_id.to_s])
|
690
733
|
resp.vpcs.each { |vpc|
|
691
734
|
map[vpc.vpc_id] = vpc
|
692
735
|
}
|
@@ -720,7 +763,7 @@ module MU
|
|
720
763
|
# @return [Array<Hash>]: A list of cloud provider identifiers of subnets associated with this VPC.
|
721
764
|
def loadSubnets
|
722
765
|
if @cloud_id
|
723
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_subnets(
|
766
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(
|
724
767
|
filters: [
|
725
768
|
{ name: "vpc-id", values: [@cloud_id] }
|
726
769
|
]
|
@@ -741,6 +784,7 @@ module MU
|
|
741
784
|
@config['subnets'].each { |subnet|
|
742
785
|
subnet['mu_name'] = @mu_name+"-"+subnet['name'] if !subnet.has_key?("mu_name")
|
743
786
|
subnet['region'] = @config['region']
|
787
|
+
subnet['credentials'] = @config['credentials']
|
744
788
|
if !resp.nil? and !resp.data.nil? and !resp.data.subnets.nil?
|
745
789
|
resp.data.subnets.each { |desc|
|
746
790
|
if desc.cidr_block == subnet["ip_block"]
|
@@ -776,6 +820,7 @@ module MU
|
|
776
820
|
subnet["tags"] = MU.structToHash(desc.tags)
|
777
821
|
subnet["cloud_id"] = desc.subnet_id
|
778
822
|
subnet['region'] = @config['region']
|
823
|
+
subnet['credentials'] = @config['credentials']
|
779
824
|
if !ext_ids.include?(desc.subnet_id)
|
780
825
|
@subnets << MU::Cloud::AWS::VPC::Subnet.new(self, subnet)
|
781
826
|
end
|
@@ -790,16 +835,16 @@ module MU
|
|
790
835
|
# @param nat_filter_key [String]: A cloud provider filter to help identify the resource, used in conjunction with nat_filter_value.
|
791
836
|
# @param nat_filter_value [String]: A cloud provider filter to help identify the resource, used in conjunction with nat_filter_key.
|
792
837
|
# @param region [String]: The cloud provider region of the target instance.
|
793
|
-
def findNat(nat_cloud_id: nil, nat_filter_key: nil, nat_filter_value: nil, region: MU.curRegion)
|
838
|
+
def findNat(nat_cloud_id: nil, nat_filter_key: nil, nat_filter_value: nil, region: MU.curRegion, credentials: nil)
|
794
839
|
# Discard the nat_cloud_id if it's an AWS instance ID
|
795
840
|
nat_cloud_id = nil if nat_cloud_id && nat_cloud_id.start_with?("i-")
|
796
841
|
|
797
842
|
if @gateways.nil?
|
798
843
|
@gateways =
|
799
844
|
if nat_cloud_id
|
800
|
-
MU::Cloud::AWS.ec2(region).describe_nat_gateways(nat_gateway_ids: [nat_cloud_id])
|
845
|
+
MU::Cloud::AWS.ec2(region: region, credentials: nil).describe_nat_gateways(nat_gateway_ids: [nat_cloud_id])
|
801
846
|
elsif nat_filter_key && nat_filter_value
|
802
|
-
MU::Cloud::AWS.ec2(region).describe_nat_gateways(
|
847
|
+
MU::Cloud::AWS.ec2(region: region, credentials: nil).describe_nat_gateways(
|
803
848
|
filter: [
|
804
849
|
{
|
805
850
|
name: nat_filter_key,
|
@@ -893,13 +938,13 @@ module MU
|
|
893
938
|
# @param instance [String]: A cloud descriptor for the instance, to save us an API call if we already have it
|
894
939
|
# @param region [String]: The cloud provider region of the target instance
|
895
940
|
# @return [Array<String>]
|
896
|
-
def self.getInstanceSubnets(instance_id: nil, instance: nil, region: MU.curRegion)
|
941
|
+
def self.getInstanceSubnets(instance_id: nil, instance: nil, region: MU.curRegion, credentials: nil)
|
897
942
|
return [] if instance_id.nil? and instance.nil?
|
898
943
|
my_subnets = []
|
899
944
|
|
900
945
|
if instance.nil?
|
901
946
|
begin
|
902
|
-
instance = MU::Cloud::AWS.ec2(region).describe_instances(instance_ids: [instance_id]).reservations.first.instances.first
|
947
|
+
instance = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_instances(instance_ids: [instance_id]).reservations.first.instances.first
|
903
948
|
rescue NoMethodError, Aws::EC2::Errors::InvalidInstanceIDNotFound => e
|
904
949
|
MU.log "Failed to identify instance #{instance_id} in MU::Cloud::AWS::VPC.getInstanceSubnets", MU::WARN
|
905
950
|
return []
|
@@ -923,7 +968,7 @@ module MU
|
|
923
968
|
# @param target_instance [OpenStruct]: The cloud descriptor of the instance to check.
|
924
969
|
# @param region [String]: The cloud provider region of the target subnet.
|
925
970
|
# @return [Boolean]
|
926
|
-
def self.haveRouteToInstance?(target_instance, region: MU.curRegion)
|
971
|
+
def self.haveRouteToInstance?(target_instance, region: MU.curRegion, credentials: nil)
|
927
972
|
return false if target_instance.nil?
|
928
973
|
return false if MU.myCloud != "AWS"
|
929
974
|
instance_id = target_instance.instance_id
|
@@ -941,21 +986,20 @@ module MU
|
|
941
986
|
|
942
987
|
return @route_cache[instance_id] if @route_cache.has_key?(instance_id) && @route_cache[instance_id]
|
943
988
|
my_subnets = MU::Cloud::AWS::VPC.getInstanceSubnets(instance: MU.myCloudDescriptor)
|
944
|
-
target_subnets = MU::Cloud::AWS::VPC.getInstanceSubnets(instance: target_instance, region: region)
|
945
|
-
# XXX make sure accounts for being in different regions
|
989
|
+
target_subnets = MU::Cloud::AWS::VPC.getInstanceSubnets(instance: target_instance, region: region, credentials: credentials)
|
946
990
|
|
947
991
|
resp = nil
|
948
992
|
my_subnets_key = my_subnets.join(",")
|
949
993
|
target_subnets_key = target_subnets.join(",")
|
950
994
|
MU::Cloud::AWS::VPC.update_route_tables_cache(my_subnets_key, region: MU.myRegion)
|
951
|
-
MU::Cloud::AWS::VPC.update_route_tables_cache(target_subnets_key, region: region)
|
995
|
+
MU::Cloud::AWS::VPC.update_route_tables_cache(target_subnets_key, region: region, credentials: credentials)
|
952
996
|
|
953
997
|
if MU::Cloud::AWS::VPC.have_route_peered_vpc?(my_subnets_key, target_subnets_key, instance_id)
|
954
998
|
return true
|
955
999
|
else
|
956
1000
|
# The cache can be out of date at times, check again without it
|
957
1001
|
MU::Cloud::AWS::VPC.update_route_tables_cache(my_subnets_key, use_cache: false, region: MU.myRegion)
|
958
|
-
MU::Cloud::AWS::VPC.update_route_tables_cache(target_subnets_key, use_cache: false, region: region)
|
1002
|
+
MU::Cloud::AWS::VPC.update_route_tables_cache(target_subnets_key, use_cache: false, region: region, credentials: credentials)
|
959
1003
|
|
960
1004
|
return MU::Cloud::AWS::VPC.have_route_peered_vpc?(my_subnets_key, target_subnets_key, instance_id)
|
961
1005
|
end
|
@@ -968,7 +1012,7 @@ module MU
|
|
968
1012
|
# @param subnet_key [String]: The subnet/subnets route tables will be extracted from.
|
969
1013
|
# @param use_cache [Boolean]: If to use the existing cache and add records to cache only if missing, or to also replace exising records in cache.
|
970
1014
|
# @param region [String]: The cloud provider region of the target subnet.
|
971
|
-
def self.update_route_tables_cache(subnet_key, use_cache: true, region: MU.curRegion)
|
1015
|
+
def self.update_route_tables_cache(subnet_key, use_cache: true, region: MU.curRegion, credentials: nil)
|
972
1016
|
@rtb_cache_semaphore.synchronize {
|
973
1017
|
update =
|
974
1018
|
if !use_cache
|
@@ -980,12 +1024,12 @@ module MU
|
|
980
1024
|
end
|
981
1025
|
|
982
1026
|
if update
|
983
|
-
route_tables = MU::Cloud::AWS::VPC.get_route_tables(subnet_ids: subnet_key.split(","), region: region)
|
1027
|
+
route_tables = MU::Cloud::AWS::VPC.get_route_tables(subnet_ids: subnet_key.split(","), region: region, credentials: credentials)
|
984
1028
|
|
985
1029
|
if route_tables.empty? && !subnet_key.empty?
|
986
|
-
vpc_id = MU::Cloud::AWS.ec2(region).describe_subnets(subnet_ids: subnet_key.split(",")).subnets.first.vpc_id
|
1030
|
+
vpc_id = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_subnets(subnet_ids: subnet_key.split(",")).subnets.first.vpc_id
|
987
1031
|
MU.log "No route table associations found for #{subnet_key}, falling back to the default table for #{vpc_id}", MU::NOTICE
|
988
|
-
route_tables = MU::Cloud::AWS::VPC.get_route_tables(vpc_ids: [vpc_id], region: region)
|
1032
|
+
route_tables = MU::Cloud::AWS::VPC.get_route_tables(vpc_ids: [vpc_id], region: region, credentials: credentials)
|
989
1033
|
end
|
990
1034
|
|
991
1035
|
@rtb_cache[subnet_key] = route_tables
|
@@ -1004,16 +1048,19 @@ module MU
|
|
1004
1048
|
|
1005
1049
|
@rtb_cache[source_subnets_key].each { |route_table|
|
1006
1050
|
route_table.routes.each { |route|
|
1007
|
-
if route.destination_cidr_block != "0.0.0.0/0" and
|
1051
|
+
if route.destination_cidr_block != "0.0.0.0/0" and !route.destination_cidr_block.nil?
|
1008
1052
|
my_routes << NetAddr::IPv4Net.parse(route.destination_cidr_block)
|
1009
1053
|
if !route.vpc_peering_connection_id.nil?
|
1054
|
+
if route.state == "blackhole"
|
1055
|
+
MU.log "Ignoring blackhole route to #{route.destination_cidr_block} over #{route.vpc_peering_connection_id}", MU::WARN
|
1056
|
+
end
|
1057
|
+
next if route.state != "active"
|
1010
1058
|
vpc_peer_mapping[route.vpc_peering_connection_id] = route.destination_cidr_block
|
1011
1059
|
end
|
1012
1060
|
end
|
1013
1061
|
}
|
1014
1062
|
}
|
1015
1063
|
my_routes.uniq!
|
1016
|
-
|
1017
1064
|
target_routes = []
|
1018
1065
|
@rtb_cache[target_subnets_key].each { |route_table|
|
1019
1066
|
route_table.routes.each { |route|
|
@@ -1021,6 +1068,7 @@ module MU
|
|
1021
1068
|
cidr = NetAddr::IPv4Net.parse(route.destination_cidr_block)
|
1022
1069
|
shared_ip_space = false
|
1023
1070
|
my_routes.each { |my_cidr|
|
1071
|
+
target_routes << NetAddr::IPv4Net.parse(route.destination_cidr_block)
|
1024
1072
|
if my_cidr.contains(NetAddr::IPv4Net.parse(route.destination_cidr_block).nth(2)) or my_cidr.cmp(cidr)
|
1025
1073
|
shared_ip_space = true
|
1026
1074
|
break
|
@@ -1043,10 +1091,10 @@ module MU
|
|
1043
1091
|
# @param vpc_ids [Array]: The cloud identifier of the VPCs to retrieve route tables for.
|
1044
1092
|
# @param region [String]: The cloud provider region of the target subnet.
|
1045
1093
|
# @return [Array<OpenStruct>]: The cloud provider's complete descriptions of the route tables
|
1046
|
-
def self.get_route_tables(subnet_ids: [], vpc_ids: [], region: MU.curRegion)
|
1094
|
+
def self.get_route_tables(subnet_ids: [], vpc_ids: [], region: MU.curRegion, credentials: nil)
|
1047
1095
|
resp = []
|
1048
1096
|
if !subnet_ids.empty?
|
1049
|
-
resp = MU::Cloud::AWS.ec2(region).describe_route_tables(
|
1097
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_route_tables(
|
1050
1098
|
filters: [
|
1051
1099
|
{
|
1052
1100
|
name: "association.subnet-id",
|
@@ -1055,7 +1103,7 @@ module MU
|
|
1055
1103
|
]
|
1056
1104
|
).route_tables
|
1057
1105
|
elsif !vpc_ids.empty?
|
1058
|
-
resp = MU::Cloud::AWS.ec2(region).describe_route_tables(
|
1106
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_route_tables(
|
1059
1107
|
filters: [
|
1060
1108
|
{
|
1061
1109
|
name: "vpc-id",
|
@@ -1068,21 +1116,28 @@ module MU
|
|
1068
1116
|
]
|
1069
1117
|
).route_tables
|
1070
1118
|
else
|
1071
|
-
resp = MU::Cloud::AWS.ec2(region).describe_route_tables.route_tables
|
1119
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_route_tables.route_tables
|
1072
1120
|
end
|
1073
1121
|
|
1074
1122
|
return resp
|
1075
1123
|
end
|
1076
1124
|
|
1125
|
+
# Does this resource type exist as a global (cloud-wide) artifact, or
|
1126
|
+
# is it localized to a region/zone?
|
1127
|
+
# @return [Boolean]
|
1128
|
+
def self.isGlobal?
|
1129
|
+
false
|
1130
|
+
end
|
1131
|
+
|
1077
1132
|
# Remove all VPC resources associated with the currently loaded deployment.
|
1078
1133
|
# @param noop [Boolean]: If true, will only print what would be done
|
1079
1134
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
1080
1135
|
# @param region [String]: The cloud provider region
|
1081
1136
|
# @return [void]
|
1082
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, flags: {})
|
1137
|
+
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
1083
1138
|
|
1084
1139
|
tagfilters = [
|
1085
|
-
|
1140
|
+
{name: "tag:MU-ID", values: [MU.deploy_id]}
|
1086
1141
|
]
|
1087
1142
|
if !ignoremaster
|
1088
1143
|
tagfilters << {name: "tag:MU-MASTER-IP", values: [MU.mu_public_ip]}
|
@@ -1091,7 +1146,7 @@ module MU
|
|
1091
1146
|
vpcs = []
|
1092
1147
|
retries = 0
|
1093
1148
|
begin
|
1094
|
-
resp = MU::Cloud::AWS.ec2(region).describe_vpcs(filters: tagfilters).vpcs
|
1149
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs(filters: tagfilters).vpcs
|
1095
1150
|
vpcs = resp if !resp.empty?
|
1096
1151
|
rescue Aws::EC2::Errors::InvalidVpcIDNotFound => e
|
1097
1152
|
if retries < 5
|
@@ -1106,8 +1161,8 @@ module MU
|
|
1106
1161
|
vpcs.each { |vpc|
|
1107
1162
|
# NAT gateways don't have any tags, and we can't assign them a name. Lets find them based on a VPC ID
|
1108
1163
|
gwthreads << Thread.new {
|
1109
|
-
purge_nat_gateways(noop, vpc_id: vpc.vpc_id, region: region)
|
1110
|
-
purge_endpoints(noop, vpc_id: vpc.vpc_id, region: region)
|
1164
|
+
purge_nat_gateways(noop, vpc_id: vpc.vpc_id, region: region, credentials: credentials)
|
1165
|
+
purge_endpoints(noop, vpc_id: vpc.vpc_id, region: region, credentials: credentials)
|
1111
1166
|
}
|
1112
1167
|
}
|
1113
1168
|
gwthreads.each { |t|
|
@@ -1115,12 +1170,12 @@ module MU
|
|
1115
1170
|
}
|
1116
1171
|
end
|
1117
1172
|
|
1118
|
-
purge_gateways(noop, tagfilters, region: region)
|
1119
|
-
purge_routetables(noop, tagfilters, region: region)
|
1120
|
-
purge_interfaces(noop, tagfilters, region: region)
|
1121
|
-
purge_subnets(noop, tagfilters, region: region)
|
1122
|
-
purge_vpcs(noop, tagfilters, region: region)
|
1123
|
-
purge_dhcpopts(noop, tagfilters, region: region)
|
1173
|
+
purge_gateways(noop, tagfilters, region: region, credentials: credentials)
|
1174
|
+
purge_routetables(noop, tagfilters, region: region, credentials: credentials)
|
1175
|
+
purge_interfaces(noop, tagfilters, region: region, credentials: credentials)
|
1176
|
+
purge_subnets(noop, tagfilters, region: region, credentials: credentials)
|
1177
|
+
purge_vpcs(noop, tagfilters, region: region, credentials: credentials)
|
1178
|
+
purge_dhcpopts(noop, tagfilters, region: region, credentials: credentials)
|
1124
1179
|
|
1125
1180
|
unless noop
|
1126
1181
|
MU::Cloud::AWS.iam.list_roles.roles.each{ |role|
|
@@ -1339,7 +1394,7 @@ module MU
|
|
1339
1394
|
|
1340
1395
|
if (!vpc['subnets'] or vpc['subnets'].empty?) and vpc['create_standard_subnets']
|
1341
1396
|
if vpc['availability_zones'].nil? or vpc['availability_zones'].empty?
|
1342
|
-
vpc['availability_zones'] = MU::Cloud::AWS.listAZs(vpc['region'])
|
1397
|
+
vpc['availability_zones'] = MU::Cloud::AWS.listAZs(region: vpc['region'])
|
1343
1398
|
else
|
1344
1399
|
# turn into a hash so we can use list parameters easily
|
1345
1400
|
vpc['availability_zones'] = vpc['availability_zones'].map { |val| val['zone'] }
|
@@ -1390,8 +1445,8 @@ module MU
|
|
1390
1445
|
|
1391
1446
|
|
1392
1447
|
# List the route tables for each subnet in the given VPC
|
1393
|
-
def self.listAllSubnetRouteTables(vpc_id, region: MU.curRegion)
|
1394
|
-
resp = MU::Cloud::AWS.ec2(region).describe_subnets(
|
1448
|
+
def self.listAllSubnetRouteTables(vpc_id, region: MU.curRegion, credentials: nil)
|
1449
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_subnets(
|
1395
1450
|
filters: [
|
1396
1451
|
{
|
1397
1452
|
name: "vpc-id",
|
@@ -1402,7 +1457,7 @@ module MU
|
|
1402
1457
|
|
1403
1458
|
subnets = resp.subnets.map { |subnet| subnet.subnet_id }
|
1404
1459
|
|
1405
|
-
tables = MU::Cloud::AWS.ec2(region).describe_route_tables(
|
1460
|
+
tables = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_route_tables(
|
1406
1461
|
filters: [
|
1407
1462
|
{
|
1408
1463
|
name: "vpc-id",
|
@@ -1417,7 +1472,7 @@ module MU
|
|
1417
1472
|
|
1418
1473
|
if tables.nil? or tables.route_tables.size == 0
|
1419
1474
|
MU.log "No route table associations found for #{subnets}, falling back to the default table for #{vpc_id}", MU::NOTICE
|
1420
|
-
tables = MU::Cloud::AWS.ec2(MU.myRegion).describe_route_tables(
|
1475
|
+
tables = MU::Cloud::AWS.ec2(region: MU.myRegion).describe_route_tables(
|
1421
1476
|
filters: [
|
1422
1477
|
{name: "vpc-id", values: [vpc_id]},
|
1423
1478
|
{name: "association.main", values: ["true"]},
|
@@ -1440,24 +1495,24 @@ module MU
|
|
1440
1495
|
vpc_id = @cloud_id
|
1441
1496
|
vpc_name = @config['name']
|
1442
1497
|
MU.setVar("curRegion", @config['region']) if !@config['region'].nil?
|
1443
|
-
resp = MU::Cloud::AWS.ec2.create_route_table(vpc_id: vpc_id).route_table
|
1498
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route_table(vpc_id: vpc_id).route_table
|
1444
1499
|
route_table_id = rtb['route_table_id'] = resp.route_table_id
|
1445
1500
|
sleep 5
|
1446
|
-
MU::MommaCat.createTag(route_table_id, "Name", vpc_name+"-"+rtb['name'].upcase)
|
1501
|
+
MU::MommaCat.createTag(route_table_id, "Name", vpc_name+"-"+rtb['name'].upcase, credentials: @config['credentials'])
|
1447
1502
|
|
1448
1503
|
if @config['tags']
|
1449
1504
|
@config['tags'].each { |tag|
|
1450
|
-
MU::MommaCat.createTag(route_table_id, tag['key'], tag['value'])
|
1505
|
+
MU::MommaCat.createTag(route_table_id, tag['key'], tag['value'], credentials: @config['credentials'])
|
1451
1506
|
}
|
1452
1507
|
end
|
1453
1508
|
|
1454
1509
|
if @config['optional_tags']
|
1455
1510
|
MU::MommaCat.listOptionalTags.each { |key, value|
|
1456
|
-
MU::MommaCat.createTag(route_table_id, key, value, region: @config['region'])
|
1511
|
+
MU::MommaCat.createTag(route_table_id, key, value, region: @config['region'], credentials: @config['credentials'])
|
1457
1512
|
}
|
1458
1513
|
end
|
1459
1514
|
|
1460
|
-
MU::MommaCat.createStandardTags(route_table_id)
|
1515
|
+
MU::MommaCat.createStandardTags(route_table_id, credentials: @config['credentials'])
|
1461
1516
|
rtb['routes'].each { |route|
|
1462
1517
|
if route['nat_host_id'].nil? and route['nat_host_name'].nil?
|
1463
1518
|
route_config = {
|
@@ -1473,7 +1528,7 @@ module MU
|
|
1473
1528
|
unless route['gateway'] == '#NAT'
|
1474
1529
|
# Need to change the order of how things are created to create the route here
|
1475
1530
|
MU.log "Creating route for #{route['destination_network']}", details: route_config
|
1476
|
-
resp = MU::Cloud::AWS.ec2.create_route(route_config)
|
1531
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(route_config)
|
1477
1532
|
end
|
1478
1533
|
end
|
1479
1534
|
}
|
@@ -1485,8 +1540,8 @@ module MU
|
|
1485
1540
|
# @param noop [Boolean]: If true, will only print what would be done
|
1486
1541
|
# @param region [String]: The cloud provider region
|
1487
1542
|
# @return [void]
|
1488
|
-
def self.purge_gateways(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
|
1489
|
-
resp = MU::Cloud::AWS.ec2(region).describe_internet_gateways(
|
1543
|
+
def self.purge_gateways(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
1544
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_internet_gateways(
|
1490
1545
|
filters: tagfilters
|
1491
1546
|
)
|
1492
1547
|
gateways = resp.data.internet_gateways
|
@@ -1495,7 +1550,7 @@ module MU
|
|
1495
1550
|
gateway.attachments.each { |attachment|
|
1496
1551
|
MU.log "Detaching Internet Gateway #{gateway.internet_gateway_id} from #{attachment.vpc_id}"
|
1497
1552
|
begin
|
1498
|
-
MU::Cloud::AWS.ec2(region).detach_internet_gateway(
|
1553
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).detach_internet_gateway(
|
1499
1554
|
internet_gateway_id: gateway.internet_gateway_id,
|
1500
1555
|
vpc_id: attachment.vpc_id
|
1501
1556
|
) if !noop
|
@@ -1505,7 +1560,7 @@ module MU
|
|
1505
1560
|
}
|
1506
1561
|
MU.log "Deleting Internet Gateway #{gateway.internet_gateway_id}"
|
1507
1562
|
begin
|
1508
|
-
MU::Cloud::AWS.ec2(region).delete_internet_gateway(internet_gateway_id: gateway.internet_gateway_id) if !noop
|
1563
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_internet_gateway(internet_gateway_id: gateway.internet_gateway_id) if !noop
|
1509
1564
|
rescue Aws::EC2::Errors::InvalidInternetGatewayIDNotFound
|
1510
1565
|
MU.log "Gateway #{gateway.internet_gateway_id} was already destroyed by the time I got to it", MU::WARN
|
1511
1566
|
end
|
@@ -1518,8 +1573,8 @@ module MU
|
|
1518
1573
|
# @param vpc_id [String]: The cloud provider's unique VPC identifier
|
1519
1574
|
# @param region [String]: The cloud provider region
|
1520
1575
|
# @return [void]
|
1521
|
-
def self.purge_nat_gateways(noop = false, vpc_id: nil, region: MU.curRegion)
|
1522
|
-
gateways = MU::Cloud::AWS.ec2(region).describe_nat_gateways(
|
1576
|
+
def self.purge_nat_gateways(noop = false, vpc_id: nil, region: MU.curRegion, credentials: nil)
|
1577
|
+
gateways = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_nat_gateways(
|
1523
1578
|
filter: [
|
1524
1579
|
{
|
1525
1580
|
name: "vpc-id",
|
@@ -1537,15 +1592,15 @@ module MU
|
|
1537
1592
|
MU.log "Deleting NAT Gateway #{gateway.nat_gateway_id}"
|
1538
1593
|
if !noop
|
1539
1594
|
begin
|
1540
|
-
MU::Cloud::AWS.ec2(region).delete_nat_gateway(nat_gateway_id: gateway.nat_gateway_id)
|
1541
|
-
resp = MU::Cloud::AWS.ec2(region).describe_nat_gateways(nat_gateway_ids: [gateway.nat_gateway_id]).nat_gateways.first
|
1595
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_nat_gateway(nat_gateway_id: gateway.nat_gateway_id)
|
1596
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_nat_gateways(nat_gateway_ids: [gateway.nat_gateway_id]).nat_gateways.first
|
1542
1597
|
|
1543
1598
|
attempts = 0
|
1544
1599
|
while resp.state != "deleted" and resp.state != "failed"
|
1545
1600
|
MU.log "Waiting for nat gateway #{gateway.nat_gateway_id} to delete" if attempts % 2 == 0
|
1546
1601
|
sleep 30
|
1547
1602
|
begin
|
1548
|
-
resp = MU::Cloud::AWS.ec2(region).describe_nat_gateways(nat_gateway_ids: [gateway.nat_gateway_id]).nat_gateways.first
|
1603
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_nat_gateways(nat_gateway_ids: [gateway.nat_gateway_id]).nat_gateways.first
|
1549
1604
|
rescue Aws::EmptyStructure, NoMethodError
|
1550
1605
|
sleep 5
|
1551
1606
|
retry
|
@@ -1575,8 +1630,8 @@ module MU
|
|
1575
1630
|
# @param vpc_id [String]: The cloud provider's unique VPC identifier
|
1576
1631
|
# @param region [String]: The cloud provider region
|
1577
1632
|
# @return [void]
|
1578
|
-
def self.purge_endpoints(noop = false, vpc_id: nil, region: MU.curRegion)
|
1579
|
-
vpc_endpoints = MU::Cloud::AWS.ec2(region).describe_vpc_endpoints(
|
1633
|
+
def self.purge_endpoints(noop = false, vpc_id: nil, region: MU.curRegion, credentials: nil)
|
1634
|
+
vpc_endpoints = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_endpoints(
|
1580
1635
|
filters: [
|
1581
1636
|
{
|
1582
1637
|
name:"vpc-id",
|
@@ -1594,15 +1649,15 @@ module MU
|
|
1594
1649
|
MU.log "Deleting VPC endpoint #{endpoint.vpc_endpoint_id}"
|
1595
1650
|
if !noop
|
1596
1651
|
begin
|
1597
|
-
MU::Cloud::AWS.ec2(region).delete_vpc_endpoints(vpc_endpoint_ids: [endpoint.vpc_endpoint_id])
|
1598
|
-
resp = MU::Cloud::AWS.ec2(region).describe_vpc_endpoints(vpc_endpoint_ids: [endpoint.vpc_endpoint_id]).vpc_endpoints.first
|
1652
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc_endpoints(vpc_endpoint_ids: [endpoint.vpc_endpoint_id])
|
1653
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_endpoints(vpc_endpoint_ids: [endpoint.vpc_endpoint_id]).vpc_endpoints.first
|
1599
1654
|
|
1600
1655
|
attempts = 0
|
1601
1656
|
while resp.state != "deleted"
|
1602
1657
|
MU.log "Waiting for VPC endpoint #{endpoint.vpc_endpoint_id} to delete" if attempts % 5 == 0
|
1603
1658
|
sleep 30
|
1604
1659
|
begin
|
1605
|
-
resp = MU::Cloud::AWS.ec2(region).describe_vpc_endpoints(vpc_endpoint_ids: [endpoint.vpc_endpoint_id]).vpc_endpoints.first
|
1660
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_endpoints(vpc_endpoint_ids: [endpoint.vpc_endpoint_id]).vpc_endpoints.first
|
1606
1661
|
rescue Aws::EmptyStructure, NoMethodError
|
1607
1662
|
sleep 5
|
1608
1663
|
retry
|
@@ -1634,8 +1689,8 @@ module MU
|
|
1634
1689
|
# @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
|
1635
1690
|
# @param region [String]: The cloud provider region
|
1636
1691
|
# @return [void]
|
1637
|
-
def self.purge_routetables(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
|
1638
|
-
resp = MU::Cloud::AWS.ec2(region).describe_route_tables(
|
1692
|
+
def self.purge_routetables(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
1693
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_route_tables(
|
1639
1694
|
filters: tagfilters
|
1640
1695
|
)
|
1641
1696
|
route_tables = resp.data.route_tables
|
@@ -1647,7 +1702,7 @@ module MU
|
|
1647
1702
|
if !route.network_interface_id.nil?
|
1648
1703
|
MU.log "Deleting Network Interface #{route.network_interface_id}"
|
1649
1704
|
begin
|
1650
|
-
MU::Cloud::AWS.ec2(region).delete_network_interface(network_interface_id: route.network_interface_id) if !noop
|
1705
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: route.network_interface_id) if !noop
|
1651
1706
|
rescue Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound => e
|
1652
1707
|
MU.log "Network Interface #{route.network_interface_id} has already been deleted", MU::WARN
|
1653
1708
|
end
|
@@ -1655,7 +1710,7 @@ module MU
|
|
1655
1710
|
if route.gateway_id != "local"
|
1656
1711
|
MU.log "Deleting #{table.route_table_id}'s route for #{route.destination_cidr_block}"
|
1657
1712
|
begin
|
1658
|
-
MU::Cloud::AWS.ec2(region).delete_route(
|
1713
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_route(
|
1659
1714
|
route_table_id: table.route_table_id,
|
1660
1715
|
destination_cidr_block: route.destination_cidr_block
|
1661
1716
|
) if !noop
|
@@ -1667,7 +1722,7 @@ module MU
|
|
1667
1722
|
can_delete = true
|
1668
1723
|
table.associations.each { |assoc|
|
1669
1724
|
begin
|
1670
|
-
MU::Cloud::AWS.ec2(region).disassociate_route_table(association_id: assoc.route_table_association_id) if !noop
|
1725
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).disassociate_route_table(association_id: assoc.route_table_association_id) if !noop
|
1671
1726
|
rescue Aws::EC2::Errors::InvalidAssociationIDNotFound => e
|
1672
1727
|
MU.log "Route table association #{assoc.route_table_association_id} already removed", MU::WARN
|
1673
1728
|
rescue Aws::EC2::Errors::InvalidParameterValue => e
|
@@ -1679,7 +1734,7 @@ module MU
|
|
1679
1734
|
next if !can_delete
|
1680
1735
|
MU.log "Deleting Route Table #{table.route_table_id}"
|
1681
1736
|
begin
|
1682
|
-
MU::Cloud::AWS.ec2(region).delete_route_table(route_table_id: table.route_table_id) if !noop
|
1737
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_route_table(route_table_id: table.route_table_id) if !noop
|
1683
1738
|
rescue Aws::EC2::Errors::InvalidRouteTableIDNotFound
|
1684
1739
|
MU.log "Route table #{table.route_table_id} already removed", MU::WARN
|
1685
1740
|
end
|
@@ -1693,8 +1748,8 @@ module MU
|
|
1693
1748
|
# @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
|
1694
1749
|
# @param region [String]: The cloud provider region
|
1695
1750
|
# @return [void]
|
1696
|
-
def self.purge_interfaces(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
|
1697
|
-
resp = MU::Cloud::AWS.ec2(region).describe_network_interfaces(
|
1751
|
+
def self.purge_interfaces(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
1752
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_network_interfaces(
|
1698
1753
|
filters: tagfilters
|
1699
1754
|
)
|
1700
1755
|
ifaces = resp.data.network_interfaces
|
@@ -1703,7 +1758,7 @@ module MU
|
|
1703
1758
|
|
1704
1759
|
ifaces.each { |iface|
|
1705
1760
|
MU.log "Deleting Network Interface #{iface.network_interface_id}"
|
1706
|
-
MU::Cloud::AWS.ec2(region).delete_network_interface(network_interface_id: iface.network_interface_id)
|
1761
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: iface.network_interface_id)
|
1707
1762
|
}
|
1708
1763
|
end
|
1709
1764
|
|
@@ -1712,8 +1767,8 @@ module MU
|
|
1712
1767
|
# @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
|
1713
1768
|
# @param region [String]: The cloud provider region
|
1714
1769
|
# @return [void]
|
1715
|
-
def self.purge_subnets(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
|
1716
|
-
resp = MU::Cloud::AWS.ec2(region).describe_subnets(
|
1770
|
+
def self.purge_subnets(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
1771
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_subnets(
|
1717
1772
|
filters: tagfilters
|
1718
1773
|
)
|
1719
1774
|
subnets = resp.data.subnets
|
@@ -1728,7 +1783,7 @@ module MU
|
|
1728
1783
|
sleep 30
|
1729
1784
|
else
|
1730
1785
|
MU.log "Deleting Subnet #{subnet.subnet_id}"
|
1731
|
-
MU::Cloud::AWS.ec2(region).delete_subnet(subnet_id: subnet.subnet_id) if !noop
|
1786
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_subnet(subnet_id: subnet.subnet_id) if !noop
|
1732
1787
|
end
|
1733
1788
|
rescue Aws::EC2::Errors::DependencyViolation => e
|
1734
1789
|
if retries < 7
|
@@ -1752,8 +1807,8 @@ module MU
|
|
1752
1807
|
# @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
|
1753
1808
|
# @param region [String]: The cloud provider region
|
1754
1809
|
# @return [void]
|
1755
|
-
def self.purge_dhcpopts(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
|
1756
|
-
resp = MU::Cloud::AWS.ec2(region).describe_dhcp_options(
|
1810
|
+
def self.purge_dhcpopts(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
1811
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_dhcp_options(
|
1757
1812
|
filters: tagfilters
|
1758
1813
|
)
|
1759
1814
|
sets = resp.data.dhcp_options
|
@@ -1763,7 +1818,7 @@ module MU
|
|
1763
1818
|
sets.each { |optset|
|
1764
1819
|
begin
|
1765
1820
|
MU.log "Deleting DHCP Option Set #{optset.dhcp_options_id}"
|
1766
|
-
MU::Cloud::AWS.ec2(region).delete_dhcp_options(dhcp_options_id: optset.dhcp_options_id)
|
1821
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_dhcp_options(dhcp_options_id: optset.dhcp_options_id)
|
1767
1822
|
rescue Aws::EC2::Errors::DependencyViolation => e
|
1768
1823
|
MU.log e.inspect, MU::ERR
|
1769
1824
|
# rescue Aws::EC2::Errors::InvalidSubnetIDNotFound
|
@@ -1778,8 +1833,8 @@ module MU
|
|
1778
1833
|
# @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
|
1779
1834
|
# @param region [String]: The cloud provider region
|
1780
1835
|
# @return [void]
|
1781
|
-
def self.purge_vpcs(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
|
1782
|
-
resp = MU::Cloud::AWS.ec2(region).describe_vpcs(
|
1836
|
+
def self.purge_vpcs(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
1837
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpcs(
|
1783
1838
|
filters: tagfilters
|
1784
1839
|
)
|
1785
1840
|
|
@@ -1787,7 +1842,7 @@ module MU
|
|
1787
1842
|
return if vpcs.nil? or vpcs.size == 0
|
1788
1843
|
|
1789
1844
|
vpcs.each { |vpc|
|
1790
|
-
my_peer_conns = MU::Cloud::AWS.ec2(region).describe_vpc_peering_connections(
|
1845
|
+
my_peer_conns = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_peering_connections(
|
1791
1846
|
filters: [
|
1792
1847
|
{
|
1793
1848
|
name: "requester-vpc-info.vpc-id",
|
@@ -1795,7 +1850,7 @@ module MU
|
|
1795
1850
|
}
|
1796
1851
|
]
|
1797
1852
|
).vpc_peering_connections
|
1798
|
-
my_peer_conns.concat(MU::Cloud::AWS.ec2(region).describe_vpc_peering_connections(
|
1853
|
+
my_peer_conns.concat(MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_peering_connections(
|
1799
1854
|
filters: [
|
1800
1855
|
{
|
1801
1856
|
name: "accepter-vpc-info.vpc-id",
|
@@ -1806,15 +1861,19 @@ module MU
|
|
1806
1861
|
my_peer_conns.each { |cnxn|
|
1807
1862
|
|
1808
1863
|
[cnxn.accepter_vpc_info.vpc_id, cnxn.requester_vpc_info.vpc_id].each { |peer_vpc|
|
1809
|
-
MU::Cloud::AWS::VPC.listAllSubnetRouteTables(peer_vpc, region: region).each { |rtb_id|
|
1810
|
-
|
1864
|
+
MU::Cloud::AWS::VPC.listAllSubnetRouteTables(peer_vpc, region: region, credentials: credentials).each { |rtb_id|
|
1865
|
+
begin
|
1866
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_route_tables(
|
1811
1867
|
route_table_ids: [rtb_id]
|
1812
|
-
|
1868
|
+
)
|
1869
|
+
rescue Aws::EC2::Errors::InvalidRouteTableIDNotFound => e
|
1870
|
+
next
|
1871
|
+
end
|
1813
1872
|
resp.route_tables.each { |rtb|
|
1814
1873
|
rtb.routes.each { |route|
|
1815
1874
|
if route.vpc_peering_connection_id == cnxn.vpc_peering_connection_id
|
1816
1875
|
MU.log "Removing route #{route.destination_cidr_block} from route table #{rtb_id} in VPC #{peer_vpc}"
|
1817
|
-
MU::Cloud::AWS.ec2(region).delete_route(
|
1876
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_route(
|
1818
1877
|
route_table_id: rtb_id,
|
1819
1878
|
destination_cidr_block: route.destination_cidr_block
|
1820
1879
|
) if !noop
|
@@ -1825,18 +1884,20 @@ module MU
|
|
1825
1884
|
}
|
1826
1885
|
MU.log "Deleting VPC peering connection #{cnxn.vpc_peering_connection_id}"
|
1827
1886
|
begin
|
1828
|
-
MU::Cloud::AWS.ec2(region).delete_vpc_peering_connection(
|
1887
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc_peering_connection(
|
1829
1888
|
vpc_peering_connection_id: cnxn.vpc_peering_connection_id
|
1830
1889
|
) if !noop
|
1831
1890
|
rescue Aws::EC2::Errors::InvalidStateTransition => e
|
1832
1891
|
MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} not in removable (state #{cnxn.status.code})", MU::WARN
|
1892
|
+
rescue Aws::EC2::Errors::OperationNotPermitted => e
|
1893
|
+
MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} refuses to delete: #{e.message}", MU::WARN
|
1833
1894
|
end
|
1834
1895
|
}
|
1835
1896
|
|
1836
1897
|
MU.log "Deleting VPC #{vpc.vpc_id}"
|
1837
1898
|
retries = 0
|
1838
1899
|
begin
|
1839
|
-
MU::Cloud::AWS.ec2(region).delete_vpc(vpc_id: vpc.vpc_id) if !noop
|
1900
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc(vpc_id: vpc.vpc_id) if !noop
|
1840
1901
|
rescue Aws::EC2::Errors::InvalidVpcIDNotFound
|
1841
1902
|
MU.log "VPC #{vpc.vpc_id} has already been deleted", MU::WARN
|
1842
1903
|
rescue Aws::EC2::Errors::DependencyViolation => e
|
@@ -1851,9 +1912,9 @@ module MU
|
|
1851
1912
|
end
|
1852
1913
|
|
1853
1914
|
if !MU::Cloud::AWS.isGovCloud?(region)
|
1854
|
-
mu_zone = MU::Cloud::DNSZone.find(cloud_id: "platform-mu", region: region).values.first
|
1915
|
+
mu_zone = MU::Cloud::DNSZone.find(cloud_id: "platform-mu", region: region, credentials: credentials).values.first
|
1855
1916
|
if !mu_zone.nil?
|
1856
|
-
MU::Cloud::AWS::DNSZone.toggleVPCAccess(id: mu_zone.id, vpc_id: vpc.vpc_id, remove: true)
|
1917
|
+
MU::Cloud::AWS::DNSZone.toggleVPCAccess(id: mu_zone.id, vpc_id: vpc.vpc_id, remove: true, credentials: credentials)
|
1857
1918
|
end
|
1858
1919
|
end
|
1859
1920
|
}
|
@@ -1882,20 +1943,20 @@ module MU
|
|
1882
1943
|
@mu_name = config['mu_name']
|
1883
1944
|
@name = config['name']
|
1884
1945
|
@deploydata = config # This is a dummy for the sake of describe()
|
1885
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_subnets(subnet_ids: [@cloud_id]).subnets.first
|
1946
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(subnet_ids: [@cloud_id]).subnets.first
|
1886
1947
|
@az = resp.availability_zone
|
1887
1948
|
@ip_block = resp.cidr_block
|
1888
|
-
@cloud_desc = resp
|
1949
|
+
@cloud_desc = resp # XXX this really isn't the cloud implementation's business
|
1889
1950
|
|
1890
1951
|
end
|
1891
1952
|
|
1892
1953
|
# Return the cloud identifier for the default route of this subnet.
|
1893
1954
|
def defaultRoute
|
1894
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_route_tables(
|
1955
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
1895
1956
|
filters: [{name: "association.subnet-id", values: [@cloud_id]}]
|
1896
1957
|
)
|
1897
1958
|
if resp.route_tables.size == 0 # use default route table for the VPC
|
1898
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_route_tables(
|
1959
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
1899
1960
|
filters: [{name: "vpc-id", values: [@parent.cloud_id]}]
|
1900
1961
|
)
|
1901
1962
|
end
|
@@ -1916,11 +1977,11 @@ module MU
|
|
1916
1977
|
# @return [Boolean]
|
1917
1978
|
def private?
|
1918
1979
|
return false if @cloud_id.nil?
|
1919
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_route_tables(
|
1980
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
1920
1981
|
filters: [{name: "association.subnet-id", values: [@cloud_id]}]
|
1921
1982
|
)
|
1922
1983
|
if resp.route_tables.size == 0 # use default route table for the VPC
|
1923
|
-
resp = MU::Cloud::AWS.ec2(@config['region']).describe_route_tables(
|
1984
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
1924
1985
|
filters: [{name: "vpc-id", values: [@parent.cloud_id]}]
|
1925
1986
|
)
|
1926
1987
|
end
|