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.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/Berksfile +16 -54
  3. data/Berksfile.lock +14 -62
  4. data/bin/mu-aws-setup +131 -108
  5. data/bin/mu-configure +311 -74
  6. data/bin/mu-gcp-setup +84 -62
  7. data/bin/mu-load-config.rb +46 -2
  8. data/bin/mu-self-update +11 -9
  9. data/bin/mu-upload-chef-artifacts +4 -4
  10. data/{mu.gemspec → cloud-mu.gemspec} +2 -2
  11. data/cookbooks/awscli/Berksfile +8 -0
  12. data/cookbooks/mu-activedirectory/Berksfile +11 -0
  13. data/cookbooks/mu-firewall/Berksfile +9 -0
  14. data/cookbooks/mu-firewall/metadata.rb +1 -1
  15. data/cookbooks/mu-glusterfs/Berksfile +10 -0
  16. data/cookbooks/mu-jenkins/Berksfile +14 -0
  17. data/cookbooks/mu-master/Berksfile +23 -0
  18. data/cookbooks/mu-master/attributes/default.rb +1 -1
  19. data/cookbooks/mu-master/metadata.rb +2 -2
  20. data/cookbooks/mu-master/recipes/default.rb +1 -1
  21. data/cookbooks/mu-master/recipes/init.rb +7 -3
  22. data/cookbooks/mu-master/recipes/ssl-certs.rb +1 -0
  23. data/cookbooks/mu-mongo/Berksfile +10 -0
  24. data/cookbooks/mu-openvpn/Berksfile +11 -0
  25. data/cookbooks/mu-php54/Berksfile +13 -0
  26. data/cookbooks/mu-splunk/Berksfile +10 -0
  27. data/cookbooks/mu-tools/Berksfile +21 -0
  28. data/cookbooks/mu-tools/files/default/Mu_CA.pem +15 -15
  29. data/cookbooks/mu-utility/Berksfile +9 -0
  30. data/cookbooks/mu-utility/metadata.rb +2 -1
  31. data/cookbooks/nagios/Berksfile +7 -4
  32. data/cookbooks/s3fs/Berksfile +9 -0
  33. data/environments/dev.json +6 -6
  34. data/environments/prod.json +6 -6
  35. data/modules/mu.rb +20 -42
  36. data/modules/mu/cleanup.rb +102 -100
  37. data/modules/mu/cloud.rb +90 -28
  38. data/modules/mu/clouds/aws.rb +449 -218
  39. data/modules/mu/clouds/aws/alarm.rb +29 -17
  40. data/modules/mu/clouds/aws/cache_cluster.rb +78 -64
  41. data/modules/mu/clouds/aws/collection.rb +25 -18
  42. data/modules/mu/clouds/aws/container_cluster.rb +73 -66
  43. data/modules/mu/clouds/aws/database.rb +124 -116
  44. data/modules/mu/clouds/aws/dnszone.rb +27 -20
  45. data/modules/mu/clouds/aws/firewall_rule.rb +30 -22
  46. data/modules/mu/clouds/aws/folder.rb +18 -3
  47. data/modules/mu/clouds/aws/function.rb +77 -23
  48. data/modules/mu/clouds/aws/group.rb +19 -12
  49. data/modules/mu/clouds/aws/habitat.rb +153 -0
  50. data/modules/mu/clouds/aws/loadbalancer.rb +59 -52
  51. data/modules/mu/clouds/aws/log.rb +30 -23
  52. data/modules/mu/clouds/aws/msg_queue.rb +29 -20
  53. data/modules/mu/clouds/aws/notifier.rb +222 -0
  54. data/modules/mu/clouds/aws/role.rb +178 -90
  55. data/modules/mu/clouds/aws/search_domain.rb +40 -24
  56. data/modules/mu/clouds/aws/server.rb +169 -137
  57. data/modules/mu/clouds/aws/server_pool.rb +60 -83
  58. data/modules/mu/clouds/aws/storage_pool.rb +59 -31
  59. data/modules/mu/clouds/aws/user.rb +36 -27
  60. data/modules/mu/clouds/aws/userdata/linux.erb +101 -93
  61. data/modules/mu/clouds/aws/vpc.rb +250 -189
  62. data/modules/mu/clouds/azure.rb +132 -0
  63. data/modules/mu/clouds/cloudformation.rb +65 -1
  64. data/modules/mu/clouds/cloudformation/alarm.rb +8 -0
  65. data/modules/mu/clouds/cloudformation/cache_cluster.rb +7 -0
  66. data/modules/mu/clouds/cloudformation/collection.rb +7 -0
  67. data/modules/mu/clouds/cloudformation/database.rb +7 -0
  68. data/modules/mu/clouds/cloudformation/dnszone.rb +7 -0
  69. data/modules/mu/clouds/cloudformation/firewall_rule.rb +9 -2
  70. data/modules/mu/clouds/cloudformation/loadbalancer.rb +7 -0
  71. data/modules/mu/clouds/cloudformation/log.rb +7 -0
  72. data/modules/mu/clouds/cloudformation/server.rb +7 -0
  73. data/modules/mu/clouds/cloudformation/server_pool.rb +7 -0
  74. data/modules/mu/clouds/cloudformation/vpc.rb +7 -0
  75. data/modules/mu/clouds/google.rb +214 -110
  76. data/modules/mu/clouds/google/container_cluster.rb +42 -24
  77. data/modules/mu/clouds/google/database.rb +15 -6
  78. data/modules/mu/clouds/google/firewall_rule.rb +17 -25
  79. data/modules/mu/clouds/google/group.rb +13 -5
  80. data/modules/mu/clouds/google/habitat.rb +105 -0
  81. data/modules/mu/clouds/google/loadbalancer.rb +28 -20
  82. data/modules/mu/clouds/google/server.rb +93 -354
  83. data/modules/mu/clouds/google/server_pool.rb +18 -10
  84. data/modules/mu/clouds/google/user.rb +22 -14
  85. data/modules/mu/clouds/google/vpc.rb +97 -69
  86. data/modules/mu/config.rb +133 -38
  87. data/modules/mu/config/alarm.rb +25 -0
  88. data/modules/mu/config/cache_cluster.rb +5 -3
  89. data/modules/mu/config/cache_cluster.yml +23 -0
  90. data/modules/mu/config/database.rb +25 -16
  91. data/modules/mu/config/database.yml +3 -3
  92. data/modules/mu/config/function.rb +1 -2
  93. data/modules/mu/config/{project.rb → habitat.rb} +10 -10
  94. data/modules/mu/config/notifier.rb +85 -0
  95. data/modules/mu/config/notifier.yml +9 -0
  96. data/modules/mu/config/role.rb +1 -1
  97. data/modules/mu/config/search_domain.yml +2 -2
  98. data/modules/mu/config/server.rb +13 -1
  99. data/modules/mu/config/server.yml +3 -3
  100. data/modules/mu/config/server_pool.rb +3 -1
  101. data/modules/mu/config/storage_pool.rb +3 -1
  102. data/modules/mu/config/storage_pool.yml +19 -0
  103. data/modules/mu/config/vpc.rb +70 -8
  104. data/modules/mu/groomers/chef.rb +2 -3
  105. data/modules/mu/kittens.rb +500 -122
  106. data/modules/mu/master.rb +5 -5
  107. data/modules/mu/mommacat.rb +151 -91
  108. data/modules/tests/super_complex_bok.yml +12 -0
  109. data/modules/tests/super_simple_bok.yml +12 -0
  110. data/spec/mu/clouds/azure_spec.rb +82 -0
  111. data/spec/spec_helper.rb +105 -0
  112. metadata +26 -5
  113. data/modules/mu/clouds/aws/notification.rb +0 -139
  114. data/modules/mu/config/notification.rb +0 -44
@@ -51,7 +51,7 @@ module MU
51
51
 
52
52
  zones_to_try = @config["zones"]
53
53
  begin
54
- asg = MU::Cloud::AWS.autoscale(@config['region']).create_auto_scaling_group(asg_options)
54
+ asg = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_auto_scaling_group(asg_options)
55
55
  rescue Aws::AutoScaling::Errors::ValidationError => e
56
56
  if zones_to_try != nil and zones_to_try.size > 0
57
57
  MU.log "#{e.message}, retrying with individual AZs", MU::WARN
@@ -66,7 +66,7 @@ module MU
66
66
  if zones_to_try != nil and zones_to_try.size < @config["zones"].size
67
67
  zones_to_try.each { |zone|
68
68
  begin
69
- MU::Cloud::AWS.autoscale(@config['region']).update_auto_scaling_group(
69
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
70
70
  auto_scaling_group_name: @mu_name,
71
71
  availability_zones: [zone]
72
72
  )
@@ -84,11 +84,11 @@ module MU
84
84
  attempts = 0
85
85
  begin
86
86
  sleep 5
87
- desc = MU::Cloud::AWS.autoscale(@config['region']).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
87
+ desc = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
88
88
  MU.log "Looking for #{desc.min_size} instances in #{@mu_name}, found #{desc.instances.size}", MU::DEBUG
89
89
  attempts = attempts + 1
90
90
  if attempts > 25 and desc.instances.size == 0
91
- MU.log "No instances spun up after #{5*attempts} seconds, something's wrong with Autoscale group #{@mu_name}", MU::ERR, details: MU::Cloud::AWS.autoscale(@config['region']).describe_scaling_activities(auto_scaling_group_name: @mu_name).activities
91
+ MU.log "No instances spun up after #{5*attempts} seconds, something's wrong with Autoscale group #{@mu_name}", MU::ERR, details: MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_scaling_activities(auto_scaling_group_name: @mu_name).activities
92
92
  raise MuError, "No instances spun up after #{5*attempts} seconds, something's wrong with Autoscale group #{@mu_name}"
93
93
  end
94
94
  end while desc.instances.size < desc.min_size
@@ -136,7 +136,7 @@ module MU
136
136
  t.join
137
137
  }
138
138
  MU.log "Setting min_size to #{@config['min_size']} and max_size to #{@config['max_size']}"
139
- MU::Cloud::AWS.autoscale(@config['region']).update_auto_scaling_group(
139
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
140
140
  auto_scaling_group_name: @mu_name,
141
141
  min_size: @config['min_size'],
142
142
  max_size: @config['max_size']
@@ -158,7 +158,7 @@ module MU
158
158
  def setScaleInProtection(need_instances = @config['min_size'])
159
159
  live_instances = []
160
160
  begin
161
- desc = MU::Cloud::AWS.autoscale(@config['region']).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
161
+ desc = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(auto_scaling_group_names: [@mu_name]).auto_scaling_groups.first
162
162
 
163
163
  live_instances = desc.instances.map { |i| i.instance_id }
164
164
  already_set = 0
@@ -170,7 +170,7 @@ module MU
170
170
  elsif already_set > need_instances
171
171
  unset_me = live_instances.sample(already_set - need_instances)
172
172
  MU.log "Disabling scale-in protection for #{unset_me.size.to_s} instances in #{@mu_name}", MU::NOTICE, details: unset_me
173
- MU::Cloud::AWS.autoscale(@config['region']).set_instance_protection(
173
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).set_instance_protection(
174
174
  auto_scaling_group_name: @mu_name,
175
175
  instance_ids: unset_me,
176
176
  protected_from_scale_in: false
@@ -179,7 +179,7 @@ module MU
179
179
  live_instances = live_instances.sample(need_instances)
180
180
  MU.log "Enabling scale-in protection for #{@config['scale_in_protection']} instances in #{@mu_name}", details: live_instances
181
181
  begin
182
- MU::Cloud::AWS.autoscale(@config['region']).set_instance_protection(
182
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).set_instance_protection(
183
183
  auto_scaling_group_name: @mu_name,
184
184
  instance_ids: live_instances,
185
185
  protected_from_scale_in: true
@@ -213,7 +213,7 @@ module MU
213
213
  # Called automatically by {MU::Deploy#createResources}
214
214
  def groom
215
215
  if @config['schedule']
216
- ext_actions = MU::Cloud::AWS.autoscale(@config['region']).describe_scheduled_actions(
216
+ ext_actions = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_scheduled_actions(
217
217
  auto_scaling_group_name: @mu_name
218
218
  ).scheduled_update_group_actions
219
219
 
@@ -234,7 +234,7 @@ module MU
234
234
  if s['action_name'] == ext.scheduled_action_name
235
235
  if !MU.hashCmp(MU.structToHash(ext), sched_config, missing_is_default: true)
236
236
  MU.log "Removing scheduled action #{s['action_name']} from AutoScale group #{@mu_name}"
237
- MU::Cloud::AWS.autoscale(@config['region']).delete_scheduled_action(
237
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_scheduled_action(
238
238
  auto_scaling_group_name: @mu_name,
239
239
  scheduled_action_name: s['action_name']
240
240
  )
@@ -246,7 +246,7 @@ module MU
246
246
  }
247
247
  if !action_already_correct
248
248
  MU.log "Adding scheduled action to AutoScale group #{@mu_name}", MU::NOTICE, details: sched_config
249
- MU::Cloud::AWS.autoscale(@config['region']).put_scheduled_update_group_action(
249
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_scheduled_update_group_action(
250
250
  sched_config
251
251
  )
252
252
  end
@@ -274,10 +274,10 @@ module MU
274
274
  if need_tag_update
275
275
  MU.log "Updating ServerPool #{@mu_name} with new tags", MU::NOTICE, details: tag_conf[:tags]
276
276
 
277
- MU::Cloud::AWS.autoscale(@config['region']).create_or_update_tags(tag_conf)
277
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_or_update_tags(tag_conf)
278
278
  current.instances.each { |instance|
279
279
  tag_conf[:tags].each { |t|
280
- MU::MommaCat.createTag(instance.instance_id, t[:key], t[:value], region: @config['region'])
280
+ MU::MommaCat.createTag(instance.instance_id, t[:key], t[:value], region: @config['region'], credentials: @config['credentials'])
281
281
  }
282
282
  }
283
283
  end
@@ -291,7 +291,7 @@ module MU
291
291
  asg_options[:new_instances_protected_from_scale_in] = (@config['scale_in_protection'] == "all")
292
292
  tg_arns = []
293
293
  if asg_options[:target_group_arns]
294
- MU::Cloud::AWS.autoscale(@config['region']).attach_load_balancer_target_groups(
294
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).attach_load_balancer_target_groups(
295
295
  auto_scaling_group_name: @mu_name,
296
296
  target_group_arns: asg_options[:target_group_arns]
297
297
  )
@@ -299,7 +299,7 @@ module MU
299
299
  asg_options.delete(:target_group_arns)
300
300
  end
301
301
 
302
- MU::Cloud::AWS.autoscale(@config['region']).update_auto_scaling_group(asg_options)
302
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(asg_options)
303
303
 
304
304
  if @config['scale_in_protection']
305
305
  if @config['scale_in_protection'] == "all"
@@ -313,7 +313,7 @@ module MU
313
313
  setScaleInProtection(0)
314
314
  end
315
315
 
316
- ext_pols = MU::Cloud::AWS.autoscale(@config['region']).describe_policies(
316
+ ext_pols = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_policies(
317
317
  auto_scaling_group_name: @mu_name
318
318
  ).scaling_policies
319
319
  if @config["scaling_policies"] and @config["scaling_policies"].size > 0
@@ -325,7 +325,7 @@ module MU
325
325
  ext_pols.each { |ext|
326
326
  if !legit_policies.include?(ext.policy_name)
327
327
  MU.log "Scaling policy #{ext.policy_name} is not named in scaling_policies, removing from #{@mu_name}", MU::NOTICE, details: ext
328
- MU::Cloud::AWS.autoscale(@config['region']).delete_policy(
328
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_policy(
329
329
  auto_scaling_group_name: @mu_name,
330
330
  policy_name: ext.policy_name
331
331
  )
@@ -389,7 +389,7 @@ module MU
389
389
  ext_pols.each { |ext|
390
390
  if ext.policy_name == policy_name
391
391
  if !MU.hashCmp(MU.structToHash(ext), policy_params, missing_is_default: true)
392
- MU::Cloud::AWS.autoscale(@config['region']).delete_policy(
392
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_policy(
393
393
  auto_scaling_group_name: @mu_name,
394
394
  policy_name: policy_name
395
395
  )
@@ -401,44 +401,9 @@ module MU
401
401
  }
402
402
  if !policy_already_correct
403
403
  MU.log "Putting scaling policy #{policy_name} for #{@mu_name}", MU::NOTICE, details: policy_params
404
- resp = MU::Cloud::AWS.autoscale(@config['region']).put_scaling_policy(policy_params)
404
+ resp = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_scaling_policy(policy_params)
405
405
  end
406
406
 
407
-
408
- # If we are creating alarms for scaling policies we need to have the autoscaling policy ARN
409
- # To make life easier we're creating the alarms here
410
- if policy.has_key?("alarms") && !policy["alarms"].empty?
411
- policy["alarms"].each { |alarm|
412
- alarm["alarm_actions"] = [] if !alarm.has_key?("alarm_actions")
413
- alarm["ok_actions"] = [] if !alarm.has_key?("ok_actions")
414
- alarm["alarm_actions"] << resp.policy_arn
415
- alarm["dimensions"] = [{name: "AutoScalingGroupName", value: asg_options[:auto_scaling_group_name]}]
416
-
417
- if alarm["enable_notifications"]
418
- topic_arn = MU::Cloud::AWS::Notification.createTopic(alarm["notification_group"], region: @config["region"])
419
- MU::Cloud::AWS::Notification.subscribe(arn: topic_arn, protocol: alarm["notification_type"], endpoint: alarm["notification_endpoint"], region: @config["region"])
420
- alarm["alarm_actions"] << topic_arn
421
- alarm["ok_actions"] << topic_arn
422
- end
423
-
424
- MU::Cloud::AWS::Alarm.setAlarm(
425
- name: "#{MU.deploy_id}-#{alarm["name"]}".upcase,
426
- ok_actions: alarm["ok_actions"],
427
- alarm_actions: alarm["alarm_actions"],
428
- insufficient_data_actions: alarm["no_data_actions"],
429
- metric_name: alarm["metric_name"],
430
- namespace: alarm["namespace"],
431
- statistic: alarm["statistic"],
432
- dimensions: alarm["dimensions"],
433
- period: alarm["period"],
434
- unit: alarm["unit"],
435
- evaluation_periods: alarm["evaluation_periods"],
436
- threshold: alarm["threshold"],
437
- comparison_operator: alarm["comparison_operator"],
438
- region: @config["region"]
439
- )
440
- }
441
- end
442
407
  }
443
408
  end
444
409
 
@@ -447,7 +412,7 @@ module MU
447
412
  # Retrieve the AWS descriptor for this Autoscale group
448
413
  # @return [OpenStruct]
449
414
  def cloud_desc
450
- MU::Cloud::AWS.autoscale(@config['region']).describe_auto_scaling_groups(
415
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(
451
416
  auto_scaling_group_names: [@mu_name]
452
417
  ).auto_scaling_groups.first
453
418
  end
@@ -471,10 +436,10 @@ module MU
471
436
  # @param tag_value [String]: The value of the tag specified by tag_key to match when searching by tag.
472
437
  # @param flags [Hash]: Optional flags
473
438
  # @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching ServerPools
474
- def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, flags: {})
439
+ def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, credentials: nil, flags: {})
475
440
  found = []
476
441
  if cloud_id
477
- resp = MU::Cloud::AWS.autoscale(region).describe_auto_scaling_groups({
442
+ resp = MU::Cloud::AWS.autoscale(region: region, credentials: credentials).describe_auto_scaling_groups({
478
443
  auto_scaling_group_names: [
479
444
  cloud_id
480
445
  ],
@@ -751,7 +716,7 @@ module MU
751
716
  ok = true
752
717
 
753
718
  if pool["termination_policy"]
754
- valid_policies = MU::Cloud::AWS.autoscale(pool['region']).describe_termination_policy_types.termination_policy_types
719
+ valid_policies = MU::Cloud::AWS.autoscale(region: pool['region']).describe_termination_policy_types.termination_policy_types
755
720
  if !valid_policies.include?(pool["termination_policy"])
756
721
  ok = false
757
722
  MU.log "Termination policy #{pool["termination_policy"]} is not valid in region #{pool['region']}", MU::ERR, details: valid_policies
@@ -853,6 +818,7 @@ module MU
853
818
  # XXX maybe break this down into policies and add those?
854
819
  end
855
820
 
821
+ role['credentials'] = pool['credentials'] if pool['credentials']
856
822
  configurator.insertKitten(role, "roles")
857
823
  pool["dependencies"] ||= []
858
824
  pool["dependencies"] << {
@@ -949,7 +915,9 @@ module MU
949
915
  alarm['dimensions'] << { "name" => pool["name"], "cloud_class" => "AutoScalingGroupName" }
950
916
  alarm["namespace"] = "AWS/EC2" if alarm["namespace"].nil?
951
917
  alarm['cloud'] = pool['cloud']
952
- # ok = false if !insertKitten(alarm, "alarms")
918
+ alarm['credentials'] = pool['credentials']
919
+ alarm['region'] = pool['region']
920
+ ok = false if !configurator.insertKitten(alarm, "alarms")
953
921
  }
954
922
  end
955
923
  }
@@ -957,17 +925,24 @@ module MU
957
925
  ok
958
926
  end
959
927
 
928
+ # Does this resource type exist as a global (cloud-wide) artifact, or
929
+ # is it localized to a region/zone?
930
+ # @return [Boolean]
931
+ def self.isGlobal?
932
+ false
933
+ end
934
+
960
935
  # Remove all autoscale groups associated with the currently loaded deployment.
961
936
  # @param noop [Boolean]: If true, will only print what would be done
962
937
  # @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
963
938
  # @param region [String]: The cloud provider region
964
939
  # @return [void]
965
- def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, flags: {})
940
+ def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
966
941
  filters = [{name: "key", values: ["MU-ID"]}]
967
942
  if !ignoremaster
968
943
  filters << {name: "key", values: ["MU-MASTER-IP"]}
969
944
  end
970
- resp = MU::Cloud::AWS.autoscale(region).describe_tags(
945
+ resp = MU::Cloud::AWS.autoscale(credentials: credentials, region: region).describe_tags(
971
946
  filters: filters,
972
947
  max_records: 100
973
948
  )
@@ -995,7 +970,7 @@ module MU
995
970
  next if noop
996
971
  retries = 0
997
972
  begin
998
- MU::Cloud::AWS.autoscale(region).delete_auto_scaling_group(
973
+ MU::Cloud::AWS.autoscale(credentials: credentials, region: region).delete_auto_scaling_group(
999
974
  auto_scaling_group_name: resource_id,
1000
975
  # XXX this should obey @force
1001
976
  force_delete: true
@@ -1017,7 +992,7 @@ module MU
1017
992
  retries = 0
1018
993
  begin
1019
994
  MU.log "Removing AutoScale Launch Configuration #{resource_id}"
1020
- MU::Cloud::AWS.autoscale(region).delete_launch_configuration(
995
+ MU::Cloud::AWS.autoscale(credentials: credentials, region: region).delete_launch_configuration(
1021
996
  launch_configuration_name: resource_id
1022
997
  )
1023
998
  rescue Aws::AutoScaling::Errors::ValidationError => e
@@ -1054,12 +1029,13 @@ module MU
1054
1029
  elsif !@config['basis']['launch_config']["instance_id"].nil?
1055
1030
  @config['basis']['launch_config']["ami_id"] = MU::Cloud::AWS::Server.createImage(
1056
1031
  name: @mu_name,
1057
- instance_id: @config['basis']['launch_config']["instance_id"]
1032
+ instance_id: @config['basis']['launch_config']["instance_id"],
1033
+ credentials: @config['credentials']
1058
1034
  )
1059
1035
  end
1060
- MU::Cloud::AWS::Server.waitForAMI(@config['basis']['launch_config']["ami_id"])
1036
+ MU::Cloud::AWS::Server.waitForAMI(@config['basis']['launch_config']["ami_id"], credentials: @config['credentials'])
1061
1037
 
1062
- oldlaunch = MU::Cloud::AWS.autoscale(@config['region']).describe_launch_configurations(
1038
+ oldlaunch = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_launch_configurations(
1063
1039
  launch_configuration_names: [@mu_name]
1064
1040
  ).launch_configurations.first
1065
1041
 
@@ -1131,7 +1107,7 @@ module MU
1131
1107
  # Put our Autoscale group onto a temporary launch config
1132
1108
  begin
1133
1109
 
1134
- MU::Cloud::AWS.autoscale(@config['region']).create_launch_configuration(
1110
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_launch_configuration(
1135
1111
  launch_configuration_name: @mu_name+"-TMP",
1136
1112
  user_data: Base64.encode64(olduserdata),
1137
1113
  image_id: oldlaunch.image_id,
@@ -1154,12 +1130,12 @@ module MU
1154
1130
  end
1155
1131
 
1156
1132
 
1157
- MU::Cloud::AWS.autoscale(@config['region']).update_auto_scaling_group(
1133
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
1158
1134
  auto_scaling_group_name: @mu_name,
1159
1135
  launch_configuration_name: @mu_name+"-TMP"
1160
1136
  )
1161
1137
  # ...now back to an identical one with the "real" name
1162
- MU::Cloud::AWS.autoscale(@config['region']).delete_launch_configuration(
1138
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_launch_configuration(
1163
1139
  launch_configuration_name: @mu_name
1164
1140
  )
1165
1141
  end
@@ -1197,9 +1173,16 @@ module MU
1197
1173
  }
1198
1174
 
1199
1175
  if @config['basis']['launch_config']['generate_iam_role']
1200
- # Using ARN instead of IAM instance profile name to hopefully get around some random AWS failures
1201
- rolename, cfm_role_name, cfm_prof_name, arn = MU::Cloud::AWS::Server.createIAMProfile(@mu_name, base_profile: @config['basis']['launch_config']['iam_role'], extra_policies: @config['basis']['launch_config']['iam_policies'], canned_policies: @config['basis']['launch_config']['canned_iam_policies'])
1202
- launch_options[:iam_instance_profile] = rolename
1176
+ role = @deploy.findLitterMate(name: @config['name'], type: "roles")
1177
+ # XXX are these the right patterns for a pool, or did we need wildcards?
1178
+ s3_objs = ["#{@deploy.deploy_id}-secret", "#{role.mu_name}.pfx", "#{role.mu_name}.crt", "#{role.mu_name}.key", "#{role.mu_name}-winrm.crt", "#{role.mu_name}-winrm.key"].map { |file|
1179
+ 'arn:'+(MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU.adminBucketName+'/'+file
1180
+ }
1181
+ role.cloudobj.injectPolicyTargets("MuSecrets", s3_objs)
1182
+
1183
+ @config['iam_role'] = role.mu_name
1184
+
1185
+ launch_options[:iam_instance_profile] = role.cloudobj.createInstanceProfile
1203
1186
  elsif @config['basis']['launch_config']['iam_role'].nil?
1204
1187
  raise MuError, "#{@mu_name} has generate_iam_role set to false, but no iam_role assigned."
1205
1188
  else
@@ -1208,18 +1191,12 @@ module MU
1208
1191
 
1209
1192
  @config['iam_role'] = rolename ? rolename : launch_options[:iam_instance_profile]
1210
1193
 
1211
- if rolename
1212
- MU::Cloud::AWS::Server.addStdPoliciesToIAMProfile(rolename, region: @config['region'])
1213
- else
1214
- MU::Cloud::AWS::Server.addStdPoliciesToIAMProfile(@config['iam_role'], region: @config['region'])
1215
- end
1216
-
1217
1194
  lc_attempts = 0
1218
1195
  begin
1219
- MU::Cloud::AWS.autoscale(@config['region']).create_launch_configuration(launch_options)
1196
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_launch_configuration(launch_options)
1220
1197
  rescue Aws::AutoScaling::Errors::ValidationError => e
1221
1198
  if lc_attempts > 3
1222
- MU.log "Got error while creating #{@mu_name} Launch Config: #{e.message}, retrying in 10s", MU::WARN
1199
+ MU.log "Got error while creating #{@mu_name} Launch Config#{@config['credentials'] ? " with credentials #{@config['credentials']}" : ""}: #{e.message}, retrying in 10s", MU::WARN, details: launch_options.reject { |k,v | k == :user_data }
1223
1200
  end
1224
1201
  sleep 5
1225
1202
  lc_attempts += 1
@@ -1228,11 +1205,11 @@ module MU
1228
1205
 
1229
1206
  if !oldlaunch.nil?
1230
1207
  # Tell the ASG to use the new one, and nuke the old one
1231
- MU::Cloud::AWS.autoscale(@config['region']).update_auto_scaling_group(
1208
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).update_auto_scaling_group(
1232
1209
  auto_scaling_group_name: @mu_name,
1233
1210
  launch_configuration_name: @mu_name
1234
1211
  )
1235
- MU::Cloud::AWS.autoscale(@config['region']).delete_launch_configuration(
1212
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).delete_launch_configuration(
1236
1213
  launch_configuration_name: @mu_name+"-TMP"
1237
1214
  )
1238
1215
  MU.log "Launch Configuration #{@mu_name} replaced"
@@ -1375,7 +1352,7 @@ module MU
1375
1352
  # Do the dance of specifying individual zones if we haven't asked to
1376
1353
  # use particular VPC subnets.
1377
1354
  if @config['zones'].nil? and asg_options[:vpc_zone_identifier].nil?
1378
- @config["zones"] = MU::Cloud::AWS.listAZs(@config['region'])
1355
+ @config["zones"] = MU::Cloud::AWS.listAZs(region: @config['region'])
1379
1356
  MU.log "Using zones from #{@config['region']}", MU::DEBUG, details: @config['zones']
1380
1357
  end
1381
1358
  asg_options[:availability_zones] = @config["zones"] if @config["zones"] != nil
@@ -36,7 +36,7 @@ module MU
36
36
  # @return [String]: The cloud provider's identifier for this storage pool.
37
37
  def create
38
38
  MU.log "Creating storage pool #{@mu_name}"
39
- resp = MU::Cloud::AWS.efs(@config['region']).create_file_system(
39
+ resp = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).create_file_system(
40
40
  creation_token: @mu_name,
41
41
  performance_mode: @config['storage_type']
42
42
  )
@@ -44,7 +44,7 @@ module MU
44
44
  attempts = 0
45
45
  loop do
46
46
  MU.log "Waiting for #{@mu_name}: #{resp.file_system_id} to become available" if attempts % 5 == 0
47
- storage_pool = MU::Cloud::AWS.efs(@config['region']).describe_file_systems(
47
+ storage_pool = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_file_systems(
48
48
  creation_token: @mu_name
49
49
  ).file_systems.first
50
50
  break if storage_pool.life_cycle_state == "available"
@@ -54,7 +54,7 @@ module MU
54
54
  raise MuError, "timed out waiting for #{resp.mount_target_id }" if attempts >= 20
55
55
  end
56
56
 
57
- addStandardTags(cloud_id: resp.file_system_id, region: @config['region'])
57
+ addStandardTags(cloud_id: resp.file_system_id, region: @config['region'], credentials: @config['credentials'])
58
58
  @cloud_id = resp.file_system_id
59
59
 
60
60
  if @config['mount_points'] && !@config['mount_points'].empty?
@@ -89,6 +89,7 @@ module MU
89
89
  ip_address: target['ip_address'],
90
90
  subnet_id: target['vpc']['subnet_id'],
91
91
  security_groups: sgs,
92
+ credentials: @config['credentials'],
92
93
  region: @config['region']
93
94
  )
94
95
  target['cloud_id'] = mount_target.mount_target_id
@@ -106,7 +107,7 @@ module MU
106
107
  # Canonical Amazon Resource Number for this resource
107
108
  # @return [String]
108
109
  def arn
109
- "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":elasticfilesystem:"+@config['region']+":"+MU.account_number+":file-system/"+@cloud_id
110
+ "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":elasticfilesystem:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":file-system/"+@cloud_id
110
111
  end
111
112
 
112
113
  # Locate an existing storage pool and return an array containing matching AWS resource descriptors for those that match.
@@ -116,10 +117,10 @@ module MU
116
117
  # @param tag_value [String]: The value of the tag specified by tag_key to match when searching by tag.
117
118
  # @param flags [Hash]: Optional flags
118
119
  # @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching storage pool
119
- def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, flags: {})
120
+ def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, credentials: nil, flags: {})
120
121
  map = {}
121
122
  if cloud_id
122
- storge_pool = MU::Cloud::AWS.efs(region).describe_file_systems(
123
+ storge_pool = MU::Cloud::AWS.efs(region: region, credentials: credentials).describe_file_systems(
123
124
  file_system_id: cloud_id
124
125
  ).file_systems.first
125
126
 
@@ -127,11 +128,11 @@ module MU
127
128
  end
128
129
 
129
130
  if tag_value
130
- storage_pools = MU::Cloud::AWS.efs(region).describe_file_systems.file_systems
131
+ storage_pools = MU::Cloud::AWS.efs(region: region, credentials: credentials).describe_file_systems.file_systems
131
132
 
132
133
  if !storage_pools.empty?
133
134
  storage_pools.each{ |pool|
134
- tags = MU::Cloud::AWS.efs(region).describe_tags(
135
+ tags = MU::Cloud::AWS.efs(region: region, credentials: credentials).describe_tags(
135
136
  file_system_id: pool.file_system_id
136
137
  ).tags
137
138
 
@@ -157,7 +158,7 @@ module MU
157
158
  # Add our standard tag set to an Amazon EFS File System.
158
159
  # @param cloud_id [String]: The cloud provider's identifier for this resource.
159
160
  # @param region [String]: The cloud provider region
160
- def addStandardTags(cloud_id: nil, region: MU.curRegion)
161
+ def addStandardTags(cloud_id: nil, region: MU.curRegion, credentials: nil)
161
162
  if cloud_id
162
163
  tags = []
163
164
  MU::MommaCat.listStandardTags.each_pair { |name, value|
@@ -180,7 +181,7 @@ module MU
180
181
 
181
182
  tags << {key: "Name", value: @mu_name} unless name_tag
182
183
 
183
- MU::Cloud::AWS.efs(region).create_tags(
184
+ MU::Cloud::AWS.efs(region: region, credentials: credentials).create_tags(
184
185
  file_system_id: cloud_id,
185
186
  tags: tags
186
187
  )
@@ -200,10 +201,10 @@ module MU
200
201
  # @param subnet_id [String]: The subnet_id to associate the mount point with
201
202
  # @param security_groups [Array]: A list of security groups to associate with the mount point.
202
203
  # @param region [String]: The cloud provider region
203
- def self.create_mount_target(cloud_id: nil, ip_address: nil, subnet_id: nil, security_groups: [], region: MU.curRegion)
204
+ def self.create_mount_target(cloud_id: nil, ip_address: nil, subnet_id: nil, security_groups: [], region: MU.curRegion, credentials: nil)
204
205
  MU.log "Creating mount target for filesystem #{cloud_id}"
205
206
 
206
- resp = MU::Cloud::AWS.efs(region).create_mount_target(
207
+ resp = MU::Cloud::AWS.efs(region: region, credentials: credentials).create_mount_target(
207
208
  file_system_id: cloud_id,
208
209
  subnet_id: subnet_id,
209
210
  ip_address: ip_address,
@@ -215,12 +216,12 @@ module MU
215
216
  loop do
216
217
  MU.log "Waiting for #{resp.mount_target_id} to become available", MU::NOTICE if attempts % 10 == 0
217
218
  begin
218
- mount_target = MU::Cloud::AWS.efs(region).describe_mount_targets(
219
+ mount_target = MU::Cloud::AWS.efs(region: region, credentials: credentials).describe_mount_targets(
219
220
  mount_target_id: resp.mount_target_id
220
221
  ).mount_targets.first
221
222
  rescue Aws::EFS::Errors::MountTargetNotFound
222
223
  if retries <= 3
223
- sleep 5
224
+ sleep 10
224
225
  retry
225
226
  else
226
227
  return nil
@@ -244,7 +245,7 @@ module MU
244
245
  # @param region [String]: The cloud provider region
245
246
  def self.modify_security_groups(cloud_id: nil, replace: false , security_groups: [], region: MU.curRegion)
246
247
  unless replace
247
- extisting_sgs = MU::Cloud::AWS.efs(region).describe_mount_target_security_groups(
248
+ extisting_sgs = MU::Cloud::AWS.efs(region: region).describe_mount_target_security_groups(
248
249
  mount_target_id: cloud_id
249
250
  ).security_groups
250
251
 
@@ -252,7 +253,7 @@ module MU
252
253
  end
253
254
 
254
255
  security_groups.uniq!
255
- resp = MU::Cloud::AWS.efs(region).modify_mount_target_security_groups(
256
+ resp = MU::Cloud::AWS.efs(region: region).modify_mount_target_security_groups(
256
257
  mount_target_id: cloud_id,
257
258
  security_groups: security_groups
258
259
  )
@@ -261,7 +262,7 @@ module MU
261
262
  # Register a description of this storage pool with this deployment's metadata.
262
263
  def notify
263
264
  deploy_struct = {}
264
- storage_pool = MU::Cloud::AWS.efs(@config['region']).describe_file_systems(
265
+ storage_pool = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_file_systems(
265
266
  creation_token: @mu_name
266
267
  ).file_systems.first
267
268
 
@@ -272,19 +273,33 @@ module MU
272
273
  subnet = nil
273
274
  dependencies
274
275
  mp_vpc = if mp['vpc'] and mp['vpc']['vpc_name']
275
- @deploy.findLitterMate(type: "vpc", name: mp['vpc']['vpc_name'])
276
+ @deploy.findLitterMate(type: "vpc", name: mp['vpc']['vpc_name'], credentials: @config['credentials'])
277
+ elsif mp['vpc']
278
+ MU::MommaCat.findStray(
279
+ @config['cloud'],
280
+ "vpcs",
281
+ deploy_id: mp['vpc']["deploy_id"],
282
+ credentials: @config['credentials'],
283
+ mu_name: mp['vpc']["mu_name"],
284
+ cloud_id: mp['vpc']['vpc_id'],
285
+ region: @config['region'],
286
+ dummy_ok: false
287
+ ).first
276
288
  # XXX non-sibling, findStray version
277
289
  end
278
290
 
279
- mount_targets = MU::Cloud::AWS.efs(@config['region']).describe_mount_targets(
291
+ mount_targets = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_mount_targets(
280
292
  file_system_id: storage_pool.file_system_id
281
293
  ).mount_targets
282
294
 
295
+ # subnet_obj = mp_vpc.subnets.select { |s|
296
+ # s.name == mp["vpc"]["subnet_name"] or s.cloud_id == mp["vpc"]["subnet_id"]
297
+ # }.first
283
298
  mount_target = nil
284
- subnet_cidr_obj = NetAddr::IPv4Net.parse(subnet_obj.ip_block)
285
299
  mp_vpc.subnets.each { |subnet_obj|
286
300
  mount_targets.map { |t|
287
- if subnet_cidr_obj.contains(t.ip_address)
301
+ subnet_cidr_obj = NetAddr::IPv4Net.parse(subnet_obj.ip_block)
302
+ if subnet_cidr_obj.contains(NetAddr::IPv4.parse(t.ip_address))
288
303
  mount_target = t
289
304
  subnet = subnet_obj.cloud_desc
290
305
  end
@@ -292,7 +307,7 @@ module MU
292
307
  break if mount_target
293
308
  }
294
309
 
295
- # mount_target = MU::Cloud::AWS.efs(@config['region']).describe_mount_targets(
310
+ # mount_target = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_mount_targets(
296
311
  # mount_target_id: mp["cloud_id"]
297
312
  # ).mount_targets.first
298
313
 
@@ -303,7 +318,7 @@ module MU
303
318
  "file_system_id" => mount_target.file_system_id,
304
319
  "mount_directory" => mp["directory"],
305
320
  "subnet_id" => mount_target.subnet_id,
306
- "vpc_id" => subnet.vpc_id,
321
+ "vpc_id" => mp_vpc.cloud_id,
307
322
  "availability_zone" => subnet.availability_zone,
308
323
  "state" => mount_target.life_cycle_state,
309
324
  "ip_address" => mount_target.ip_address,
@@ -327,17 +342,24 @@ module MU
327
342
  return deploy_struct
328
343
  end
329
344
 
345
+ # Does this resource type exist as a global (cloud-wide) artifact, or
346
+ # is it localized to a region/zone?
347
+ # @return [Boolean]
348
+ def self.isGlobal?
349
+ false
350
+ end
351
+
330
352
  # Called by {MU::Cleanup}. Locates resources that were created by the
331
353
  # currently-loaded deployment, and purges them.
332
354
  # @param noop [Boolean]: If true, will only print what would be done
333
355
  # @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
334
356
  # @param region [String]: The cloud provider region in which to operate
335
357
  # @return [void]
336
- def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, flags: {})
358
+ def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
337
359
  supported_regions = %w{us-west-2 us-east-1 eu-west-1}
338
360
  if supported_regions.include?(region)
339
361
  begin
340
- resp = MU::Cloud::AWS.efs(region).describe_file_systems
362
+ resp = MU::Cloud::AWS.efs(credentials: credentials, region: region).describe_file_systems
341
363
  return if resp.nil? or resp.file_systems.nil?
342
364
  storage_pools = resp.file_systems
343
365
  rescue Aws::EFS::Errors::AccessDeniedException
@@ -350,7 +372,7 @@ module MU
350
372
 
351
373
  if !storage_pools.empty?
352
374
  storage_pools.each{ |pool|
353
- tags = MU::Cloud::AWS.efs(region).describe_tags(
375
+ tags = MU::Cloud::AWS.efs(credentials: credentials, region: region).describe_tags(
354
376
  file_system_id: pool.file_system_id
355
377
  ).tags
356
378
 
@@ -372,7 +394,7 @@ module MU
372
394
 
373
395
  # How to identify mount points in a reliable way? Mount points are not tagged, which means we can only reliably identify mount points based on a filesystem ID. We can you our deployment metadata, but it isn’t necessarily reliable
374
396
  # begin
375
- # resp = MU::Cloud::AWS.efs(region).delete_mount_target(
397
+ # resp = MU::Cloud::AWS.efs(credentials: credentials, region: region).delete_mount_target(
376
398
  # mount_target_id: "MountTargetId"
377
399
  # )
378
400
  # MU.log "Deleted mount target"
@@ -382,7 +404,7 @@ module MU
382
404
 
383
405
  if !our_pools.empty?
384
406
  our_pools.each{ |pool|
385
- mount_targets = MU::Cloud::AWS.efs(region).describe_mount_targets(
407
+ mount_targets = MU::Cloud::AWS.efs(credentials: credentials, region: region).describe_mount_targets(
386
408
  file_system_id: pool.file_system_id
387
409
  ).mount_targets
388
410
 
@@ -391,7 +413,7 @@ module MU
391
413
  MU.log "Deleting mount target #{mp.mount_target_id} for filesystem #{pool.name}: #{pool.file_system_id}"
392
414
  unless noop
393
415
  begin
394
- resp = MU::Cloud::AWS.efs(region).delete_mount_target(
416
+ resp = MU::Cloud::AWS.efs(credentials: credentials, region: region).delete_mount_target(
395
417
  mount_target_id: mp.mount_target_id
396
418
  )
397
419
  rescue Aws::EFS::Errors::BadRequest => e
@@ -405,7 +427,7 @@ module MU
405
427
  unless noop
406
428
  attempts = 0
407
429
  begin
408
- resp = MU::Cloud::AWS.efs(region).delete_file_system(
430
+ resp = MU::Cloud::AWS.efs(credentials: credentials, region: region).delete_file_system(
409
431
  file_system_id: pool.file_system_id
410
432
  )
411
433
  rescue Aws::EFS::Errors::BadRequest => e
@@ -474,7 +496,13 @@ module MU
474
496
  pool['mount_points'].each{ |mp|
475
497
  if mp['ingress_rules']
476
498
  fwname = "storage-#{mp['name']}"
477
- acl = {"name" => fwname, "rules" => mp['ingress_rules'], "region" => pool['region'], "optional_tags" => pool['optional_tags']}
499
+ acl = {
500
+ "name" => fwname,
501
+ "rules" => mp['ingress_rules'],
502
+ "region" => pool['region'],
503
+ "credentials" => pool['credentials'],
504
+ "optional_tags" => pool['optional_tags']
505
+ }
478
506
  acl["tags"] = pool['tags'] if pool['tags'] && !pool['tags'].empty?
479
507
  acl["vpc"] = mp['vpc'].dup if mp['vpc']
480
508
  ok = false if !configurator.insertKitten(acl, "firewall_rules")