cloud-mu 3.1.6 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/bin/mu-adopt +15 -12
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +37 -1
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -1
- data/bin/mu-run-tests +37 -12
- data/cloud-mu.gemspec +4 -4
- data/cookbooks/mu-tools/attributes/default.rb +7 -0
- data/cookbooks/mu-tools/libraries/helper.rb +87 -3
- data/cookbooks/mu-tools/recipes/apply_security.rb +39 -23
- data/cookbooks/mu-tools/recipes/aws_api.rb +13 -0
- data/cookbooks/mu-tools/recipes/google_api.rb +4 -0
- data/cookbooks/mu-tools/recipes/rsyslog.rb +8 -1
- data/cookbooks/mu-tools/resources/disk.rb +33 -12
- data/cookbooks/mu-tools/resources/mommacat_request.rb +1 -2
- data/cookbooks/mu-tools/templates/centos-8/sshd_config.erb +215 -0
- data/extras/clean-stock-amis +10 -2
- data/extras/generate-stock-images +7 -3
- data/extras/image-generators/AWS/centos7.yaml +19 -16
- data/extras/image-generators/AWS/{rhel7.yaml → rhel71.yaml} +0 -0
- data/extras/image-generators/AWS/{win2k12.yaml → win2k12r2.yaml} +0 -0
- data/modules/mommacat.ru +2 -2
- data/modules/mu.rb +84 -97
- data/modules/mu/adoption.rb +359 -59
- data/modules/mu/cleanup.rb +67 -44
- data/modules/mu/cloud.rb +108 -1754
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +44 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +929 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +178 -0
- data/modules/mu/config.rb +122 -80
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +32 -3
- data/modules/mu/config/cache_cluster.rb +2 -2
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/collection.rb +1 -1
- data/modules/mu/config/container_cluster.rb +2 -2
- data/modules/mu/config/database.rb +84 -105
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +5 -4
- data/modules/mu/config/doc_helpers.rb +4 -5
- data/modules/mu/config/endpoint.rb +2 -1
- data/modules/mu/config/firewall_rule.rb +3 -19
- data/modules/mu/config/folder.rb +1 -1
- data/modules/mu/config/function.rb +17 -8
- data/modules/mu/config/group.rb +1 -1
- data/modules/mu/config/habitat.rb +1 -1
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/loadbalancer.rb +57 -11
- data/modules/mu/config/log.rb +1 -1
- data/modules/mu/config/msg_queue.rb +1 -1
- data/modules/mu/config/nosqldb.rb +1 -1
- data/modules/mu/config/notifier.rb +8 -19
- data/modules/mu/config/ref.rb +81 -9
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +30 -34
- data/modules/mu/config/search_domain.rb +1 -1
- data/modules/mu/config/server.rb +5 -13
- data/modules/mu/config/server_pool.rb +3 -7
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +10 -0
- data/modules/mu/config/user.rb +1 -1
- data/modules/mu/config/vpc.rb +13 -17
- data/modules/mu/defaults/AWS.yaml +106 -106
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +1 -0
- data/modules/mu/deploy.rb +33 -19
- data/modules/mu/groomer.rb +15 -0
- data/modules/mu/groomers/chef.rb +3 -0
- data/modules/mu/logger.rb +120 -144
- data/modules/mu/master.rb +22 -1
- data/modules/mu/mommacat.rb +71 -26
- data/modules/mu/mommacat/daemon.rb +23 -14
- data/modules/mu/mommacat/naming.rb +82 -3
- data/modules/mu/mommacat/search.rb +59 -16
- data/modules/mu/mommacat/storage.rb +119 -48
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +248 -62
- data/modules/mu/{clouds → providers}/aws/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +275 -41
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +14 -50
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/{clouds → providers}/aws/collection.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +65 -63
- data/modules/mu/providers/aws/database.rb +1747 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +26 -12
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +39 -32
- data/modules/mu/{clouds → providers}/aws/folder.rb +1 -1
- data/modules/mu/{clouds → providers}/aws/function.rb +291 -133
- data/modules/mu/{clouds → providers}/aws/group.rb +18 -20
- data/modules/mu/{clouds → providers}/aws/habitat.rb +3 -3
- data/modules/mu/providers/aws/job.rb +469 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +77 -47
- data/modules/mu/{clouds → providers}/aws/log.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +14 -11
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +96 -5
- data/modules/mu/{clouds → providers}/aws/notifier.rb +135 -63
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -78
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +172 -41
- data/modules/mu/{clouds → providers}/aws/server.rb +120 -145
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +42 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +21 -38
- data/modules/mu/{clouds → providers}/aws/user.rb +12 -16
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/vpc.rb +141 -73
- data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
- data/modules/mu/{clouds → providers}/azure.rb +4 -1
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
- data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/server.rb +32 -24
- data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +4 -6
- data/modules/mu/{clouds → providers}/cloudformation.rb +1 -1
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +3 -3
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +15 -6
- data/modules/mu/{clouds → providers}/google/bucket.rb +2 -2
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +29 -14
- data/modules/mu/{clouds → providers}/google/database.rb +2 -9
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/google/folder.rb +5 -9
- data/modules/mu/{clouds → providers}/google/function.rb +4 -4
- data/modules/mu/{clouds → providers}/google/group.rb +9 -17
- data/modules/mu/{clouds → providers}/google/habitat.rb +4 -8
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +2 -2
- data/modules/mu/{clouds → providers}/google/role.rb +46 -35
- data/modules/mu/{clouds → providers}/google/server.rb +26 -11
- data/modules/mu/{clouds → providers}/google/server_pool.rb +11 -11
- data/modules/mu/{clouds → providers}/google/user.rb +32 -22
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +38 -3
- data/modules/tests/aws-jobs-functions.yaml +46 -0
- data/modules/tests/centos6.yaml +15 -0
- data/modules/tests/centos7.yaml +15 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +2 -2
- data/modules/tests/eks.yaml +1 -1
- data/modules/tests/functions/node-function/lambda_function.js +10 -0
- data/modules/tests/functions/python-function/lambda_function.py +12 -0
- data/modules/tests/microservice_app.yaml +288 -0
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +2 -2
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +126 -98
- data/modules/mu/clouds/aws/database.rb +0 -1974
- data/modules/mu/clouds/aws/endpoint.rb +0 -596
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0a85c9f70be756955896aaeb1ea32d462178402d4eec97279454337f839fc96
|
4
|
+
data.tar.gz: 3bee42f370ebb5ac6caa2fb52a36ec61d4aae204410a4aed13472cad130e222a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2910888a4c3061b4536bd84d60ec2c6b2b4170043983c603d5ff5b0af22ed43adee32e283e13da844fd949a9761a88c171a1eeb6b2b99bd7a08a93ed1efae772
|
7
|
+
data.tar.gz: 5b6e371475a5768895d5618865d42d5005265fa0810d5bf71e2af93032bb2767e843612ef7ec9e401b7be48dc10827cb3445bd005cdc9e4a8dd088488f30fed7
|
data/Dockerfile
CHANGED
data/bin/mu-adopt
CHANGED
@@ -21,12 +21,6 @@ require 'bundler/setup'
|
|
21
21
|
require 'optimist'
|
22
22
|
require 'mu'
|
23
23
|
|
24
|
-
available_clouds = MU::Cloud.supportedClouds
|
25
|
-
available_clouds.reject! { |cloud|
|
26
|
-
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
|
27
|
-
cloudclass.listCredentials.nil? or cloudclass.listCredentials.size == 0
|
28
|
-
}
|
29
|
-
|
30
24
|
available_types = MU::Cloud.resource_types.keys.map { |t| t.to_s }
|
31
25
|
grouping_options = {
|
32
26
|
"logical" => "Group resources in logical layers (folders and habitats together, users/roles/groups together, network resources together, etc)",
|
@@ -39,16 +33,19 @@ $opt = Optimist::options do
|
|
39
33
|
EOS
|
40
34
|
opt :appname, "The overarching name of the application stack we will generate", :required => false, :default => "mu", :type => :string
|
41
35
|
opt :types, "The resource types to scan and import. Valid types: #{available_types.join(", ")}", :required => false, :type => :strings, :default => available_types
|
42
|
-
opt :clouds, "The cloud providers to scan and import.", :required => false, :type => :strings, :default =>
|
36
|
+
opt :clouds, "The cloud providers to scan and import.", :required => false, :type => :strings, :default => MU::Cloud.availableClouds
|
43
37
|
opt :parent, "Where applicable, resources which reside in the root folder or organization are configured with the specified parent in our target BoK", :required => false, :type => :string
|
44
38
|
opt :billing, "Force-set this billing entity on created resources, instead of copying from the live resources", :required => false, :type => :string
|
45
39
|
opt :sources, "One or more sets of credentials to use when importing resources. By default we will search and import from all sets of available credentials for each cloud provider specified with --clouds", :required => false, :type => :strings
|
46
40
|
opt :credentials, "Override the 'credentials' value in our generated Baskets of Kittens to target a single, specific account. Our default behavior is to set each resource to deploy into the account from which it was sourced.", :required => false, :type => :string
|
47
41
|
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
42
|
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
|
43
|
+
opt :merge_changes, "When using --diff, merge detected changes into the baseline deploy after reporting on them.", :required => false, :type => :boolean, :default => false
|
49
44
|
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
45
|
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
|
46
|
+
opt :regions, "Restrict to operating on a subset of available regions, instead of all that we know about.", :require => false, :type => :strings
|
51
47
|
opt :scrub, "Whether to set scrub_mu_isms in the BoKs we generate", :default => $MU_CFG.has_key?('adopt_scrub_mu_isms') ? $MU_CFG['adopt_scrub_mu_isms'] : false
|
48
|
+
opt :pattern, "Only adopt resources whose resource name would match this pattern. Must be a valid regular expression. Alphabetical characters will be treated case-insensitively.", :required => false, :type => :string
|
52
49
|
end
|
53
50
|
|
54
51
|
ok = true
|
@@ -64,6 +61,16 @@ if $opt[:diff]
|
|
64
61
|
$opt[:savedeploys] = false
|
65
62
|
end
|
66
63
|
|
64
|
+
pattern = nil
|
65
|
+
if $opt[:pattern]
|
66
|
+
begin
|
67
|
+
pattern = Regexp.new($opt[:pattern], true)
|
68
|
+
rescue RegexpError => e
|
69
|
+
MU.log "Invalid --pattern option: #{e.message}", MU::ERR
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
67
74
|
types = []
|
68
75
|
$opt[:types].each { |t|
|
69
76
|
t_name = t.gsub(/-/, "_")
|
@@ -102,8 +109,7 @@ if !ok
|
|
102
109
|
exit 1
|
103
110
|
end
|
104
111
|
|
105
|
-
|
106
|
-
adoption = MU::Adoption.new(clouds: clouds, types: types, parent: $opt[:parent], billing: $opt[:billing], sources: $opt[:sources], credentials: $opt[:credentials], group_by: $opt[:grouping].to_sym, savedeploys: $opt[:savedeploys], diff: $opt[:diff], habitats: $opt[:habitats], scrub_mu_isms: $opt[:scrub])
|
112
|
+
adoption = MU::Adoption.new(clouds: clouds, types: types, parent: $opt[:parent], billing: $opt[:billing], sources: $opt[:sources], credentials: $opt[:credentials], group_by: $opt[:grouping].to_sym, savedeploys: $opt[:savedeploys], diff: $opt[:diff], habitats: $opt[:habitats], scrub_mu_isms: $opt[:scrub], regions: $opt[:regions], merge: $opt[:merge_changes], pattern: pattern)
|
107
113
|
found = adoption.scrapeClouds
|
108
114
|
if found.nil? or found.empty?
|
109
115
|
MU.log "No resources found to adopt", MU::WARN, details: {"clouds" => clouds, "types" => types }
|
@@ -117,10 +123,7 @@ boks.each_pair { |appname, bok|
|
|
117
123
|
File.open("#{appname}.yaml", "w") { |f|
|
118
124
|
f.write JSON.parse(JSON.generate(bok)).to_yaml
|
119
125
|
}
|
120
|
-
conf_engine = MU::Config.new("#{appname}.yaml")
|
121
|
-
stack_conf = conf_engine.config
|
122
126
|
# puts stack_conf.to_yaml
|
123
|
-
MU.log "#{appname}.yaml validated successfully", MU::NOTICE
|
124
127
|
MU::Cloud.resource_types.each_pair { |type, cfg|
|
125
128
|
if bok[cfg[:cfg_plural]]
|
126
129
|
MU.log "#{bok[cfg[:cfg_plural]].size.to_s} #{cfg[:cfg_plural]}", MU::NOTICE
|
data/bin/mu-azure-tests
ADDED
@@ -0,0 +1,57 @@
|
|
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
|
+
(0..100000).to_a.each { |n|
|
26
|
+
retries = 0
|
27
|
+
seed = nil
|
28
|
+
# begin
|
29
|
+
# raise MuError, "Failed to allocate an unused MU-ID after #{retries} tries!" if retries > 70
|
30
|
+
# seedsize = 1 + (retries/10).abs
|
31
|
+
# seed = (0...seedsize+1).map { ('a'..'z').to_a[rand(26)] }.join
|
32
|
+
# end while seed == "mu" or seed[0] == seed[1]
|
33
|
+
seed = "nn"
|
34
|
+
handle = MU::MommaCat.generateHandle(seed)
|
35
|
+
puts handle
|
36
|
+
}
|
37
|
+
exit
|
38
|
+
|
39
|
+
#pp MU::Cloud::Azure.listRegions
|
40
|
+
#pp MU::Cloud::Azure::Habitat.testcalls
|
41
|
+
#pp MU::Cloud::Azure::VPC.find(cloud_id: MU::Cloud::Azure::Id.new(resource_group: "mu", name: "mu-vnet"))
|
42
|
+
#pp MU::Cloud::Azure.authorization.role_assignments.list_for_resource_group("AKS-DEV-2019062015-KA-EASTUS")
|
43
|
+
#pp MU::Cloud::Azure::Role.find(role_name: "Azure Kubernetes Service Cluster Admin Role")
|
44
|
+
#puts MU::Cloud::Azure.default_subscription
|
45
|
+
#pp MU::Cloud::Azure.fetchPublicIP("MYVPC-DEV-2019061911-XI-EASTUS", "ip-addr-thingy")
|
46
|
+
#pp MU::Cloud::Azure.ensureProvider("egtazure", "Microsoft.ContainerService", force: true)
|
47
|
+
pp MU::Cloud::Azure::Server.find(cloud_id: "mu")
|
48
|
+
exit
|
49
|
+
pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/6")
|
50
|
+
pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/7")
|
51
|
+
pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/8")
|
52
|
+
pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/7")
|
53
|
+
pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/6")
|
54
|
+
pp MU::Cloud::Azure::Server.fetchImage("Debian/debian-10/10")
|
55
|
+
pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2012-R2-Datacenter")
|
56
|
+
pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2016-Datacenter")
|
57
|
+
pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2019-Datacenter")
|
data/bin/mu-cleanup
CHANGED
@@ -24,10 +24,8 @@ require 'mu'
|
|
24
24
|
Dir.chdir(MU.installDir)
|
25
25
|
|
26
26
|
credentials = []
|
27
|
-
MU::Cloud.
|
28
|
-
|
29
|
-
next if cloudclass.listCredentials.nil? or cloudclass.listCredentials.size == 0
|
30
|
-
credentials.concat(cloudclass.listCredentials)
|
27
|
+
MU::Cloud.availableClouds.each { |cloud|
|
28
|
+
credentials.concat(MU::Cloud.cloudClass(cloud).listCredentials)
|
31
29
|
}
|
32
30
|
credentials.uniq!
|
33
31
|
|
data/bin/mu-configure
CHANGED
@@ -113,12 +113,44 @@ $CONFIGURABLES = {
|
|
113
113
|
"desc" => "Disable the Momma Cat grooming daemon. Nodes which require asynchronous Ansible/Chef bootstraps will not function. This option is only honored in gem-based installations.",
|
114
114
|
"boolean" => true
|
115
115
|
},
|
116
|
+
"adopt_change_notify" => {
|
117
|
+
"title" => "Adoption Change Notifications",
|
118
|
+
"subtree" => {
|
119
|
+
"slack" => {
|
120
|
+
"title" => "Send to Slack",
|
121
|
+
"desc" => "Report modifications to adopted resources, detected by mu-adopt --diff, to the Slack webhook and channel configured under Slack Configuration.",
|
122
|
+
"boolean" => true
|
123
|
+
},
|
124
|
+
"slack_snippet_threshold" => {
|
125
|
+
"title" => "Attachment Threshold",
|
126
|
+
"desc" => "If a list of details about a modified resources is longer than this number of lines (in JSON), it will be sent as an \"attachment,\" which in Slack means a blockquote that displays a few lines with a \"Show more\" button. The internal default is 5 lines."
|
127
|
+
},
|
128
|
+
# "email" => {
|
129
|
+
# "title" => "Send Email",
|
130
|
+
# "desc" => "",
|
131
|
+
# "boolean" => true
|
132
|
+
# }
|
133
|
+
}
|
134
|
+
},
|
116
135
|
"adopt_scrub_mu_isms" => {
|
117
|
-
"title" => "
|
136
|
+
"title" => "Scrub Mu-isms from Baskets of Kittens",
|
118
137
|
"default" => false,
|
119
138
|
"desc" => "Ordinarily, Mu will automatically name, tag and generate auxiliary resources in a standard Mu-ish fashion that allows for deployment of multiple clones of a given stack. Toggling this flag will change the default behavior of mu-adopt, when it creates stack descriptors from found resources, to enable or disable this behavior (see also mu-adopt's --scrub option).",
|
120
139
|
"boolean" => true
|
121
140
|
},
|
141
|
+
"slack" => {
|
142
|
+
"title" => "Slack Configuration",
|
143
|
+
"subtree" => {
|
144
|
+
"webhook" => {
|
145
|
+
"title" => "Webhook",
|
146
|
+
"desc" => "The hooks.slack.com URL for the webook to which we'll send deploy notifications"
|
147
|
+
},
|
148
|
+
"channel" => {
|
149
|
+
"title" => "Channel",
|
150
|
+
"desc" => "The channel name (without leading #) to which alerts should be sent."
|
151
|
+
}
|
152
|
+
}
|
153
|
+
},
|
122
154
|
"mommacat_port" => {
|
123
155
|
"title" => "Momma Cat Listen Port",
|
124
156
|
"pattern" => /^[0-9]+$/i,
|
@@ -247,6 +279,10 @@ $CONFIGURABLES = {
|
|
247
279
|
"required" => false,
|
248
280
|
"desc" => "For Google Cloud projects which are attached to a GSuite domain. GCP service accounts cannot view or manage GSuite resources (groups, users, etc) directly, but must instead masquerade as a GSuite user which has delegated authority to the service account. See also: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority"
|
249
281
|
},
|
282
|
+
"org" => {
|
283
|
+
"title" => "Default Org/Domain",
|
284
|
+
"desc" => "For credential sets which have access to multiple GSuite or Cloud Identity orgs, you must specify a default organization (e.g. my.domain.com)."
|
285
|
+
},
|
250
286
|
"customer_id" => {
|
251
287
|
"title" => "GSuite Customer ID",
|
252
288
|
"required" => false,
|
data/bin/mu-deploy
CHANGED
@@ -105,7 +105,7 @@ if $opts[:dryrun]
|
|
105
105
|
Thread.handle_interrupt(MU::Cloud::MuCloudResourceNotImplemented => :never) {
|
106
106
|
begin
|
107
107
|
Thread.handle_interrupt(MU::Cloud::MuCloudResourceNotImplemented => :immediate) {
|
108
|
-
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::
|
108
|
+
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::NOTICE, verbosity: MU::Logger::NORMAL
|
109
109
|
Thread.current.exit
|
110
110
|
}
|
111
111
|
ensure
|
@@ -124,7 +124,7 @@ if $opts[:dryrun]
|
|
124
124
|
)
|
125
125
|
cost_dummy_deploy.run
|
126
126
|
rescue MU::Cloud::MuCloudResourceNotImplemented, MU::Cloud::MuCloudFlagNotImplemented
|
127
|
-
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::
|
127
|
+
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::NOTICE, verbosity: MU::Logger::NORMAL
|
128
128
|
end
|
129
129
|
end
|
130
130
|
exit
|
@@ -135,7 +135,7 @@ if $opts[:update]
|
|
135
135
|
# TODO consider whether this is useful/valid
|
136
136
|
# old_conf = JSON.parse(File.read(deploy.deploy_dir+"/basket_of_kittens.json"))
|
137
137
|
# stack_conf = old_conf.merge(stack_conf)
|
138
|
-
deploy.updateBasketofKittens(stack_conf)
|
138
|
+
deploy.updateBasketofKittens(stack_conf, skip_validation: true)
|
139
139
|
deployer = MU::Deploy.new(
|
140
140
|
deploy.environment,
|
141
141
|
verbosity: verbosity,
|
@@ -0,0 +1,25 @@
|
|
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
|
+
MU::MommaCat.findStray("AWS", "firewall_rule", region: MU.myRegion, dummy_ok: true, debug: true)
|
data/bin/mu-gen-docs
CHANGED
@@ -79,8 +79,7 @@ EOF
|
|
79
79
|
impl_counts[type] ||= 0
|
80
80
|
[a, b].each { |cloud|
|
81
81
|
begin
|
82
|
-
|
83
|
-
case myclass.quality
|
82
|
+
case MU::Cloud.resourceClass(cloud, type).quality
|
84
83
|
when MU::Cloud::RELEASE
|
85
84
|
cloud_is_useful[cloud] = true
|
86
85
|
counts[cloud] += 4
|
@@ -114,8 +113,7 @@ EOF
|
|
114
113
|
cloudlist.each { |cloud|
|
115
114
|
readme += "<td><center>"
|
116
115
|
begin
|
117
|
-
|
118
|
-
case myclass.quality
|
116
|
+
case MU::Cloud.resourceClass(cloud, type).quality
|
119
117
|
when MU::Cloud::RELEASE
|
120
118
|
readme += "<img src='release.png' style='#{icon_style}' title='Release Quality' alt='[Release Quality]'>"
|
121
119
|
when MU::Cloud::BETA
|
data/bin/mu-load-config.rb
CHANGED
@@ -134,7 +134,7 @@ def loadMuConfig(default_cfg_overrides = nil)
|
|
134
134
|
}
|
135
135
|
end
|
136
136
|
|
137
|
-
global_cfg = { "config_files" => [] }
|
137
|
+
global_cfg = { "config_files" => [], "overridden_keys" => [] }
|
138
138
|
if File.exist?(cfgPath)
|
139
139
|
global_cfg = YAML.load(File.read(cfgPath))
|
140
140
|
global_cfg["config_files"] = [cfgPath]
|
@@ -147,6 +147,7 @@ def loadMuConfig(default_cfg_overrides = nil)
|
|
147
147
|
if localfile
|
148
148
|
global_cfg.merge!(localfile)
|
149
149
|
global_cfg["config_files"] << "#{home}/.mu.yaml"
|
150
|
+
global_cfg["overridden_keys"] = localfile.keys
|
150
151
|
end
|
151
152
|
end
|
152
153
|
if !global_cfg.has_key?("installdir")
|
data/bin/mu-run-tests
CHANGED
@@ -34,6 +34,7 @@ Usage:
|
|
34
34
|
#{$0} [-m <#>] [-f] [-v] [specific test BoK to run [...]]
|
35
35
|
EOS
|
36
36
|
opt :max_threads, "Environment to set on creation.", :require => false, :default => 3, :type => :integer
|
37
|
+
opt :max_retries, "Number of times to retry failed tests in --dryrun mode.", :require => false, :default => 2, :type => :integer
|
37
38
|
opt :full, "Actually run deploys, instead of --dryrun", :require => false, :default => false
|
38
39
|
opt :verbose, "Show more information while running", :require => false, :default => false
|
39
40
|
end
|
@@ -42,7 +43,7 @@ only = ARGV
|
|
42
43
|
|
43
44
|
files = Dir.glob("*.yaml", base: dir)
|
44
45
|
files.concat(Dir.glob("*.yml", base: dir))
|
45
|
-
baseclouds = MU::Cloud.
|
46
|
+
baseclouds = MU::Cloud.availableClouds.reject { |c| c == "CloudFormation" }
|
46
47
|
|
47
48
|
commands = {}
|
48
49
|
failures = []
|
@@ -56,20 +57,33 @@ end
|
|
56
57
|
|
57
58
|
files.each { |f|
|
58
59
|
clouds = baseclouds.dup
|
60
|
+
groomer_match = true
|
59
61
|
File.open(dir+"/"+f).readlines.each { |l|
|
60
62
|
l.chomp!
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
if l.match(/^\s*#\s*clouds: (.*)/)
|
64
|
+
clouds = []
|
65
|
+
cloudstr = Regexp.last_match[1]
|
66
|
+
cloudstr.split(/\s*,\s*/).each { |c|
|
67
|
+
baseclouds.each { |cloud|
|
68
|
+
if cloud.match(/^#{Regexp.quote(c)}$/i)
|
69
|
+
clouds << cloud
|
70
|
+
end
|
71
|
+
}
|
72
|
+
}
|
73
|
+
elsif l.match(/^\s*#\s*groomers: (.*)/)
|
74
|
+
groomerstr = Regexp.last_match[1]
|
75
|
+
groomerstr.split(/\s*,\s*/).each { |g|
|
76
|
+
if !MU::Groomer.availableGroomers.include?(g)
|
77
|
+
MU.log "#{f} requires groomer #{g}, which is not available. This test will be skipped.", MU::NOTICE
|
78
|
+
groomer_match = false
|
68
79
|
end
|
69
80
|
}
|
70
|
-
|
71
|
-
break
|
81
|
+
end
|
72
82
|
}
|
83
|
+
if !groomer_match
|
84
|
+
next
|
85
|
+
end
|
86
|
+
|
73
87
|
clouds.each { |cloud|
|
74
88
|
cmd = "mu-deploy #{f} --cloud #{cloud} #{$opts[:full] ? "" : "--dryrun"}"
|
75
89
|
commands[cmd] = {
|
@@ -108,8 +122,19 @@ def execCommand(cmd, results_stash)
|
|
108
122
|
}
|
109
123
|
|
110
124
|
ok = true
|
111
|
-
|
112
|
-
|
125
|
+
retries = 0
|
126
|
+
begin
|
127
|
+
output = %x{#{cmd} 2>&1}
|
128
|
+
if $?.exitstatus != 0
|
129
|
+
ok = false
|
130
|
+
retries += 1
|
131
|
+
if $opts[:verbose] and !$opts[:full] and retries <= $opts[:max_retries]
|
132
|
+
puts "#{cmd} RETRY #{retries.to_s}".light_red
|
133
|
+
end
|
134
|
+
else
|
135
|
+
ok = true
|
136
|
+
end
|
137
|
+
end while !ok and !$opts[:full] and retries <= $opts[:max_retries]
|
113
138
|
|
114
139
|
results_stash["output"] += output
|
115
140
|
|
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.
|
21
|
-
s.date = '2020-
|
20
|
+
s.version = '3.4.0'
|
21
|
+
s.date = '2020-10-22'
|
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"
|
@@ -36,7 +36,7 @@ EOF
|
|
36
36
|
'https://github.com/cloudamatic/mu'
|
37
37
|
s.license = 'BSD-3-Clause-Attribution'
|
38
38
|
s.add_runtime_dependency 'addressable', '~> 2.5'
|
39
|
-
s.add_runtime_dependency "aws-sdk
|
39
|
+
s.add_runtime_dependency "aws-sdk", "~> 3.0"
|
40
40
|
s.add_runtime_dependency 'azure_sdk', "~> 0.52"
|
41
41
|
s.add_runtime_dependency 'bundler', "~> 1.17"
|
42
42
|
s.add_runtime_dependency 'chronic_duration', "~> 0.10"
|
@@ -57,7 +57,7 @@ EOF
|
|
57
57
|
s.add_runtime_dependency 'rack', "~> 2.0"
|
58
58
|
s.add_runtime_dependency 'ruby-graphviz', "~> 1.2"
|
59
59
|
s.add_runtime_dependency 'rubocop', '~> 0.58'
|
60
|
-
s.add_runtime_dependency 'rubyzip', "~> 2.
|
60
|
+
s.add_runtime_dependency 'rubyzip', "~> 2.3"
|
61
61
|
s.add_runtime_dependency 'simple-password-gen', "~> 0.1"
|
62
62
|
s.add_runtime_dependency 'slack-notifier', "~> 2.3"
|
63
63
|
s.add_runtime_dependency 'solve', '~> 4.0'
|
@@ -21,6 +21,13 @@ if disk_name_str == "CAP-MASTER" or disk_name_str == "MU-MASTER" and !node['host
|
|
21
21
|
disk_name_str = node['hostname']
|
22
22
|
end rescue NoMethodError
|
23
23
|
|
24
|
+
diskdevs = :xvd
|
25
|
+
if !platform_family?("windows")
|
26
|
+
if default['kernel']['modules'].keys.include?("nvme")
|
27
|
+
diskdevs = :nvme
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
24
31
|
default['os_updates_using_chef'] = false
|
25
32
|
|
26
33
|
default['application_attributes']['application_volume']['mount_directory'] = '/apps'
|
@@ -45,6 +45,70 @@ module Mutools
|
|
45
45
|
nil
|
46
46
|
end
|
47
47
|
|
48
|
+
# Just list our block devices
|
49
|
+
# @return [Array<String>]
|
50
|
+
def list_disk_devices
|
51
|
+
if File.executable?("/bin/lsblk")
|
52
|
+
shell_out(%Q{/bin/lsblk -i -p -r -n | egrep ' disk( |$)'}).stdout.each_line.map { |l|
|
53
|
+
l.chomp.sub(/ .*/, '')
|
54
|
+
}
|
55
|
+
else
|
56
|
+
# XXX something dumber
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# If we're in AWS and NVME-aware, return a mapping of AWS-side device names
|
62
|
+
# to actual NVME devices.
|
63
|
+
# @return [Hash]
|
64
|
+
def attached_nvme_disks
|
65
|
+
if get_aws_metadata("meta-data/instance-id").nil? or
|
66
|
+
!File.executable?("/bin/lsblk") or !File.executable?("/sbin/nvme")
|
67
|
+
return {}
|
68
|
+
end
|
69
|
+
map = {}
|
70
|
+
devices = list_disk_devices
|
71
|
+
return {} if !devices
|
72
|
+
devices.each { |d|
|
73
|
+
if d =~ /^\/dev\/nvme/
|
74
|
+
shell_out(%Q{/sbin/nvme id-ctrl -v #{d}}).stdout.each_line { |desc|
|
75
|
+
if desc.match(/^0000: (?:[0-9a-f]{2} ){16}"(.+?)\./)
|
76
|
+
virt_dev = Regexp.last_match[1]
|
77
|
+
map[virt_dev] = d
|
78
|
+
if !File.exists?(virt_dev)
|
79
|
+
begin
|
80
|
+
File.symlink(d, virt_dev)
|
81
|
+
rescue Errno::EEXIST # XXX whyyyyy is this needed
|
82
|
+
end
|
83
|
+
end
|
84
|
+
break
|
85
|
+
end
|
86
|
+
}
|
87
|
+
end
|
88
|
+
}
|
89
|
+
map
|
90
|
+
end
|
91
|
+
|
92
|
+
def real_devicepath(dev)
|
93
|
+
map = attached_nvme_disks
|
94
|
+
if map[dev]
|
95
|
+
map[dev]
|
96
|
+
else
|
97
|
+
dev # be nice to actually handle this too
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def nvme?
|
102
|
+
if File.executable?("/bin/lsblk")
|
103
|
+
shell_out(%Q{/bin/lsblk -i -p -r -n}).stdout.each_line { |l|
|
104
|
+
return true if l =~ /^\/dev\/nvme\d/
|
105
|
+
}
|
106
|
+
else
|
107
|
+
return true if File.exists?("/dev/nvme0n1")
|
108
|
+
end
|
109
|
+
false
|
110
|
+
end
|
111
|
+
|
48
112
|
@project = nil
|
49
113
|
@authorizer = nil
|
50
114
|
def set_gcp_cfg_params
|
@@ -186,12 +250,12 @@ module Mutools
|
|
186
250
|
if cloud == "AWS"
|
187
251
|
resp = nil
|
188
252
|
begin
|
253
|
+
Chef::Log.info("Fetch deploy secret from s3://#{bucket}/#{filename}")
|
189
254
|
resp = s3.get_object(bucket: bucket, key: filename)
|
190
255
|
rescue ::Aws::S3::Errors::PermanentRedirect => e
|
191
256
|
tmps3 = Aws::S3::Client.new(region: "us-east-1")
|
192
257
|
resp = tmps3.get_object(bucket: bucket, key: filename)
|
193
258
|
end
|
194
|
-
Chef::Log.info("Fetch deploy secret from s3://#{bucket}/#{filename}")
|
195
259
|
secret = resp.body.read
|
196
260
|
elsif cloud == "Google"
|
197
261
|
include_recipe "mu-tools::gcloud"
|
@@ -230,17 +294,20 @@ module Mutools
|
|
230
294
|
end
|
231
295
|
|
232
296
|
def mommacat_request(action, arg)
|
297
|
+
params = Base64.urlsafe_encode64(JSON.generate(arg)) if arg
|
233
298
|
uri = URI("https://#{get_mu_master_ips.first}:2260/")
|
234
299
|
req = Net::HTTP::Post.new(uri)
|
235
300
|
res_type = (node['deployment'].has_key?(:server_pools) and node['deployment']['server_pools'].has_key?(node['service_name'])) ? "server_pool" : "server"
|
236
301
|
response = nil
|
237
302
|
begin
|
238
303
|
secret = get_deploy_secret
|
239
|
-
if secret.nil?
|
304
|
+
if secret.nil? or secret.empty?
|
240
305
|
raise "Failed to fetch deploy secret, and I can't communicate with Momma Cat without it"
|
241
306
|
end
|
242
307
|
|
243
308
|
Chef::Log.info("Sending Momma Cat #{action} request to #{uri} from #{get_aws_metadata("meta-data/instance-id")}")
|
309
|
+
disks_before = list_disk_devices if action == "add_volume"
|
310
|
+
|
244
311
|
req.set_form_data(
|
245
312
|
"mu_id" => mu_get_tag_value("MU-ID"),
|
246
313
|
"mu_resource_name" => node['service_name'],
|
@@ -248,7 +315,7 @@ module Mutools
|
|
248
315
|
"mu_resource_type" => res_type,
|
249
316
|
"mu_user" => node['deployment']['mu_user'] || node['deployment']['chef_user'],
|
250
317
|
"mu_deploy_secret" => secret,
|
251
|
-
action =>
|
318
|
+
action => params
|
252
319
|
)
|
253
320
|
http = Net::HTTP.new(uri.hostname, uri.port)
|
254
321
|
http.use_ssl = true
|
@@ -256,6 +323,23 @@ module Mutools
|
|
256
323
|
response = http.request(req)
|
257
324
|
if response.code != "200"
|
258
325
|
Chef::Log.error("Got #{response.code} back from #{uri} on #{action} => #{arg}")
|
326
|
+
else
|
327
|
+
if action == "add_volume" and arg and arg.is_a?(Hash) and arg[:dev]
|
328
|
+
seen_requested = false
|
329
|
+
retries = 0
|
330
|
+
begin
|
331
|
+
list_disk_devices.each { |d|
|
332
|
+
if d == arg[:dev] or
|
333
|
+
(nvme? and d == attached_nvme_disks[arg[:dev]])
|
334
|
+
seen_requested = true
|
335
|
+
end
|
336
|
+
}
|
337
|
+
if !seen_requested
|
338
|
+
sleep 6
|
339
|
+
retries += 1
|
340
|
+
end
|
341
|
+
end while retries < 5 and !seen_requested
|
342
|
+
end
|
259
343
|
end
|
260
344
|
rescue EOFError => e
|
261
345
|
# Sometimes deployment metadata is incomplete and missing a
|