cloud-mu 3.3.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/ansible/roles/mu-nat/tasks/main.yml +3 -0
  3. data/bin/mu-aws-setup +41 -7
  4. data/bin/mu-azure-setup +36 -2
  5. data/bin/mu-configure +214 -119
  6. data/bin/mu-gcp-setup +37 -2
  7. data/bin/mu-node-manage +3 -0
  8. data/bin/mu-refresh-ssl +67 -0
  9. data/bin/mu-run-tests +14 -4
  10. data/bin/mu-self-update +30 -10
  11. data/bin/mu-upload-chef-artifacts +30 -26
  12. data/cloud-mu.gemspec +9 -7
  13. data/cookbooks/mu-master/attributes/default.rb +5 -1
  14. data/cookbooks/mu-master/metadata.rb +2 -2
  15. data/cookbooks/mu-master/recipes/default.rb +81 -26
  16. data/cookbooks/mu-master/recipes/init.rb +197 -62
  17. data/cookbooks/mu-master/recipes/update_nagios_only.rb +1 -1
  18. data/cookbooks/mu-master/recipes/vault.rb +78 -77
  19. data/cookbooks/mu-master/templates/default/mods/rewrite.conf.erb +1 -0
  20. data/cookbooks/mu-master/templates/default/nagios.conf.erb +103 -0
  21. data/cookbooks/mu-master/templates/default/web_app.conf.erb +14 -30
  22. data/cookbooks/mu-tools/attributes/default.rb +12 -0
  23. data/cookbooks/mu-tools/files/centos-6/CentOS-Base.repo +47 -0
  24. data/cookbooks/mu-tools/libraries/helper.rb +98 -4
  25. data/cookbooks/mu-tools/libraries/monkey.rb +1 -1
  26. data/cookbooks/mu-tools/recipes/apply_security.rb +31 -9
  27. data/cookbooks/mu-tools/recipes/aws_api.rb +8 -2
  28. data/cookbooks/mu-tools/recipes/base_repositories.rb +1 -1
  29. data/cookbooks/mu-tools/recipes/gcloud.rb +2 -9
  30. data/cookbooks/mu-tools/recipes/google_api.rb +7 -0
  31. data/cookbooks/mu-tools/recipes/rsyslog.rb +8 -1
  32. data/cookbooks/mu-tools/resources/disk.rb +113 -42
  33. data/cookbooks/mu-tools/resources/mommacat_request.rb +1 -2
  34. data/cookbooks/mu-tools/templates/centos-8/sshd_config.erb +215 -0
  35. data/extras/Gemfile.lock.bootstrap +394 -0
  36. data/extras/bucketstubs/error.html +0 -0
  37. data/extras/bucketstubs/index.html +0 -0
  38. data/extras/clean-stock-amis +11 -3
  39. data/extras/generate-stock-images +6 -3
  40. data/extras/git_rpm/build.sh +20 -0
  41. data/extras/git_rpm/mugit.spec +53 -0
  42. data/extras/image-generators/AWS/centos7.yaml +19 -16
  43. data/extras/image-generators/AWS/{rhel7.yaml → rhel71.yaml} +0 -0
  44. data/extras/image-generators/AWS/{win2k12.yaml → win2k12r2.yaml} +0 -0
  45. data/extras/image-generators/VMWare/centos8.yaml +15 -0
  46. data/extras/openssl_rpm/build.sh +19 -0
  47. data/extras/openssl_rpm/mussl.spec +46 -0
  48. data/extras/python_rpm/muthon.spec +14 -4
  49. data/extras/ruby_rpm/muby.spec +9 -5
  50. data/extras/sqlite_rpm/build.sh +19 -0
  51. data/extras/sqlite_rpm/muqlite.spec +47 -0
  52. data/install/installer +7 -5
  53. data/modules/mommacat.ru +2 -2
  54. data/modules/mu.rb +12 -5
  55. data/modules/mu/cloud/machine_images.rb +1 -1
  56. data/modules/mu/cloud/providers.rb +6 -1
  57. data/modules/mu/cloud/resource_base.rb +7 -4
  58. data/modules/mu/cloud/ssh_sessions.rb +5 -1
  59. data/modules/mu/cloud/wrappers.rb +16 -7
  60. data/modules/mu/config.rb +28 -12
  61. data/modules/mu/config/database.rb +2 -2
  62. data/modules/mu/config/firewall_rule.rb +1 -1
  63. data/modules/mu/config/ref.rb +3 -3
  64. data/modules/mu/config/schema_helpers.rb +12 -3
  65. data/modules/mu/config/server.rb +10 -4
  66. data/modules/mu/config/server_pool.rb +2 -2
  67. data/modules/mu/config/vpc.rb +10 -10
  68. data/modules/mu/defaults/AWS.yaml +96 -96
  69. data/modules/mu/deploy.rb +27 -14
  70. data/modules/mu/groomers/chef.rb +2 -2
  71. data/modules/mu/master.rb +49 -3
  72. data/modules/mu/mommacat.rb +27 -9
  73. data/modules/mu/mommacat/naming.rb +2 -2
  74. data/modules/mu/mommacat/search.rb +16 -5
  75. data/modules/mu/mommacat/storage.rb +67 -32
  76. data/modules/mu/providers/aws.rb +185 -71
  77. data/modules/mu/providers/aws/alarm.rb +3 -3
  78. data/modules/mu/providers/aws/bucket.rb +19 -19
  79. data/modules/mu/providers/aws/cache_cluster.rb +22 -22
  80. data/modules/mu/providers/aws/cdn.rb +2 -2
  81. data/modules/mu/providers/aws/collection.rb +14 -14
  82. data/modules/mu/providers/aws/container_cluster.rb +27 -27
  83. data/modules/mu/providers/aws/database.rb +49 -45
  84. data/modules/mu/providers/aws/dnszone.rb +5 -5
  85. data/modules/mu/providers/aws/endpoint.rb +35 -35
  86. data/modules/mu/providers/aws/firewall_rule.rb +26 -23
  87. data/modules/mu/providers/aws/function.rb +35 -32
  88. data/modules/mu/providers/aws/group.rb +7 -7
  89. data/modules/mu/providers/aws/habitat.rb +2 -2
  90. data/modules/mu/providers/aws/job.rb +35 -32
  91. data/modules/mu/providers/aws/loadbalancer.rb +58 -37
  92. data/modules/mu/providers/aws/log.rb +14 -14
  93. data/modules/mu/providers/aws/msg_queue.rb +10 -10
  94. data/modules/mu/providers/aws/nosqldb.rb +8 -8
  95. data/modules/mu/providers/aws/notifier.rb +7 -7
  96. data/modules/mu/providers/aws/role.rb +69 -47
  97. data/modules/mu/providers/aws/search_domain.rb +10 -10
  98. data/modules/mu/providers/aws/server.rb +198 -110
  99. data/modules/mu/providers/aws/server_pool.rb +71 -119
  100. data/modules/mu/providers/aws/storage_pool.rb +17 -9
  101. data/modules/mu/providers/aws/user.rb +1 -1
  102. data/modules/mu/providers/aws/vpc.rb +106 -51
  103. data/modules/mu/providers/aws/vpc_subnet.rb +43 -39
  104. data/modules/mu/providers/azure.rb +82 -16
  105. data/modules/mu/providers/azure/server.rb +18 -3
  106. data/modules/mu/providers/cloudformation/server.rb +1 -1
  107. data/modules/mu/providers/google.rb +20 -5
  108. data/modules/mu/providers/google/folder.rb +6 -2
  109. data/modules/mu/providers/google/function.rb +65 -30
  110. data/modules/mu/providers/google/role.rb +2 -1
  111. data/modules/mu/providers/google/vpc.rb +27 -2
  112. data/modules/tests/aws-servers-with-handrolled-iam.yaml +37 -0
  113. data/modules/tests/k8s.yaml +1 -1
  114. metadata +32 -15
@@ -30,13 +30,13 @@ module MU
30
30
  @config["log_group_name"] = @mu_name
31
31
  @config["log_stream_name"] =
32
32
  if @config["enable_cloudtrail_logging"]
33
- "#{MU::Cloud::AWS.credToAcct(@config['credentials'])}_CloudTrail_#{@config["region"]}"
33
+ "#{MU::Cloud::AWS.credToAcct(@credentials)}_CloudTrail_#{@region}"
34
34
  else
35
35
  @mu_name
36
36
  end
37
37
 
38
38
  MU.log "Creating log group #{@mu_name}"
39
- MU::Cloud::AWS.cloudwatchlogs(region: @config["region"], credentials: @config["credentials"]).create_log_group(
39
+ MU::Cloud::AWS.cloudwatchlogs(region: @region, credentials: @credentials).create_log_group(
40
40
  log_group_name: @config["log_group_name"],
41
41
  tags: @tags
42
42
  )
@@ -45,7 +45,7 @@ module MU
45
45
  retries = 0
46
46
  max_retries = 5
47
47
  begin
48
- resp = MU::Cloud::AWS::Log.getLogGroupByName(@config["log_group_name"], region: @config["region"])
48
+ resp = MU::Cloud::AWS::Log.getLogGroupByName(@config["log_group_name"], region: @region)
49
49
  if resp.nil?
50
50
  if retries >= max_retries
51
51
  raise MuError, "Cloudwatch Logs group #{@config["log_group_name"]} creation hasn't succeeded after #{(retries*max_retries).to_s}s"
@@ -56,19 +56,19 @@ module MU
56
56
  end
57
57
  end while resp.nil?
58
58
 
59
- MU::Cloud::AWS.cloudwatchlogs(region: @config["region"], credentials: @config["credentials"]).create_log_stream(
59
+ MU::Cloud::AWS.cloudwatchlogs(region: @region, credentials: @credentials).create_log_stream(
60
60
  log_group_name: @config["log_group_name"],
61
61
  log_stream_name: @config["log_stream_name"]
62
62
  )
63
63
 
64
- MU::Cloud::AWS.cloudwatchlogs(region: @config["region"], credentials: @config["credentials"]).put_retention_policy(
64
+ MU::Cloud::AWS.cloudwatchlogs(region: @region, credentials: @credentials).put_retention_policy(
65
65
  log_group_name: @config["log_group_name"],
66
66
  retention_in_days: @config["retention_period"]
67
67
  )
68
68
 
69
69
  if @config["filters"] && !@config["filters"].empty?
70
70
  @config["filters"].each{ |filter|
71
- MU::Cloud::AWS.cloudwatchlogs(region: @config["region"], credentials: @config["credentials"]).put_metric_filter(
71
+ MU::Cloud::AWS.cloudwatchlogs(region: @region, credentials: @credentials).put_metric_filter(
72
72
  log_group_name: @config["log_group_name"],
73
73
  filter_name: filter["name"],
74
74
  filter_pattern: filter["search_pattern"],
@@ -82,8 +82,8 @@ module MU
82
82
  end
83
83
 
84
84
  if @config["enable_cloudtrail_logging"]
85
- trail_resp = MU::Cloud::AWS.cloudtrail(region: @config["region"], credentials: @config["credentials"]).describe_trails.trail_list.first
86
- raise MuError, "Can't find a cloudtrail in #{MU::Cloud::AWS.credToAcct(@config['credentials'])}/#{@config["region"]}. Please create cloudtrail before enabling logging on it" unless trail_resp
85
+ trail_resp = MU::Cloud::AWS.cloudtrail(region: @region, credentials: @credentials).describe_trails.trail_list.first
86
+ raise MuError, "Can't find a cloudtrail in #{MU::Cloud::AWS.credToAcct(@credentials)}/#{@region}. Please create cloudtrail before enabling logging on it" unless trail_resp
87
87
 
88
88
  iam_policy = '{
89
89
  "Version": "2012-10-17",
@@ -96,7 +96,7 @@ module MU
96
96
  "logs:PutLogEventsBatch",
97
97
  "logs:PutLogEvents"
98
98
  ],
99
- "Resource": "arn:'+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+':logs:'+@config["region"]+':'+MU::Cloud::AWS.credToAcct(@config['credentials'])+':log-group:'+@config["log_group_name"]+':log-stream:'+@config["log_stream_name"]+'*"
99
+ "Resource": "arn:'+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+':logs:'+@region+':'+MU::Cloud::AWS.credToAcct(@credentials)+':log-group:'+@config["log_group_name"]+':log-stream:'+@config["log_stream_name"]+'*"
100
100
  }
101
101
  ]
102
102
  }'
@@ -132,11 +132,11 @@ module MU
132
132
  policy_document: iam_policy
133
133
  )
134
134
 
135
- log_group_resp = MU::Cloud::AWS::Log.getLogGroupByName(@config["log_group_name"], region: @config["region"])
135
+ log_group_resp = MU::Cloud::AWS::Log.getLogGroupByName(@config["log_group_name"], region: @region)
136
136
 
137
137
  retries = 0
138
138
  begin
139
- MU::Cloud::AWS.cloudtrail(region: @config["region"], credentials: @config["credentials"]).update_trail(
139
+ MU::Cloud::AWS.cloudtrail(region: @region, credentials: @credentials).update_trail(
140
140
  name: trail_resp.name,
141
141
  cloud_watch_logs_log_group_arn: log_group_resp.arn,
142
142
  cloud_watch_logs_role_arn: iam_resp.role.arn
@@ -270,9 +270,9 @@ module MU
270
270
  def toKitten(**_args)
271
271
  bok = {
272
272
  "cloud" => "AWS",
273
- "credentials" => @config['credentials'],
273
+ "credentials" => @credentials,
274
274
  "cloud_id" => @cloud_id,
275
- "region" => @config['region']
275
+ "region" => @region
276
276
  }
277
277
 
278
278
  if !cloud_desc
@@ -283,7 +283,7 @@ module MU
283
283
  bok['name'] = cloud_desc.log_group_name.sub(/.*?\/([^\/]+)$/, '\1')
284
284
 
285
285
  if cloud_desc.metric_filter_count > 0
286
- resp = MU::Cloud::AWS.cloudwatchlogs(region: @config['region'], credentials: @credentials).describe_metric_filters(
286
+ resp = MU::Cloud::AWS.cloudwatchlogs(region: @region, credentials: @credentials).describe_metric_filters(
287
287
  log_group_name: @cloud_id
288
288
  )
289
289
  resp.metric_filters.each { |filter|
@@ -33,7 +33,7 @@ module MU
33
33
  namestr += ".fifo" if attrs['FifoQueue']
34
34
 
35
35
  MU.log "Creating SQS queue #{namestr}", details: attrs
36
- resp = MU::Cloud::AWS.sqs(region: @config['region'], credentials: @config['credentials']).create_queue(
36
+ resp = MU::Cloud::AWS.sqs(region: @region, credentials: @credentials).create_queue(
37
37
  queue_name: namestr,
38
38
  attributes: attrs
39
39
  )
@@ -60,7 +60,7 @@ module MU
60
60
  }
61
61
  if changed
62
62
  MU.log "Updating SQS queue #{@mu_name}", MU::NOTICE, details: new_attrs
63
- MU::Cloud::AWS.sqs(region: @config['region'], credentials: @config['credentials']).set_queue_attributes(
63
+ MU::Cloud::AWS.sqs(region: @region, credentials: @credentials).set_queue_attributes(
64
64
  queue_url: @cloud_id,
65
65
  attributes: new_attrs
66
66
  )
@@ -71,7 +71,7 @@ module MU
71
71
  # Canonical Amazon Resource Number for this resource
72
72
  # @return [String]
73
73
  def arn
74
- "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":sqs:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":"+@cloud_id
74
+ "arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":sqs:"+@region+":"+MU::Cloud::AWS.credToAcct(@credentials)+":"+@cloud_id
75
75
  end
76
76
 
77
77
  @cloud_desc_cache = nil
@@ -83,7 +83,7 @@ module MU
83
83
  return nil if !@cloud_id
84
84
 
85
85
  if !@cloud_id
86
- resp = MU::Cloud::AWS.sqs(region: @config['region'], credentials: @config['credentials']).list_queues(
86
+ resp = MU::Cloud::AWS.sqs(region: @region, credentials: @credentials).list_queues(
87
87
  queue_name_prefix: @mu_name
88
88
  )
89
89
  return nil if !resp or !resp.queue_urls
@@ -98,8 +98,8 @@ module MU
98
98
  return nil if !@cloud_id
99
99
  @cloud_desc_cache = MU::Cloud::AWS::MsgQueue.find(
100
100
  cloud_id: @cloud_id.dup,
101
- region: @config['region'],
102
- credentials: @config['credentials']
101
+ region: @region,
102
+ credentials: @credentials
103
103
  )
104
104
  @cloud_desc_cache
105
105
  end
@@ -110,8 +110,8 @@ module MU
110
110
  cloud_desc
111
111
  deploy_struct = MU::Cloud::AWS::MsgQueue.find(
112
112
  cloud_id: @cloud_id,
113
- region: @config['region'],
114
- credentials: @config['credentials']
113
+ region: @region,
114
+ credentials: @credentials
115
115
  )
116
116
  return deploy_struct
117
117
  end
@@ -426,7 +426,7 @@ module MU
426
426
  if sibling # resolve sibling queues to something useful
427
427
  id = sibling.cloud_id
428
428
  end
429
- desc = MU::Cloud::AWS::MsgQueue.find(cloud_id: id, credentials: @config['credentials'])
429
+ desc = MU::Cloud::AWS::MsgQueue.find(cloud_id: id, credentials: @credentials)
430
430
  if !desc
431
431
  raise MuError, "Failed to get cloud descriptor for SQS queue #{@config['failqueue']['name']}"
432
432
  end
@@ -484,7 +484,7 @@ module MU
484
484
  end
485
485
 
486
486
  begin
487
- MU::Cloud::AWS.sqs(region: @config['region'], credentials: @config['credentials']).tag_queue(
487
+ MU::Cloud::AWS.sqs(region: @region, credentials: @credentials).tag_queue(
488
488
  queue_url: url,
489
489
  tags: tags
490
490
  )
@@ -114,11 +114,11 @@ module MU
114
114
 
115
115
  MU.log "Creating DynamoDB table #{@mu_name}", MU::NOTICE, details: params
116
116
 
117
- resp = MU::Cloud::AWS.dynamo(credentials: @config['credentials'], region: @config['region']).create_table(params)
117
+ resp = MU::Cloud::AWS.dynamo(credentials: @credentials, region: @region).create_table(params)
118
118
  @cloud_id = @mu_name
119
119
 
120
120
  begin
121
- resp = MU::Cloud::AWS.dynamo(credentials: @config['credentials'], region: @config['region']).describe_table(table_name: @cloud_id)
121
+ resp = MU::Cloud::AWS.dynamo(credentials: @credentials, region: @region).describe_table(table_name: @cloud_id)
122
122
  sleep 5 if resp.table.table_status == "CREATING"
123
123
  end while resp.table.table_status == "CREATING"
124
124
 
@@ -130,7 +130,7 @@ module MU
130
130
  begin
131
131
  batch = items_to_write.slice!(0, (items_to_write.length >= 25 ? 25 : items_to_write.length))
132
132
  begin
133
- MU::Cloud::AWS.dynamo(credentials: @config['credentials'], region: @config['region']).batch_write_item(
133
+ MU::Cloud::AWS.dynamo(credentials: @credentials, region: @region).batch_write_item(
134
134
  request_items: {
135
135
  @cloud_id => batch.map { |i| { put_request: { item: i } } }
136
136
  }
@@ -162,7 +162,7 @@ module MU
162
162
  }
163
163
  end
164
164
 
165
- MU::Cloud::AWS.dynamo(credentials: @config['credentials'], region: @config['region']).tag_resource(
165
+ MU::Cloud::AWS.dynamo(credentials: @credentials, region: @region).tag_resource(
166
166
  resource_arn: arn,
167
167
  tags: tagset
168
168
  )
@@ -281,9 +281,9 @@ module MU
281
281
  def toKitten(**_args)
282
282
  bok = {
283
283
  "cloud" => "AWS",
284
- "credentials" => @config['credentials'],
284
+ "credentials" => @credentials,
285
285
  "cloud_id" => @cloud_id,
286
- "region" => @config['region']
286
+ "region" => @region
287
287
  }
288
288
 
289
289
  if !cloud_desc
@@ -318,10 +318,10 @@ module MU
318
318
 
319
319
  bok['stream'] = cloud_desc.stream_specification.stream_view_type
320
320
  # cloud_desc.latest_stream_arn
321
- # MU::Cloud::AWS.dynamostream(credentials: @credentials, region: @config['region']).list_streams
321
+ # MU::Cloud::AWS.dynamostream(credentials: @credentials, region: @region).list_streams
322
322
  end
323
323
 
324
- bok["populate"] = MU::Cloud::AWS.dynamo(credentials: @credentials, region: @config['region']).scan(
324
+ bok["populate"] = MU::Cloud::AWS.dynamo(credentials: @credentials, region: @region).scan(
325
325
  table_name: @cloud_id
326
326
  ).items
327
327
 
@@ -28,7 +28,7 @@ module MU
28
28
  # Called automatically by {MU::Deploy#createResources}
29
29
  def create
30
30
  @cloud_id = @mu_name
31
- MU::Cloud::AWS.sns(region: @config['region'], credentials: @config['credentials']).create_topic(name: @cloud_id)
31
+ MU::Cloud::AWS.sns(region: @region, credentials: @credentials).create_topic(name: @cloud_id)
32
32
  MU.log "Created SNS topic #{@mu_name}"
33
33
  end
34
34
 
@@ -52,7 +52,7 @@ module MU
52
52
  # @param endpoint [String]: The address, identifier, or ARN of the resource being subscribed
53
53
  # @param protocol [String]: The protocol being subscribed
54
54
  def subscribe(endpoint, protocol)
55
- self.class.subscribe(arn, endpoint, protocol, region: @config['region'], credentials: @credentials)
55
+ self.class.subscribe(arn, endpoint, protocol, region: @region, credentials: @credentials)
56
56
  end
57
57
 
58
58
  # Subscribe something to an SNS topic
@@ -116,14 +116,14 @@ module MU
116
116
  # @return [String]
117
117
  def arn
118
118
  @cloud_id ||= @mu_name
119
- "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":sns:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":"+@cloud_id
119
+ "arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":sns:"+@region+":"+MU::Cloud::AWS.credToAcct(@credentials)+":"+@cloud_id
120
120
  end
121
121
 
122
122
  # Return the metadata for this user cofiguration
123
123
  # @return [Hash]
124
124
  def notify
125
125
  return nil if !@cloud_id or !cloud_desc(use_cache: false)
126
- desc = MU::Cloud::AWS.sns(region: @config["region"], credentials: @config["credentials"]).get_topic_attributes(topic_arn: arn).attributes
126
+ desc = MU::Cloud::AWS.sns(region: @region, credentials: @credentials).get_topic_attributes(topic_arn: arn).attributes
127
127
  MU.structToHash(desc)
128
128
  end
129
129
 
@@ -165,9 +165,9 @@ module MU
165
165
  def toKitten(**_args)
166
166
  bok = {
167
167
  "cloud" => "AWS",
168
- "credentials" => @config['credentials'],
168
+ "credentials" => @credentials,
169
169
  "cloud_id" => @cloud_id,
170
- "region" => @config['region']
170
+ "region" => @region
171
171
  }
172
172
 
173
173
  if !cloud_desc
@@ -180,7 +180,7 @@ module MU
180
180
  "lambda" => "functions",
181
181
  "sqs" => "msg_queues"
182
182
  }
183
- MU::Cloud::AWS.sns(region: @config['region'], credentials: @credentials).list_subscriptions_by_topic(topic_arn: cloud_desc["TopicArn"]).subscriptions.each { |sub|
183
+ MU::Cloud::AWS.sns(region: @region, credentials: @credentials).list_subscriptions_by_topic(topic_arn: cloud_desc["TopicArn"]).subscriptions.each { |sub|
184
184
  bok['subscriptions'] ||= []
185
185
 
186
186
  bok['subscriptions'] << if sub.endpoint.match(/^arn:[^:]+:(sqs|lambda):([^:]+):(\d+):.*?([^:\/]+)$/)
@@ -30,7 +30,7 @@ module MU
30
30
  end
31
31
  end
32
32
 
33
- @mu_name ||= @deploy.getResourceName(@config["name"], max_length: 64)
33
+ @mu_name ||= @config['scrub_mu_isms'] ? @config['name'] : @deploy.getResourceName(@config["name"], max_length: 64)
34
34
  end
35
35
 
36
36
  # Called automatically by {MU::Deploy#createResources}
@@ -43,7 +43,7 @@ module MU
43
43
 
44
44
  policy_name = @mu_name+"-"+policy.keys.first.upcase
45
45
  MU.log "Creating IAM policy #{policy_name}"
46
- MU::Cloud::AWS.iam(credentials: @config['credentials']).create_policy(
46
+ MU::Cloud::AWS.iam(credentials: @credentials).create_policy(
47
47
  policy_name: policy_name,
48
48
  path: "/"+@deploy.deploy_id+"/",
49
49
  policy_document: JSON.generate(policy.values.first),
@@ -53,16 +53,18 @@ module MU
53
53
  end
54
54
 
55
55
  if !@config['bare_policies']
56
- MU.log "Creating IAM role #{@mu_name}"
57
56
  @cloud_id = @mu_name
58
57
  path = @config['strip_path'] ? nil : "/"+@deploy.deploy_id+"/"
59
- MU::Cloud::AWS.iam(credentials: @config['credentials']).create_role(
60
- path: path,
61
- role_name: @mu_name,
62
- description: "Generated by Mu",
63
- assume_role_policy_document: gen_assume_role_policy_doc,
64
- tags: get_tag_params
65
- )
58
+ params = {
59
+ :path => path,
60
+ :role_name => @mu_name,
61
+ :description => "Generated by Mu",
62
+ :assume_role_policy_document => gen_assume_role_policy_doc,
63
+ :tags => get_tag_params(@config['scrub_mu_isms'])
64
+ }
65
+
66
+ MU.log "Creating IAM role #{@mu_name} (#{@credentials})", details: params
67
+ MU::Cloud::AWS.iam(credentials: @credentials).create_role(params)
66
68
  end
67
69
  end
68
70
 
@@ -75,7 +77,7 @@ module MU
75
77
  end
76
78
 
77
79
  if !@config['bare_policies']
78
- resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_role(
80
+ resp = MU::Cloud::AWS.iam(credentials: @credentials).get_role(
79
81
  role_name: @mu_name
80
82
  ).role
81
83
  ext_tags = resp.tags.map { |t| t.to_h }
@@ -84,7 +86,7 @@ module MU
84
86
 
85
87
  if tag_param.size > 0
86
88
  MU.log "Updating tags on IAM role #{@mu_name}", MU::NOTICE, details: tag_param
87
- MU::Cloud::AWS.iam(credentials: @config['credentials']).tag_role(role_name: @mu_name, tags: tag_param)
89
+ MU::Cloud::AWS.iam(credentials: @credentials).tag_role(role_name: @mu_name, tags: tag_param)
88
90
  end
89
91
  end
90
92
 
@@ -92,13 +94,14 @@ module MU
92
94
  configured_policies = []
93
95
 
94
96
  if @config['raw_policies']
97
+ MU.log "Attaching #{@config['raw_policies'].size.to_s} raw #{@config['raw_policies'].size > 1 ? "policies" : "policy"} to role #{@mu_name}", MU::NOTICE
95
98
  configured_policies = @config['raw_policies'].map { |p|
96
99
  @mu_name+"-"+p.keys.first.upcase
97
100
  }
98
101
  end
99
102
 
100
103
  if @config['attachable_policies']
101
- MU.log "Attaching #{@config['attachable_policies'].size.to_s} #{@config['attachable_policies'].size > 1 ? "policies" : "policy"} to role #{@mu_name}", MU::NOTICE
104
+ MU.log "Attaching #{@config['attachable_policies'].size.to_s} external #{@config['attachable_policies'].size > 1 ? "policies" : "policy"} to role #{@mu_name}", MU::NOTICE
102
105
  configured_policies.concat(@config['attachable_policies'].map { |p|
103
106
  id = if p.is_a?(MU::Config::Ref)
104
107
  p.cloud_id
@@ -109,18 +112,17 @@ module MU
109
112
  end
110
113
  id.gsub(/.*?\/([^:\/]+)$/, '\1')
111
114
  })
112
- configured_policies.each { |pol|
113
- }
114
115
  end
115
116
 
117
+ # Purge anything that doesn't belong
116
118
  if !@config['bare_policies']
117
- attached_policies = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_role_policies(
119
+ attached_policies = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_role_policies(
118
120
  role_name: @mu_name
119
121
  ).attached_policies
120
122
  attached_policies.each { |a|
121
123
  if !configured_policies.include?(a.policy_name)
122
- MU.log "Removing IAM policy #{a.policy_name} from role #{@mu_name}", MU::NOTICE
123
- MU::Cloud::AWS::Role.purgePolicy(a.policy_arn, @config['credentials'])
124
+ MU.log "Removing IAM policy #{a.policy_name} from role #{@mu_name}", MU::NOTICE, details: configured_policies
125
+ MU::Cloud::AWS::Role.purgePolicy(a.policy_arn, @credentials)
124
126
  end
125
127
  }
126
128
  end
@@ -153,8 +155,8 @@ module MU
153
155
  policy.values.each { |p|
154
156
  p["Version"] ||= "2012-10-17"
155
157
  }
156
- policy_name = basename+"-"+policy.keys.first.upcase
157
158
 
159
+ policy_name = basename+"-"+policy.keys.first.upcase
158
160
  arn = "arn:"+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+":iam::"+MU::Cloud::AWS.credToAcct(credentials)+":policy#{path}/#{policy_name}"
159
161
  resp = begin
160
162
  desc = MU::Cloud::AWS.iam(credentials: credentials).get_policy(policy_arn: arn)
@@ -164,7 +166,7 @@ module MU
164
166
  version_id: desc.policy.default_version_id
165
167
  )
166
168
 
167
- ext = JSON.parse(URI.decode(version.policy_version.document))
169
+ ext = JSON.parse(CGI.unescape(version.policy_version.document))
168
170
  if ext != policy.values.first
169
171
  # Special exception- we don't want to overwrite extra rules
170
172
  # in MuSecrets policies, because our siblings might have
@@ -184,12 +186,16 @@ module MU
184
186
 
185
187
  rescue Aws::IAM::Errors::NoSuchEntity
186
188
  MU.log "Creating IAM policy #{policy_name}", details: policy.values.first
187
- MU::Cloud::AWS.iam(credentials: credentials).create_policy(
189
+ desc = MU::Cloud::AWS.iam(credentials: credentials).create_policy(
188
190
  policy_name: policy_name,
189
191
  path: path+"/",
190
192
  policy_document: JSON.generate(policy.values.first),
191
193
  description: "Raw policy from #{basename}"
192
194
  )
195
+ MU.retrier([Aws::IAM::Errors::NoSuchEntity], loop_if: Proc.new { desc.nil? }) {
196
+ desc = MU::Cloud::AWS.iam(credentials: credentials).get_policy(policy_arn: arn)
197
+ }
198
+ desc
193
199
  end
194
200
  arns << resp.policy.arn
195
201
  }
@@ -216,6 +222,7 @@ module MU
216
222
  # populated with one or both depending on what this resource has
217
223
  # defined.
218
224
  def cloud_desc(use_cache: true)
225
+ require 'aws-sdk-iam'
219
226
 
220
227
  # we might inherit a naive cached description from the base cloud
221
228
  # layer; rearrange it to our tastes
@@ -305,8 +312,8 @@ end
305
312
  # Insert a new target entity into an existing policy.
306
313
  # @param policy [String]: The name of the policy to which we're appending, which must already exist as part of this role resource
307
314
  # @param targets [Array<String>]: The target resource. If +target_type+ isn't specified, this should be a fully-resolved ARN.
308
- def injectPolicyTargets(policy, targets)
309
- if !policy.match(/^#{@deploy.deploy_id}/)
315
+ def injectPolicyTargets(policy, targets, attach: false)
316
+ if @deploy and !policy.match(/^#{@deploy.deploy_id}/)
310
317
  policy = @mu_name+"-"+policy.upcase
311
318
  end
312
319
  my_policies = cloud_desc(use_cache: false)["policies"]
@@ -316,7 +323,7 @@ end
316
323
  my_policies.each { |p|
317
324
  if p.policy_name == policy
318
325
  seen_policy = true
319
- old = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy_version(
326
+ old = MU::Cloud::AWS.iam(credentials: @credentials).get_policy_version(
320
327
  policy_arn: p.arn,
321
328
  version_id: p.default_version_id
322
329
  ).policy_version
@@ -328,7 +335,7 @@ end
328
335
  targets.each { |target|
329
336
  target_string = target
330
337
 
331
- if target['type']
338
+ if target['type'] and @deploy
332
339
  sibling = @deploy.findLitterMate(
333
340
  name: target["identifier"],
334
341
  type: target["type"]
@@ -575,7 +582,7 @@ end
575
582
  def toKitten(**_args)
576
583
  bok = {
577
584
  "cloud" => "AWS",
578
- "credentials" => @config['credentials'],
585
+ "credentials" => @credentials,
579
586
  "cloud_id" => @cloud_id
580
587
  }
581
588
 
@@ -609,7 +616,7 @@ end
609
616
  policy_name: pol.policy_name
610
617
  )
611
618
  if resp and resp.policy_document
612
- JSON.parse(URI.decode(resp.policy_document))
619
+ JSON.parse(CGI.unescape(resp.policy_document))
613
620
  end
614
621
  rescue ::Aws::IAM::Errors::NoSuchEntity, ::Aws::IAM::Errors::ValidationError
615
622
  resp = MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
@@ -619,7 +626,7 @@ end
619
626
  policy_arn: pol.arn,
620
627
  version_id: resp.policy.default_version_id
621
628
  )
622
- JSON.parse(URI.decode(version.policy_version.document))
629
+ JSON.parse(CGI.unescape(version.policy_version.document))
623
630
  end
624
631
  bok["policies"] = MU::Cloud::AWS::Role.doc2MuPolicies(pol.policy_name, doc, bok["policies"])
625
632
  end
@@ -635,7 +642,7 @@ end
635
642
  bok["strip_path"] = true if desc.path == "/"
636
643
 
637
644
  if desc.assume_role_policy_document
638
- assume_doc = JSON.parse(URI.decode(desc.assume_role_policy_document))
645
+ assume_doc = JSON.parse(CGI.unescape(desc.assume_role_policy_document))
639
646
  assume_doc["Statement"].each { |s|
640
647
  bok["can_assume"] ||= []
641
648
  method = if s["Action"] == "sts:AssumeRoleWithWebIdentity"
@@ -768,12 +775,12 @@ end
768
775
  def bindTo(entitytype, entityname)
769
776
  if entitytype == "instance_profile"
770
777
  begin
771
- resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(
778
+ resp = MU::Cloud::AWS.iam(credentials: @credentials).get_instance_profile(
772
779
  instance_profile_name: entityname
773
780
  ).instance_profile
774
781
 
775
782
  if !resp.roles.map { |r| r.role_name}.include?(@mu_name)
776
- MU::Cloud::AWS.iam(credentials: @config['credentials']).add_role_to_instance_profile(
783
+ MU::Cloud::AWS.iam(credentials: @credentials).add_role_to_instance_profile(
777
784
  instance_profile_name: entityname,
778
785
  role_name: @mu_name
779
786
  )
@@ -783,30 +790,30 @@ end
783
790
  raise e
784
791
  end
785
792
  elsif ["user", "group", "role"].include?(entitytype)
786
- mypolicies = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_policies(
793
+ mypolicies = MU::Cloud::AWS.iam(credentials: @credentials).list_policies(
787
794
  path_prefix: "/"+@deploy.deploy_id+"/"
788
795
  ).policies
789
796
  mypolicies.reject! { |p|
790
- !p.policy_name.match(/^#{Regexp.quote(@mu_name)}-/)
797
+ !p.policy_name.match(/^#{Regexp.quote(@mu_name)}(-|$)/)
791
798
  }
792
799
 
793
800
  if @config['attachable_policies']
794
801
  @config['attachable_policies'].each { |policy_hash|
795
802
  policy = policy_hash["id"]
796
803
  p_arn = if !policy.match(/^arn:/i)
797
- "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/"+policy
804
+ "arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":iam::aws:policy/"+policy
798
805
  else
799
806
  policy
800
807
  end
801
808
 
802
809
  subpaths = ["service-role", "aws-service-role", "job-function"]
803
810
  begin
804
- mypolicies << MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy(
811
+ mypolicies << MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
805
812
  policy_arn: p_arn
806
813
  ).policy
807
814
  rescue Aws::IAM::Errors::NoSuchEntity => e
808
815
  if subpaths.size > 0
809
- p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/#{subpaths.shift}/"+policy
816
+ p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":iam::aws:policy/#{subpaths.shift}/"+policy
810
817
  retry
811
818
  end
812
819
  raise e
@@ -814,39 +821,52 @@ end
814
821
  }
815
822
  end
816
823
 
824
+ if @config['raw_policies']
825
+ raw_arns = MU::Cloud::AWS::Role.manageRawPolicies(
826
+ @config['raw_policies'],
827
+ basename: @deploy.getResourceName(@config['name']),
828
+ credentials: @credentials
829
+ )
830
+ raw_arns.each { |p_arn|
831
+ mypolicies << MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
832
+ policy_arn: p_arn
833
+ ).policy
834
+ }
835
+ end
836
+
817
837
  mypolicies.each { |p|
818
838
  if entitytype == "user"
819
- resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_user_policies(
839
+ resp = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_user_policies(
820
840
  path_prefix: "/"+@deploy.deploy_id+"/",
821
841
  user_name: entityname
822
842
  )
823
843
  if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
824
844
  MU.log "Attaching IAM policy #{p.policy_name} to user #{entityname}", MU::NOTICE
825
- MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_user_policy(
845
+ MU::Cloud::AWS.iam(credentials: @credentials).attach_user_policy(
826
846
  policy_arn: p.arn,
827
847
  user_name: entityname
828
848
  )
829
849
  end
830
850
  elsif entitytype == "group"
831
- resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_group_policies(
851
+ resp = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_group_policies(
832
852
  path_prefix: "/"+@deploy.deploy_id+"/",
833
853
  group_name: entityname
834
854
  )
835
855
  if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
836
856
  MU.log "Attaching policy #{p.policy_name} to group #{entityname}", MU::NOTICE
837
- MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_group_policy(
857
+ MU::Cloud::AWS.iam(credentials: @credentials).attach_group_policy(
838
858
  policy_arn: p.arn,
839
859
  group_name: entityname
840
860
  )
841
861
  end
842
862
  elsif entitytype == "role"
843
- resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_role_policies(
863
+ resp = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_role_policies(
844
864
  role_name: entityname
845
865
  )
846
866
 
847
867
  if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
848
868
  MU.log "Attaching policy #{p.policy_name} to role #{entityname}", MU::NOTICE
849
- MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_role_policy(
869
+ MU::Cloud::AWS.iam(credentials: @credentials).attach_role_policy(
850
870
  policy_arn: p.arn,
851
871
  role_name: entityname
852
872
  )
@@ -867,19 +887,19 @@ end
867
887
  end
868
888
 
869
889
  resp = begin
870
- MU.log "Creating instance profile #{@mu_name} #{@config['credentials']}"
871
- MU::Cloud::AWS.iam(credentials: @config['credentials']).create_instance_profile(
890
+ MU.log "Creating instance profile #{@mu_name} #{@credentials}"
891
+ MU::Cloud::AWS.iam(credentials: @credentials).create_instance_profile(
872
892
  instance_profile_name: @mu_name
873
893
  )
874
894
  rescue Aws::IAM::Errors::EntityAlreadyExists
875
- MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(
895
+ MU::Cloud::AWS.iam(credentials: @credentials).get_instance_profile(
876
896
  instance_profile_name: @mu_name
877
897
  )
878
898
  end
879
899
 
880
900
  # make sure it's really there before moving on
881
901
  begin
882
- MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(instance_profile_name: @mu_name)
902
+ MU::Cloud::AWS.iam(credentials: @credentials).get_instance_profile(instance_profile_name: @mu_name)
883
903
  rescue Aws::IAM::Errors::NoSuchEntity => e
884
904
  MU.log e.inspect, MU::WARN
885
905
  sleep 10
@@ -1067,6 +1087,8 @@ end
1067
1087
  role.delete("import")
1068
1088
  end
1069
1089
 
1090
+ role['strip_path'] = true if role['scrub_mu_isms']
1091
+
1070
1092
  # If we're attaching some managed policies, make sure all of the ones
1071
1093
  # that should already exist do indeed exist
1072
1094
  if role['attachable_policies']
@@ -1097,7 +1119,7 @@ end
1097
1119
  role['policies'].each { |policy|
1098
1120
  policy['targets'].each { |target|
1099
1121
  if target['type']
1100
- MU::Config.addDependency(role, target['identifier'], target['type'], no_create_wait: true)
1122
+ MU::Config.addDependency(role, target['identifier'], target['type'], my_phase: "groom")
1101
1123
  end
1102
1124
  }
1103
1125
  }