cloud-mu 2.0.4 → 2.1.0beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +6 -0
  3. data/ansible/roles/geerlingguy.firewall/LICENSE +20 -0
  4. data/ansible/roles/geerlingguy.firewall/README.md +93 -0
  5. data/ansible/roles/geerlingguy.firewall/defaults/main.yml +19 -0
  6. data/ansible/roles/geerlingguy.firewall/handlers/main.yml +3 -0
  7. data/ansible/roles/geerlingguy.firewall/meta/main.yml +26 -0
  8. data/ansible/roles/geerlingguy.firewall/molecule/default/molecule.yml +40 -0
  9. data/ansible/roles/geerlingguy.firewall/molecule/default/playbook.yml +17 -0
  10. data/ansible/roles/geerlingguy.firewall/molecule/default/tests/test_default.py +14 -0
  11. data/ansible/roles/geerlingguy.firewall/molecule/default/yaml-lint.yml +6 -0
  12. data/ansible/roles/geerlingguy.firewall/tasks/disable-other-firewalls.yml +66 -0
  13. data/ansible/roles/geerlingguy.firewall/tasks/main.yml +44 -0
  14. data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +136 -0
  15. data/ansible/roles/geerlingguy.firewall/templates/firewall.init.j2 +52 -0
  16. data/ansible/roles/geerlingguy.firewall/templates/firewall.unit.j2 +12 -0
  17. data/bin/mu-ansible-secret +114 -0
  18. data/bin/mu-aws-setup +74 -21
  19. data/bin/mu-node-manage +22 -12
  20. data/bin/mu-self-update +11 -4
  21. data/cloud-mu.gemspec +3 -3
  22. data/cookbooks/firewall/metadata.json +1 -1
  23. data/cookbooks/firewall/recipes/default.rb +4 -0
  24. data/cookbooks/mu-master/recipes/default.rb +0 -3
  25. data/cookbooks/mu-master/recipes/init.rb +15 -9
  26. data/cookbooks/mu-master/templates/default/mu.rc.erb +1 -1
  27. data/cookbooks/mu-master/templates/default/web_app.conf.erb +0 -4
  28. data/cookbooks/mu-php54/metadata.rb +2 -2
  29. data/cookbooks/mu-php54/recipes/default.rb +1 -3
  30. data/cookbooks/mu-tools/recipes/eks.rb +25 -2
  31. data/cookbooks/mu-tools/recipes/nrpe.rb +6 -1
  32. data/cookbooks/mu-tools/recipes/set_mu_hostname.rb +8 -0
  33. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
  34. data/cookbooks/mu-tools/templates/default/kubeconfig.erb +2 -2
  35. data/cookbooks/mu-tools/templates/default/kubelet-config.json.erb +35 -0
  36. data/extras/clean-stock-amis +10 -4
  37. data/extras/list-stock-amis +64 -0
  38. data/extras/python_rpm/build.sh +21 -0
  39. data/extras/python_rpm/muthon.spec +68 -0
  40. data/install/README.md +5 -2
  41. data/install/user-dot-murc.erb +1 -1
  42. data/modules/mu.rb +52 -8
  43. data/modules/mu/clouds/aws.rb +1 -1
  44. data/modules/mu/clouds/aws/container_cluster.rb +1071 -47
  45. data/modules/mu/clouds/aws/firewall_rule.rb +45 -19
  46. data/modules/mu/clouds/aws/log.rb +3 -2
  47. data/modules/mu/clouds/aws/role.rb +18 -2
  48. data/modules/mu/clouds/aws/server.rb +11 -5
  49. data/modules/mu/clouds/aws/server_pool.rb +20 -24
  50. data/modules/mu/clouds/aws/userdata/linux.erb +1 -1
  51. data/modules/mu/clouds/aws/vpc.rb +9 -0
  52. data/modules/mu/clouds/google/server.rb +2 -0
  53. data/modules/mu/config.rb +3 -3
  54. data/modules/mu/config/container_cluster.rb +1 -1
  55. data/modules/mu/config/firewall_rule.rb +4 -0
  56. data/modules/mu/config/role.rb +29 -0
  57. data/modules/mu/config/server.rb +9 -4
  58. data/modules/mu/groomer.rb +14 -3
  59. data/modules/mu/groomers/ansible.rb +553 -0
  60. data/modules/mu/groomers/chef.rb +0 -5
  61. data/modules/mu/mommacat.rb +18 -3
  62. data/modules/scratchpad.erb +1 -1
  63. data/requirements.txt +5 -0
  64. metadata +39 -16
@@ -106,10 +106,10 @@ module MU
106
106
  # XXX the egress logic here is a crude hack, this really needs to be
107
107
  # done at config level
108
108
  setRules(
109
- [],
110
- add_to_self: @config['self_referencing'],
111
- ingress: true,
112
- egress: egress
109
+ [],
110
+ add_to_self: @config['self_referencing'],
111
+ ingress: true,
112
+ egress: egress
113
113
  )
114
114
 
115
115
  MU.log "EC2 Security Group #{groupname} is #{secgroup.group_id}", MU::DEBUG
@@ -124,10 +124,10 @@ module MU
124
124
  # XXX the egress logic here is a crude hack, this really needs to be
125
125
  # done at config level
126
126
  setRules(
127
- @config['rules'],
128
- add_to_self: @config['self_referencing'],
129
- ingress: true,
130
- egress: egress
127
+ @config['rules'],
128
+ add_to_self: @config['self_referencing'],
129
+ ingress: true,
130
+ egress: egress
131
131
  )
132
132
  end
133
133
  end
@@ -150,36 +150,58 @@ module MU
150
150
  # @param egress [Boolean]: Whether this is an egress ruleset, instead of ingress.
151
151
  # @param port_range [String]: A port range descriptor (e.g. 0-65535). Only valid with udp or tcp.
152
152
  # @return [void]
153
- def addRule(hosts, proto: "tcp", port: nil, egress: false, port_range: "0-65535")
153
+ def addRule(hosts, proto: "tcp", port: nil, egress: false, port_range: "0-65535", comment: nil)
154
154
  rule = Hash.new
155
155
  rule["proto"] = proto
156
- if hosts.is_a?(String)
157
- rule["hosts"] = [hosts]
158
- else
159
- rule["hosts"] = hosts
160
- end
156
+ sgs = []
157
+ hosts = [hosts] if hosts.is_a?(String)
158
+ hosts.each { |h|
159
+ if h.match(/^sg-/)
160
+ sgs << h
161
+ end
162
+ }
163
+ rule["sgs"] = sgs if sgs.size > 0
164
+ hosts = hosts - sgs
165
+ rule["hosts"] = hosts if hosts.size > 0
166
+
161
167
  if port != nil
162
168
  port = port.to_s if !port.is_a?(String)
163
169
  rule["port"] = port
164
170
  else
165
171
  rule["port_range"] = port_range
166
172
  end
173
+ rule["description"] = comment if comment
167
174
  ec2_rule = convertToEc2([rule])
168
175
 
169
176
  begin
170
177
  if egress
171
178
  MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).authorize_security_group_egress(
172
- group_id: @cloud_id,
173
- ip_permissions: ec2_rule
179
+ group_id: @cloud_id,
180
+ ip_permissions: ec2_rule
174
181
  )
175
182
  else
176
183
  MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).authorize_security_group_ingress(
177
- group_id: @cloud_id,
178
- ip_permissions: ec2_rule
184
+ group_id: @cloud_id,
185
+ ip_permissions: ec2_rule
179
186
  )
180
187
  end
181
188
  rescue Aws::EC2::Errors::InvalidPermissionDuplicate => e
182
189
  MU.log "Attempt to add duplicate rule to #{@cloud_id}", MU::DEBUG, details: ec2_rule
190
+ # Ensure that, at least, the description field gets updated on
191
+ # existing rules
192
+ if comment
193
+ if egress
194
+ MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).update_security_group_rule_descriptions_egress(
195
+ group_id: @cloud_id,
196
+ ip_permissions: ec2_rule
197
+ )
198
+ else
199
+ MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).update_security_group_rule_descriptions_ingress(
200
+ group_id: @cloud_id,
201
+ ip_permissions: ec2_rule
202
+ )
203
+ end
204
+ end
183
205
  end
184
206
  end
185
207
 
@@ -554,7 +576,11 @@ module MU
554
576
  rule['hosts'].each { |cidr|
555
577
  next if cidr.nil? # XXX where is that coming from?
556
578
  cidr = cidr + "/32" if cidr.match(/^\d+\.\d+\.\d+\.\d+$/)
557
- ec2_rule[:ip_ranges] << {cidr_ip: cidr}
579
+ if rule['description']
580
+ ec2_rule[:ip_ranges] << {cidr_ip: cidr, description: rule['description']}
581
+ else
582
+ ec2_rule[:ip_ranges] << {cidr_ip: cidr}
583
+ end
558
584
  }
559
585
  end
560
586
 
@@ -191,13 +191,14 @@ module MU
191
191
 
192
192
  # Return the cloud descriptor for the Log Group
193
193
  def cloud_desc
194
- MU::Cloud::AWS::Log.find(cloud_id: @cloud_id).values.first
194
+ found = MU::Cloud::AWS::Log.find(cloud_id: @cloud_id)
195
+ found ? found.values.first : nil
195
196
  end
196
197
 
197
198
  # Canonical Amazon Resource Number for this resource
198
199
  # @return [String]
199
200
  def arn
200
- cloud_desc.arn
201
+ cloud_desc ? cloud_desc.arn : nil
201
202
  end
202
203
 
203
204
  # Return the metadata for this log configuration
@@ -30,6 +30,7 @@ module MU
30
30
  @config = MU::Config.manxify(kitten_cfg)
31
31
  @cloud_id ||= cloud_id
32
32
  @mu_name = mu_name
33
+ @cloud_id ||= @mu_name # should be the same
33
34
  @mu_name ||= @deploy.getResourceName(@config["name"])
34
35
  end
35
36
 
@@ -54,8 +55,10 @@ module MU
54
55
 
55
56
  if !@config['bare_policies']
56
57
  MU.log "Creating IAM role #{@mu_name}"
58
+ @cloud_id = @mu_name
59
+ path = @config['strip_path'] ? nil : "/"+@deploy.deploy_id+"/"
57
60
  resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).create_role(
58
- path: "/"+@deploy.deploy_id+"/",
61
+ path: nil,
59
62
  role_name: @mu_name,
60
63
  description: "Generated by Mu",
61
64
  assume_role_policy_document: gen_role_policy_doc,
@@ -128,6 +131,7 @@ module MU
128
131
  policy_arn: arn,
129
132
  version_id: desc.policy.default_version_id
130
133
  )
134
+
131
135
  if version.policy_version.document != URI.encode(JSON.generate(policy.values.first), /[^a-z0-9\-]/i)
132
136
  MU.log "Updating IAM policy #{policy_name}", MU::NOTICE, details: policy.values.first
133
137
  update_policy(arn, policy.values.first)
@@ -196,6 +200,7 @@ module MU
196
200
  end
197
201
 
198
202
  end
203
+ desc['cloud_id'] ||= @cloud_id
199
204
 
200
205
  desc
201
206
  end
@@ -216,6 +221,7 @@ module MU
216
221
  end
217
222
 
218
223
  my_policies = cloud_desc["policies"]
224
+ my_policies ||= []
219
225
 
220
226
  my_policies.each { |p|
221
227
  if p.policy_name == policy
@@ -563,6 +569,11 @@ module MU
563
569
  "tags" => MU::Config.tags_primitive,
564
570
  "optional_tags" => MU::Config.optional_tags_primitive,
565
571
  "policies" => self.condition_schema,
572
+ "strip_path" => {
573
+ "type" => "boolean",
574
+ "default" => false,
575
+ "description" => "Normally we namespace IAM roles with a +path+ set to match our +deploy_id+; this disables that behavior. Temporary workaround for a bug in EKS/IAM integration."
576
+ },
566
577
  "import" => {
567
578
  "items" => {
568
579
  "description" => "Can be a shorthand reference to a canned IAM policy like +AdministratorAccess+, or a full ARN like +arn:aws:iam::aws:policy/AmazonESCognitoAccess+"
@@ -734,8 +745,13 @@ module MU
734
745
  )
735
746
  if sibling
736
747
  id = sibling.cloudobj.arn
737
- id += target["path"] if target["path"]
748
+ id.sub!(/:([^:]+)$/, ":"+target["path"]) if target["path"]
738
749
  doc["Statement"].first["Resource"] << id
750
+ if id.match(/:log-group:/)
751
+ stream_id = id.sub(/:([^:]+)$/, ":log-stream:*")
752
+ # "arn:aws:logs:us-east-2:accountID:log-group:log_group_name:log-stream:CloudTrail_log_stream_name_prefix*"
753
+ doc["Statement"].first["Resource"] << stream_id
754
+ end
739
755
  else
740
756
  raise MuError, "Couldn't find a #{target["entity_type"]} named #{target["identifier"]} when generating IAM policy"
741
757
  end
@@ -424,7 +424,10 @@ module MU
424
424
  groupname = resp.auto_scaling_instances.first.auto_scaling_group_name
425
425
  MU.log "Pausing Autoscale processes in #{groupname}", MU::NOTICE
426
426
  MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).suspend_processes(
427
- auto_scaling_group_name: groupname
427
+ auto_scaling_group_name: groupname,
428
+ scaling_processes: [
429
+ "Terminate",
430
+ ],
428
431
  )
429
432
  end
430
433
  begin
@@ -445,7 +448,10 @@ module MU
445
448
  if !groupname.nil?
446
449
  MU.log "Resuming Autoscale processes in #{groupname}", MU::NOTICE
447
450
  MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).resume_processes(
448
- auto_scaling_group_name: groupname
451
+ auto_scaling_group_name: groupname,
452
+ scaling_processes: [
453
+ "Terminate",
454
+ ],
449
455
  )
450
456
  end
451
457
  end
@@ -1218,7 +1224,7 @@ module MU
1218
1224
  purgecmd = "rm -rf /cygdrive/c/chef/ /home/#{@config['windows_admin_username']}/.ssh/authorized_keys /home/Administrator/.ssh/authorized_keys /cygdrive/c/mu-installer-ran-updates /cygdrive/c/mu_installed_chef"
1219
1225
  # session.exec!("powershell -Command \"& {(Get-WmiObject -Class Win32_Product -Filter \"Name='UniversalForwarder'\").Uninstall()}\"")
1220
1226
  else
1221
- purgecmd = "#{sudo} rm -rf /root/.ssh/authorized_keys /etc/ssh/ssh_host_*key* /etc/chef /etc/opscode/* /.mu-installer-ran-updates /var/chef /opt/mu_installed_chef /opt/chef ; #{sudo} sed -i 's/^HOSTNAME=.*//' /etc/sysconfig/network"
1227
+ purgecmd = "#{sudo} rm -rf /var/lib/cloud/instances/i-* /root/.ssh/authorized_keys /etc/ssh/ssh_host_*key* /etc/chef /etc/opscode/* /.mu-installer-ran-updates /var/chef /opt/mu_installed_chef /opt/chef ; #{sudo} sed -i 's/^HOSTNAME=.*//' /etc/sysconfig/network"
1222
1228
  end
1223
1229
  end
1224
1230
  session.exec!(purgecmd)
@@ -2205,8 +2211,8 @@ module MU
2205
2211
  if server['iam_policies']
2206
2212
  role['iam_policies'] = server['iam_policies'].dup
2207
2213
  end
2208
- if server['canned_policies']
2209
- role['import'] = server['canned_policies'].dup
2214
+ if server['canned_iam_policies']
2215
+ role['import'] = server['canned_iam_policies'].dup
2210
2216
  end
2211
2217
  if server['iam_role']
2212
2218
  # XXX maybe break this down into policies and add those?
@@ -368,18 +368,7 @@ module MU
368
368
  policy_params[:scaling_adjustment] = policy['adjustment']
369
369
  policy_params[:adjustment_type] = policy['type']
370
370
  elsif policy["policy_type"] == "TargetTrackingScaling"
371
- def strToSym(hash)
372
- newhash = {}
373
- hash.each_pair { |k, v|
374
- if v.is_a?(Hash)
375
- newhash[k.to_sym] = strToSym(v)
376
- else
377
- newhash[k.to_sym] = v
378
- end
379
- }
380
- newhash
381
- end
382
- policy_params[:target_tracking_configuration] = strToSym(policy['target_tracking_configuration'])
371
+ policy_params[:target_tracking_configuration] = MU.strToSym(policy['target_tracking_configuration'])
383
372
  policy_params[:target_tracking_configuration].delete(:preferred_target_group)
384
373
  if policy_params[:target_tracking_configuration][:predefined_metric_specification] and
385
374
  policy_params[:target_tracking_configuration][:predefined_metric_specification][:predefined_metric_type] == "ALBRequestCountPerTarget"
@@ -489,6 +478,11 @@ module MU
489
478
  toplevel_required = []
490
479
 
491
480
  schema = {
481
+ "role_strip_path" => {
482
+ "type" => "boolean",
483
+ "default" => false,
484
+ "description" => "Normally we namespace IAM roles with a +path+ set to match our +deploy_id+; this disables that behavior. Temporary workaround for a bug in EKS/IAM integration."
485
+ },
492
486
  "notifications" => {
493
487
  "type" => "object",
494
488
  "description" => "Send notifications to an SNS topic for basic AutoScaling events",
@@ -845,8 +839,11 @@ module MU
845
839
  ok = false
846
840
  end
847
841
  else
842
+ s3_objs = ['arn:'+(MU::Cloud::AWS.isGovCloud?(pool['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU.adminBucketName+'/Mu_CA.pem']
843
+
848
844
  role = {
849
845
  "name" => pool["name"],
846
+ "strip_path" => pool["role_strip_path"],
850
847
  "can_assume" => [
851
848
  {
852
849
  "entity_id" => "ec2.amazonaws.com",
@@ -857,19 +854,15 @@ module MU
857
854
  {
858
855
  "name" => "MuSecrets",
859
856
  "permissions" => ["s3:GetObject"],
860
- "targets" => [
861
- {
862
- "identifier" => 'arn:'+(MU::Cloud::AWS.isGovCloud?(pool['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU.adminBucketName+'/Mu_CA.pem'
863
- }
864
- ]
857
+ "targets" => s3_objs.map { |f| { "identifier" => f } }
865
858
  }
866
859
  ]
867
860
  }
868
861
  if launch['iam_policies']
869
862
  role['iam_policies'] = launch['iam_policies'].dup
870
863
  end
871
- if pool['canned_policies']
872
- role['import'] = pool['canned_policies'].dup
864
+ if pool['canned_iam_policies']
865
+ role['import'] = pool['canned_iam_policies'].dup
873
866
  end
874
867
  if pool['iam_role']
875
868
  # XXX maybe break this down into policies and add those?
@@ -1154,6 +1147,14 @@ module MU
1154
1147
 
1155
1148
  storage.concat(MU::Cloud::AWS::Server.ephemeral_mappings)
1156
1149
 
1150
+ if @config['basis']['launch_config']['generate_iam_role']
1151
+ role = @deploy.findLitterMate(name: @config['name'], type: "roles")
1152
+ 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|
1153
+ 'arn:'+(MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU.adminBucketName+'/'+file
1154
+ }
1155
+ role.cloudobj.injectPolicyTargets("MuSecrets", s3_objs)
1156
+ end
1157
+
1157
1158
  if !oldlaunch.nil?
1158
1159
  olduserdata = Base64.decode64(oldlaunch.user_data)
1159
1160
  if userdata != olduserdata or
@@ -1237,11 +1238,6 @@ module MU
1237
1238
 
1238
1239
  if @config['basis']['launch_config']['generate_iam_role']
1239
1240
  role = @deploy.findLitterMate(name: @config['name'], type: "roles")
1240
- # XXX are these the right patterns for a pool, or did we need wildcards?
1241
- 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|
1242
- 'arn:'+(MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws")+':s3:::'+MU.adminBucketName+'/'+file
1243
- }
1244
- role.cloudobj.injectPolicyTargets("MuSecrets", s3_objs)
1245
1241
 
1246
1242
  @config['iam_role'] = role.mu_name
1247
1243
 
@@ -108,8 +108,8 @@ if ping -c 5 8.8.8.8 > /dev/null; then
108
108
  service sshd start
109
109
  fi
110
110
  fi
111
- fi
112
111
  <% end %>
112
+ fi
113
113
  else
114
114
  /bin/logger "***** Unable to verify internet connectivity, skipping package updates from userdata"
115
115
  touch /.mu-installer-ran-updates
@@ -386,8 +386,17 @@ module MU
386
386
  }
387
387
 
388
388
  MU.log "Creating route for #{route['destination_network']} through NAT gatway #{gateway['id']}", details: route_config
389
+ nat_retries = 0
389
390
  begin
390
391
  resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(route_config)
392
+ rescue Aws::EC2::Errors::InvalidNatGatewayIDNotFound => e
393
+ if nat_retries < 5
394
+ nat_retries += 1
395
+ sleep 10
396
+ retry
397
+ else
398
+ raise e
399
+ end
391
400
  rescue Aws::EC2::Errors::RouteAlreadyExists => e
392
401
  MU.log "Attempt to create duplicate route to #{route['destination_network']} for #{gateway['id']} in #{rtb['route_table_id']}", MU::WARN
393
402
  end
@@ -623,6 +623,8 @@ next if !create
623
623
  az,
624
624
  cloud_id
625
625
  )
626
+ rescue ::OpenSSL::SSL::SSLError => e
627
+ MU.log "Got #{e.message} looking for instance #{cloud_id} in project #{flags["project"]} (#{az}). Usually this means we've tried to query a non-functional region.", MU::DEBUG
626
628
  rescue ::Google::Apis::ClientError => e
627
629
  raise e if !e.message.match(/^notFound: /)
628
630
  end
data/modules/mu/config.rb CHANGED
@@ -1214,7 +1214,7 @@ module MU
1214
1214
  "type" => "array",
1215
1215
  "minItems" => 1,
1216
1216
  "items" => {
1217
- "description" => "Tags to apply to this resource. Will apply at the cloud provider level and in Chef, where applicable.",
1217
+ "description" => "Tags to apply to this resource. Will apply at the cloud provider level and in node groomers, where applicable.",
1218
1218
  "type" => "object",
1219
1219
  "title" => "tags",
1220
1220
  "required" => ["key", "value"],
@@ -1500,7 +1500,7 @@ module MU
1500
1500
  }
1501
1501
  end
1502
1502
  if conf_chunk.nil? and schema_chunk["default"] != nil
1503
- return schema_chunk["default"]
1503
+ return schema_chunk["default"].dup
1504
1504
  end
1505
1505
  end
1506
1506
  return conf_chunk
@@ -1567,7 +1567,7 @@ module MU
1567
1567
  def self.check_vault_refs(server)
1568
1568
  ok = true
1569
1569
  server['vault_access'] = [] if server['vault_access'].nil?
1570
- server['groomer'] ||= "Chef"
1570
+ server['groomer'] ||= self.defaultGroomer
1571
1571
  groomclass = MU::Groomer.loadGroomer(server['groomer'])
1572
1572
 
1573
1573
  begin
@@ -41,7 +41,7 @@ module MU
41
41
  "properties" => {
42
42
  "version" => {
43
43
  "type" => "string",
44
- "default" => "1.10",
44
+ "default" => "1.11",
45
45
  "description" => "Version of Kubernetes control plane to deploy",
46
46
  },
47
47
  "max_pods" => {
@@ -78,6 +78,10 @@ module MU
78
78
  "type" => "boolean",
79
79
  "default" => false
80
80
  },
81
+ "comment" => {
82
+ "type" => "string",
83
+ "description" => "String description of this firewall rule, where supported"
84
+ },
81
85
  "hosts" => {
82
86
  "type" => "array",
83
87
  "items" => MU::Config::CIDR_PRIMITIVE
@@ -45,6 +45,32 @@ module MU
45
45
  }
46
46
  end
47
47
 
48
+ # Chunk of schema to reference an account/project, here to be embedded
49
+ # into the schemas of other resources.
50
+ def self.reference
51
+ {
52
+ "type" => "object",
53
+ "description" => "An IAM role to associate with this resource",
54
+ "minProperties" => 1,
55
+ "additionalProperties" => false,
56
+ "properties" => {
57
+ "id" => {
58
+ "type" => "string",
59
+ "description" => "Discover this role by looking for this cloud provider identifier, such as an AWS ARN"
60
+ },
61
+ "name" => {
62
+ "type" => "string",
63
+ "description" => "Discover this role by Mu-internal name; typically the shorthand 'name' field of a Role object declared elsewhere in the deploy, or in another deploy that's being referenced with 'deploy_id'."
64
+ },
65
+ "cloud" => MU::Config.cloud_primitive,
66
+ "deploy_id" => {
67
+ "type" => "string",
68
+ "description" => "Search for this Role in an existing Mu deploy by Mu deploy id (e.g. DEMO-DEV-2014111400-NG)."
69
+ }
70
+ }
71
+ }
72
+ end
73
+
48
74
  # A generic, cloud-neutral descriptor for a policy that grants or denies
49
75
  # permissions to some entity over some other entity.
50
76
  # @param subobjects [Boolean]: Whether the returned schema should include a +path+ parameter
@@ -89,6 +115,9 @@ module MU
89
115
  "identifier" => {
90
116
  "type" => "string",
91
117
  "description" => "Either the name of a sibling Mu resource in this stack (used in conjunction with +entity_type+), or the full cloud identifier for a resource, such as an ARN in Amazon Web Services."
118
+ },
119
+ "path" => {
120
+ "type" => "string",
92
121
  }
93
122
  }
94
123
  }