cloud-mu 2.0.4 → 2.1.0beta

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 (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
  }