cloud-mu 3.1.1 → 3.1.2beta2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e410b5b2d1b9bb3bb28993cda8852ba50bc0d4a32218a64226af3e66ae86465a
4
- data.tar.gz: ec28f00264ebea17f917428b12b44f2eaf2361711c1ee8ab0b8db6ac94d4bad8
3
+ metadata.gz: 5df44eebc605db5e8965c18414c18f1802a565df95014216609799ff912311d7
4
+ data.tar.gz: 7978b64d27f1fd467c0215ad8b7c6246f4bb4cbba4eeb1f834a35dd4adf08aae
5
5
  SHA512:
6
- metadata.gz: 5232f7dc31462aa58f307ded9bb7f46d7dd63a7b373ba88d4546620b8531ae5e71167d8d86d29a49638f159ea21dd5fd2e88a7bb7529c8df350e8627ca29fd71
7
- data.tar.gz: '09b513e485274453b5a3242e9747c9bc0cd41e06ea9a6744ffe4ab7cab38b43845c8ca124159d0ab418f39441d894f626b48505992de913615a1fb2a8c4b77cf'
6
+ metadata.gz: ad79d77971ecf24de81294e302f5f0284529da90468e6793be7334d08a59248a026a5b0b36552fe7fb54f80c604f539da0fe2a0f3f2b130a05df9d5993f2808a
7
+ data.tar.gz: df69d04d5c0f7799b52e60955ea3d1d1a21f63d509a44e369824f011f88a159a425dfdf9d8ebb02975d085b3ba6c3f604937d292aa1c9330ecc43ffa5b8b6c40
data/Berksfile.lock ADDED
@@ -0,0 +1,179 @@
1
+ DEPENDENCIES
2
+ awscli
3
+ chocolatey
4
+ firewall
5
+ path: cookbooks/firewall
6
+ mu-activedirectory
7
+ mu-firewall
8
+ mu-glusterfs
9
+ mu-master
10
+ mu-mongo
11
+ mu-nagios
12
+ git: https://github.com/cloudamatic/mu-nagios.git
13
+ revision: c1e3f6155d5ab9952c8403693b118664f8d50973
14
+ mu-openvpn
15
+ mu-splunk
16
+ mu-tools
17
+ mu-utility
18
+
19
+ GRAPH
20
+ apache2 (5.2.1)
21
+ apt (7.2.0)
22
+ awscli (1.1.2)
23
+ python (~> 1.4)
24
+ bind (2.2.1)
25
+ bind9-ng (0.1.0)
26
+ build-essential (8.2.1)
27
+ mingw (>= 1.1)
28
+ seven_zip (>= 0.0.0)
29
+ chef-sugar (5.1.8)
30
+ chef-vault (3.1.2)
31
+ chocolatey (2.0.1)
32
+ consul (2.3.0)
33
+ build-essential (>= 0.0.0)
34
+ firewall (~> 2.0)
35
+ golang (>= 0.0.0)
36
+ nssm (>= 0.0.0)
37
+ poise (~> 2.2)
38
+ poise-archive (~> 1.3)
39
+ poise-service (~> 1.4)
40
+ consul-cluster (2.0.0)
41
+ consul (~> 2.1)
42
+ ssl_certificate (~> 1.11)
43
+ cpan (0.1.0)
44
+ database (6.1.1)
45
+ postgresql (>= 1.0.0)
46
+ firewall (2.7.1)
47
+ golang (1.7.0)
48
+ hashicorp-vault (2.5.0)
49
+ build-essential (>= 0.0.0)
50
+ golang (~> 1.7)
51
+ poise (~> 2.6)
52
+ poise-service (~> 1.1)
53
+ rubyzip (~> 1.0)
54
+ homebrew (5.0.8)
55
+ hostsfile (3.0.1)
56
+ java (2.2.1)
57
+ homebrew (>= 0.0.0)
58
+ windows (>= 0.0.0)
59
+ mingw (2.1.0)
60
+ seven_zip (>= 0.0.0)
61
+ mongodb (0.16.2)
62
+ apt (>= 1.8.2)
63
+ python (>= 0.0.0)
64
+ runit (>= 1.5.0)
65
+ yum (>= 3.0)
66
+ mu-activedirectory (0.2.0)
67
+ chef-vault (~> 3.1.1)
68
+ windows (~> 5.1.1)
69
+ yum-epel (~> 3.2.0)
70
+ mu-firewall (0.1.2)
71
+ firewall (~> 2.7.1)
72
+ mu-glusterfs (0.1.0)
73
+ mu-firewall (>= 0.0.0)
74
+ yum (~> 5.1.0)
75
+ mu-master (0.9.6)
76
+ apache2 (< 6.0.0)
77
+ bind (~> 2.2.0)
78
+ bind9-ng (~> 0.1.0)
79
+ chef-sugar (>= 0.0.0)
80
+ chef-vault (~> 3.1.1)
81
+ consul-cluster (~> 2.0.0)
82
+ hostsfile (~> 3.0.1)
83
+ mu-activedirectory (>= 0.0.0)
84
+ mu-firewall (>= 0.0.0)
85
+ mu-nagios (>= 0.0.0)
86
+ mu-tools (>= 0.0.0)
87
+ mu-utility (>= 0.0.0)
88
+ nrpe (~> 2.0.3)
89
+ postfix (~> 5.3.1)
90
+ s3fs (>= 0.0.0)
91
+ vault-cluster (~> 2.1.0)
92
+ mu-mongo (0.5.0)
93
+ chef-vault (~> 3.1.1)
94
+ mongodb (~> 0.16.2)
95
+ mu-nagios (8.2.2)
96
+ apache2 (< 6.0.0)
97
+ build-essential (>= 5.0)
98
+ nginx (>= 7.0)
99
+ nrpe (>= 0.0.0)
100
+ php (>= 0.0.0)
101
+ php-fpm (>= 0.7.9)
102
+ yum-epel (>= 0.0.0)
103
+ zap (>= 0.6.0)
104
+ mu-openvpn (0.1.0)
105
+ chef-vault (~> 3.1.1)
106
+ mu-firewall (>= 0.0.0)
107
+ mu-utility (>= 0.0.0)
108
+ mu-splunk (1.3.0)
109
+ chef-vault (>= 1.0.4)
110
+ mu-tools (1.1.0)
111
+ chef-vault (~> 3.1.1)
112
+ chocolatey (>= 0.0.0)
113
+ database (~> 6.1.1)
114
+ firewall (>= 0.0.0)
115
+ java (~> 2.2.0)
116
+ mu-activedirectory (>= 0.0.0)
117
+ mu-firewall (>= 0.0.0)
118
+ mu-nagios (>= 0.0.0)
119
+ mu-splunk (>= 0.0.0)
120
+ mu-utility (>= 0.0.0)
121
+ oracle-instantclient (~> 1.1.0)
122
+ poise-python (~> 1.7.0)
123
+ postgresql (~> 7.1.0)
124
+ selinux (~> 3.0.0)
125
+ windows (~> 5.1.1)
126
+ yum-epel (~> 3.2.0)
127
+ mu-utility (0.6.0)
128
+ mu-firewall (>= 0.0.0)
129
+ windows (~> 5.1.1)
130
+ nginx (10.0.2)
131
+ ohai (~> 5.2)
132
+ nrpe (2.0.5)
133
+ build-essential (>= 0.0.0)
134
+ yum-epel (>= 0.0.0)
135
+ nssm (4.0.1)
136
+ windows (>= 0.0.0)
137
+ ohai (5.3.0)
138
+ oracle-instantclient (1.1.0)
139
+ build-essential (>= 0.0.0)
140
+ cpan (>= 0.0.0)
141
+ php (>= 0.0.0)
142
+ packagecloud (1.0.1)
143
+ php (7.0.0)
144
+ yum-epel (>= 0.0.0)
145
+ php-fpm (0.8.0)
146
+ poise (2.8.2)
147
+ poise-archive (1.5.0)
148
+ poise (~> 2.6)
149
+ poise-languages (2.1.2)
150
+ poise (~> 2.5)
151
+ poise-archive (~> 1.0)
152
+ poise-python (1.7.0)
153
+ poise (~> 2.7)
154
+ poise-languages (~> 2.0)
155
+ poise-service (1.5.2)
156
+ poise (~> 2.0)
157
+ postfix (5.3.1)
158
+ postgresql (7.1.5)
159
+ python (1.4.6)
160
+ build-essential (>= 0.0.0)
161
+ yum-epel (>= 0.0.0)
162
+ rubyzip (1.3.1)
163
+ poise (~> 2.2)
164
+ runit (5.1.2)
165
+ packagecloud (>= 0.0.0)
166
+ yum-epel (>= 0.0.0)
167
+ s3fs (3.0.1)
168
+ selinux (3.0.1)
169
+ seven_zip (3.1.2)
170
+ windows (>= 0.0.0)
171
+ ssl_certificate (1.12.0)
172
+ vault-cluster (2.1.0)
173
+ consul-cluster (~> 2.0)
174
+ hashicorp-vault (~> 2.1)
175
+ ssl_certificate (~> 1.11)
176
+ windows (5.1.6)
177
+ yum (5.1.0)
178
+ yum-epel (3.2.0)
179
+ zap (1.2.0)
data/bin/mu-adopt CHANGED
@@ -47,7 +47,7 @@ $opt = Optimist::options do
47
47
  opt :savedeploys, "Generate actual deployment metadata in #{MU.dataDir}/deployments, as though the resources we found were created with mu-deploy. If we are generating more than one configuration, and a resource needs to reference another resource (e.g. to declare a VPC in which to reside), this will allow us to reference them as virtual resource, rather than by raw cloud identifier.", :required => false, :type => :boolean, :default => false
48
48
  opt :diff, "List the differences between what we find and an existing, saved deploy from a previous run, if one exists.", :required => false, :type => :boolean
49
49
  opt :grouping, "Methods for grouping found resources into separate Baskets.\n\n"+MU::Adoption::GROUPMODES.keys.map { |g| "* "+g.to_s+": "+MU::Adoption::GROUPMODES[g] }.join("\n")+"\n\n", :required => false, :type => :string, :default => "logical"
50
- opt :habitats, "Limit scope of research searching to the named accounts/projects/subscriptions, instead of search all habitats visible to our credentials.", :required => false, :type => :strings
50
+ opt :habitats, "Limit scope of searches to the named accounts/projects/subscriptions, instead of search all habitats visible to our credentials.", :required => false, :type => :strings
51
51
  end
52
52
 
53
53
  ok = true
@@ -0,0 +1,46 @@
1
+ #!/usr/local/ruby-current/bin/ruby
2
+ # Copyright:: Copyright (c) 2014 eGlobalTech, Inc., all rights reserved
3
+ #
4
+ # Licensed under the BSD-3 license (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License in the root of the project or at
7
+ #
8
+ # http://egt-labs.com/mu/LICENSE.html
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'rubygems'
17
+ require 'bundler/setup'
18
+ require 'json'
19
+ require 'erb'
20
+ require 'optimist'
21
+ require 'json-schema'
22
+ require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
23
+ require 'mu'
24
+
25
+ puts $stdout.class.name
26
+ exit
27
+
28
+ #pp MU::Cloud::Azure.listRegions
29
+ #pp MU::Cloud::Azure::Habitat.testcalls
30
+ #pp MU::Cloud::Azure::VPC.find(cloud_id: MU::Cloud::Azure::Id.new(resource_group: "mu", name: "mu-vnet"))
31
+ #pp MU::Cloud::Azure.authorization.role_assignments.list_for_resource_group("AKS-DEV-2019062015-KA-EASTUS")
32
+ #pp MU::Cloud::Azure::Role.find(role_name: "Azure Kubernetes Service Cluster Admin Role")
33
+ #puts MU::Cloud::Azure.default_subscription
34
+ #pp MU::Cloud::Azure.fetchPublicIP("MYVPC-DEV-2019061911-XI-EASTUS", "ip-addr-thingy")
35
+ #pp MU::Cloud::Azure.ensureProvider("egtazure", "Microsoft.ContainerService", force: true)
36
+ pp MU::Cloud::Azure::Server.find(cloud_id: "mu")
37
+ exit
38
+ pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/6")
39
+ pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/7")
40
+ pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/8")
41
+ pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/7")
42
+ pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/6")
43
+ pp MU::Cloud::Azure::Server.fetchImage("Debian/debian-10/10")
44
+ pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2012-R2-Datacenter")
45
+ pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2016-Datacenter")
46
+ pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2019-Datacenter")
data/bin/mu-cleanup CHANGED
@@ -45,6 +45,7 @@ Usage:
45
45
  opt :verbose, "Display debugging output.", :require => false, :default => false, :type => :boolean
46
46
  opt :credentials, "Restrict to operating on a subset of available credential sets, instead of all that we know about.", :require => false, :default => credentials, :type => :strings
47
47
  opt :regions, "Restrict to operating on a subset of available regions, instead of all that we know about.", :require => false, :type => :strings
48
+ opt :habitats, "Restrict to operating on the named accounts/projects/subscriptions, instead of search all habitats visible to our credentials.", :required => false, :type => :strings
48
49
  opt :quiet, "Display minimal output.", :require => false, :default => false, :type => :boolean
49
50
  end
50
51
  verbosity = MU::Logger::NORMAL
@@ -77,5 +78,6 @@ MU::Cleanup.run(
77
78
  skipcloud: $opts[:skipcloud],
78
79
  ignoremaster: $opts[:ignoremaster],
79
80
  credsets: $opts[:credentials],
80
- regions: $opts[:regions]
81
+ regions: $opts[:regions],
82
+ habitats: $opts[:habitats]
81
83
  )
data/bin/mu-configure CHANGED
@@ -1469,3 +1469,10 @@ if !$NOOP
1469
1469
  puts "source #{HOMEDIR}/.bashrc".bold
1470
1470
  end
1471
1471
  end
1472
+
1473
+ if $IN_GEM
1474
+ ansible_exec_path = MU::Groomer::Ansible.ansibleExecDir
1475
+ if !ansible_exec_path or ansible_exec_path.empty?
1476
+ puts "No Ansible executables found. Will not be able to groom servers!".red
1477
+ end
1478
+ end
data/cloud-mu.gemspec CHANGED
@@ -17,8 +17,8 @@ end
17
17
 
18
18
  Gem::Specification.new do |s|
19
19
  s.name = 'cloud-mu'
20
- s.version = '3.1.1'
21
- s.date = '2020-01-11'
20
+ s.version = '3.1.2beta2'
21
+ s.date = '2020-01-27'
22
22
  s.require_paths = ['modules']
23
23
  s.required_ruby_version = '>= 2.4'
24
24
  s.summary = "The eGTLabs Mu toolkit for unified cloud deployments"
@@ -54,11 +54,12 @@ EOF
54
54
  s.add_runtime_dependency 'net-ssh', "~> 4.2"
55
55
  s.add_runtime_dependency 'net-ssh-multi', '~> 1.2', '>= 1.2.1'
56
56
  s.add_runtime_dependency 'googleauth', "~> 0.6"
57
- s.add_runtime_dependency 'google-api-client', "~> 0.30.8"
57
+ s.add_runtime_dependency 'google-api-client', "~> 0.36.4"
58
58
  s.add_runtime_dependency 'rubocop', '~> 0.58'
59
59
  s.add_runtime_dependency 'addressable', '~> 2.5'
60
60
  s.add_runtime_dependency 'slack-notifier', "~> 2.3"
61
61
  s.add_runtime_dependency 'azure_sdk', "~> 0.37"
62
62
  s.add_runtime_dependency 'rack', "~> 2.0"
63
63
  s.add_runtime_dependency 'thin', "~> 1.7"
64
+ s.add_runtime_dependency 'rubyzip', "~> 2.0"
64
65
  end
@@ -0,0 +1,33 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
33
+ -----END CERTIFICATE-----
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -40,8 +40,10 @@ module MU
40
40
  # @param verbosity [Integer]: Debug level for MU.log output
41
41
  # @param web [Boolean]: Generate web-friendly output.
42
42
  # @param ignoremaster [Boolean]: Ignore the tags indicating the originating MU master server when deleting.
43
+ # @param regions [Array<String>]: Operate only on these regions
44
+ # @param habitats [Array<String>]: Operate only on these accounts/projects/subscriptions
43
45
  # @return [void]
44
- def self.run(deploy_id, noop: false, skipsnapshots: false, onlycloud: false, verbosity: MU::Logger::NORMAL, web: false, ignoremaster: false, skipcloud: false, mommacat: nil, credsets: nil, regions: nil)
46
+ def self.run(deploy_id, noop: false, skipsnapshots: false, onlycloud: false, verbosity: MU::Logger::NORMAL, web: false, ignoremaster: false, skipcloud: false, mommacat: nil, credsets: nil, regions: nil, habitats: nil)
45
47
  MU.setLogging(verbosity, web)
46
48
  @noop = noop
47
49
  @skipsnapshots = skipsnapshots
@@ -92,8 +94,8 @@ module MU
92
94
  if !@skipcloud
93
95
  creds = {}
94
96
  MU::Cloud.availableClouds.each { |cloud|
97
+ cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
95
98
  if $MU_CFG[cloud.downcase] and $MU_CFG[cloud.downcase].size > 0
96
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
97
99
  creds[cloud] ||= {}
98
100
  cloudclass.listCredentials.each { |credset|
99
101
  next if credsets and credsets.size > 0 and !credsets.include?(credset)
@@ -101,6 +103,11 @@ module MU
101
103
  MU.log "Will scan #{cloud} with credentials #{credset}"
102
104
  creds[cloud][credset] = cloudclass.listRegions(credentials: credset)
103
105
  }
106
+ else
107
+ if cloudclass.hosted?
108
+ creds[cloud] ||= {}
109
+ creds[cloud]["#default"] = cloudclass.listRegions
110
+ end
104
111
  end
105
112
  }
106
113
 
@@ -139,7 +146,9 @@ module MU
139
146
  Thread.abort_on_exception = false
140
147
  MU.setVar("curRegion", r)
141
148
  projects = []
142
- if $MU_CFG[cloud.downcase][credset]["project"]
149
+ if $MU_CFG and $MU_CFG[cloud.downcase] and
150
+ $MU_CFG[cloud.downcase][credset] and
151
+ $MU_CFG[cloud.downcase][credset]["project"]
143
152
  # XXX GCP credential schema needs an array for projects
144
153
  projects << $MU_CFG[cloud.downcase][credset]["project"]
145
154
  end
@@ -160,6 +169,9 @@ module MU
160
169
  projectthreads = []
161
170
  projects.each { |project|
162
171
  next if !habitatclass.isLive?(project, credset)
172
+ if habitats and !habitats.empty? and project != ""
173
+ next if !habitats.include?(project)
174
+ end
163
175
 
164
176
  projectthreads << Thread.new {
165
177
  MU.dupGlobals(parent_thread_id)
@@ -92,6 +92,12 @@ module MU
92
92
  current = cloud_desc
93
93
 
94
94
  if @config['policies']
95
+ @config['policies'].each { |pol|
96
+ pol['grant_to'] ||= [
97
+ { "id" => "*" }
98
+ ]
99
+ }
100
+
95
101
  policy_docs = MU::Cloud::AWS::Role.genPolicyDocument(@config['policies'], deploy_obj: @deploy)
96
102
  policy_docs.each { |doc|
97
103
  MU.log "Applying S3 bucket policy #{doc.keys.first} to bucket #{@cloud_id}", MU::NOTICE, details: doc.values.first
@@ -35,6 +35,8 @@ module MU
35
35
 
36
36
  # TODO guard this crap so we don't touch it if there are no changes
37
37
  @config['methods'].each { |m|
38
+ m["auth"] ||= m["iam_role"] ? "AWS_IAM" : "NONE"
39
+
38
40
  method_arn = "arn:#{MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws"}:execute-api:#{@config["region"]}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:#{@cloud_id}/*/#{m['type']}/#{m['path']}"
39
41
 
40
42
  resp = MU::Cloud::AWS.apig(region: @config['region'], credentials: @config['credentials']).get_resources(
@@ -495,6 +495,37 @@ module MU
495
495
  rescue Aws::EC2::Errors::DependencyViolation, Aws::EC2::Errors::InvalidGroupInUse
496
496
  if retries < 10
497
497
  MU.log "EC2 Security Group #{sg.group_name} is still in use, waiting...", MU::NOTICE
498
+ # try to get out from under loose network interfaces with which
499
+ # we're associated
500
+ if sg.vpc_id
501
+ # get the default SG for this VPC
502
+ default_resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_security_groups(
503
+ filters: [
504
+ { name: "group-name", values: ["default"] },
505
+ { name: "vpc-id", values: [sg.vpc_id] }
506
+ ]
507
+ ).security_groups
508
+ if default_resp and default_resp.size == 1
509
+ default_sg = default_resp.first.group_id
510
+ eni_resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_network_interfaces(
511
+ filters: [ {name: "group-id", values: [sg.group_id]} ]
512
+ )
513
+ if eni_resp and eni_resp.data and
514
+ eni_resp.data.network_interfaces
515
+ eni_resp.data.network_interfaces.each { |iface|
516
+ iface_groups = iface.groups.map { |sg| sg.group_id }
517
+ iface_groups.delete(sg.group_id)
518
+ iface_groups << default_sg if iface_groups.empty?
519
+ MU.log "Attempting to remove #{sg.group_id} from ENI #{iface.network_interface_id}"
520
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).modify_network_interface_attribute(
521
+ network_interface_id: iface.network_interface_id,
522
+ groups: iface_groups
523
+ )
524
+ }
525
+ end
526
+ end
527
+ end
528
+
498
529
  sleep 10
499
530
  retries = retries + 1
500
531
  retry
@@ -97,8 +97,11 @@ module MU
97
97
  sgs << sg.cloud_id if sg and sg.cloud_id
98
98
  }
99
99
  end
100
+ if !@vpc
101
+ raise MuError, "Function #{@config['name']} had a VPC configured, but none was loaded"
102
+ end
100
103
  lambda_properties[:vpc_config] = {
101
- :subnet_ids => @config['vpc']['subnets'].map { |s| s["subnet_id"] },
104
+ :subnet_ids => @vpc.subnets.map { |s| s.cloud_id },
102
105
  :security_group_ids => sgs
103
106
  }
104
107
  end
@@ -407,8 +410,48 @@ MU.log shortname, MU::NOTICE, details: function.configuration.role
407
410
  # @param config [MU::Config]: The calling MU::Config object
408
411
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
409
412
  def self.schema(config)
410
- toplevel_required = []
413
+ toplevel_required = ["runtime"]
411
414
  schema = {
415
+ "triggers" => {
416
+ "type" => "array",
417
+ "items" => {
418
+ "type" => "object",
419
+ "description" => "Trigger for lambda function",
420
+ "required" => ["service"],
421
+ "properties" => {
422
+ "service" => {
423
+ "type" => "string",
424
+ "enum" => %w{apigateway events s3 sns sqs dynamodb kinesis ses cognito alexa iot},
425
+ "description" => "The name of the AWS service that will trigger this function"
426
+ },
427
+ "name" => {
428
+ "type" => "string",
429
+ "description" => "The name of the API Gateway, Cloudwatch Event, or other event trigger object"
430
+ }
431
+ }
432
+ }
433
+ },
434
+ "runtime" => {
435
+ "type" => "string",
436
+ "enum" => %w{nodejs nodejs4.3 nodejs6.10 nodejs8.10 nodejs10.x nodejs12.x java8 java11 python2.7 python3.6 python3.7 python3.8 dotnetcore1.0 dotnetcore2.0 dotnetcore2.1 nodejs4.3-edge go1.x ruby2.5 provided},
437
+ },
438
+ "code" => {
439
+ "type" => "object",
440
+ "properties" => {
441
+ "s3_bucket" => {
442
+ "type" => "string",
443
+ "description" => "An S3 bucket where the deployment package can be found. Must be used in conjunction with s3_key."
444
+ },
445
+ "s3_key" => {
446
+ "type" => "string",
447
+ "description" => "Key in s3_bucket where the deployment package can be found. Must be used in conjunction with s3_bucket."
448
+ },
449
+ "s3_object_version" => {
450
+ "type" => "string",
451
+ "description" => "Specify an S3 object version for the deployment package, instead of the current default"
452
+ },
453
+ }
454
+ },
412
455
  "iam_role" => {
413
456
  "type" => "string",
414
457
  "description" => "Deprecated, +role+ is now preferred. The name of an IAM role for our Lambda function to assume. Can refer to an existing IAM role, or a sibling 'role' resource in Mu. If not specified, will create a default role with permissions listed in `permissions` (and if none are listed, we will set `AWSLambdaBasicExecutionRole`)."
@@ -598,6 +598,7 @@ module MU
598
598
  # @param targetgroups [Array<String>] The target group(s) of which this node should be made a member. Not applicable to classic LoadBalancers. If not supplied, the node will be registered to all available target groups on this LoadBalancer.
599
599
  def registerNode(instance_id, targetgroups: nil)
600
600
  if @config['classic'] or !@config.has_key?("classic")
601
+ MU.log "Registering #{instance_id} to ELB #{@cloud_id}"
601
602
  MU::Cloud::AWS.elb(region: @config['region'], credentials: @config['credentials']).register_instances_with_load_balancer(
602
603
  load_balancer_name: @cloud_id,
603
604
  instances: [
@@ -608,11 +609,12 @@ module MU
608
609
  if targetgroups.nil? or !targetgroups.is_a?(Array) or targetgroups.size == 0
609
610
  if @targetgroups.nil?
610
611
  cloud_desc
611
- return
612
+ return if @targetgroups.nil?
612
613
  end
613
614
  targetgroups = @targetgroups.keys
614
615
  end
615
616
  targetgroups.each { |tg|
617
+ MU.log "Registering #{instance_id} to Target Group #{tg}"
616
618
  MU::Cloud::AWS.elb2(region: @config['region'], credentials: @config['credentials']).register_targets(
617
619
  target_group_arn: @targetgroups[tg].target_group_arn,
618
620
  targets: [
@@ -1126,6 +1126,7 @@ end
1126
1126
  if policy["grant_to"] # XXX factor this with target, they're too similar
1127
1127
  statement["Principal"] ||= []
1128
1128
  policy["grant_to"].each { |grantee|
1129
+ grantee["identifier"] ||= grantee["id"]
1129
1130
  if grantee["type"] and deploy_obj
1130
1131
  sibling = deploy_obj.findLitterMate(
1131
1132
  name: grantee["identifier"],
@@ -1147,6 +1148,7 @@ end
1147
1148
  end
1148
1149
  if policy["targets"]
1149
1150
  policy["targets"].each { |target|
1151
+ target["identifier"] ||= target["id"]
1150
1152
  if target["type"] and deploy_obj
1151
1153
  sibling = deploy_obj.findLitterMate(
1152
1154
  name: target["identifier"],
@@ -1154,7 +1156,7 @@ end
1154
1156
  )
1155
1157
  if sibling
1156
1158
  id = sibling.cloudobj.arn
1157
- id.sub!(/:([^:]+)$/, ":"+target["path"]) if target["path"]
1159
+ id.sub!(/:([^:]+)$/, ":"+'\1'+target["path"]) if target["path"]
1158
1160
  statement["Resource"] << id
1159
1161
  if id.match(/:log-group:/)
1160
1162
  stream_id = id.sub(/:([^:]+)$/, ":log-stream:*")
@@ -756,7 +756,7 @@ module MU
756
756
 
757
757
  nat_ssh_key, nat_ssh_user, nat_ssh_host, canonical_ip, ssh_user, ssh_key_name = getSSHConfig
758
758
  if subnet.private? and !nat_ssh_host and !MU::Cloud::AWS::VPC.haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
759
- raise MuError, "#{node} is in a private subnet (#{subnet}), but has no NAT host configured, and I have no other route to it"
759
+ raise MuError, "#{node} is in a private subnet (#{subnet}), but has no bastion host configured, and I have no other route to it"
760
760
  end
761
761
 
762
762
  # If we've asked for additional subnets (and this @config is not a
@@ -764,7 +764,7 @@ module MU
764
764
  # extra interfaces to accomodate.
765
765
  if !@config['vpc']['subnets'].nil? and @config['basis'].nil?
766
766
  device_index = 1
767
- @vpc.subnets { |s|
767
+ @vpc.subnets.each { |s|
768
768
  subnet_id = s.cloud_id
769
769
  MU.log "Adding network interface on subnet #{subnet_id} for #{node}"
770
770
  iface = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_network_interface(subnet_id: subnet_id).network_interface
@@ -942,6 +942,8 @@ module MU
942
942
  # we're done.
943
943
  if MU.inGem?
944
944
  MU.log "Deploying from a gem, not grooming"
945
+ MU::MommaCat.unlock(instance.instance_id+"-orchestrate")
946
+ MU::MommaCat.unlock(instance.instance_id+"-groom")
945
947
 
946
948
  return true
947
949
  elsif @groomer.haveBootstrapped?
@@ -2233,8 +2235,12 @@ module MU
2233
2235
 
2234
2236
  if ips.size > 0 and !onlycloud
2235
2237
  known_hosts_files = [Etc.getpwuid(Process.uid).dir+"/.ssh/known_hosts"]
2236
- if Etc.getpwuid(Process.uid).name == "root"
2237
- known_hosts_files << Etc.getpwnam("nagios").dir+"/.ssh/known_hosts"
2238
+ if Etc.getpwuid(Process.uid).name == "root" and !MU.inGem?
2239
+ begin
2240
+ known_hosts_files << Etc.getpwnam("nagios").dir+"/.ssh/known_hosts"
2241
+ rescue ArgumentError
2242
+ # we're in a non-nagios environment and that's ok
2243
+ end
2238
2244
  end
2239
2245
  known_hosts_files.each { |known_hosts|
2240
2246
  next if !File.exist?(known_hosts)
@@ -1409,7 +1409,7 @@ module MU
1409
1409
  found = false
1410
1410
  @deploy.deployment["loadbalancers"].each_pair { |lb_name, deployed_lb|
1411
1411
  if lb_name == lb['concurrent_load_balancer']
1412
- lbs << deployed_lb["awsname"]
1412
+ lbs << deployed_lb["awsname"] # XXX check for classic
1413
1413
  if deployed_lb.has_key?("targetgroups")
1414
1414
  deployed_lb["targetgroups"].each_pair { |tg_name, tg_arn|
1415
1415
  tg_arns << tg_arn
@@ -1423,8 +1423,9 @@ module MU
1423
1423
  }
1424
1424
  if tg_arns.size > 0
1425
1425
  asg_options[:target_group_arns] = tg_arns
1426
- else
1427
- asg_options[:load_balancer_names] = lbs
1426
+ end
1427
+ if lbs.size > 0
1428
+ # asg_options[:load_balancer_names] = lbs
1428
1429
  end
1429
1430
  end
1430
1431
  asg_options[:termination_policies] = @config["termination_policies"] if @config["termination_policies"]