cloud-mu 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +25 -0
- data/README.md +2 -2
- data/bin/mu-node-manage +1 -1
- data/chefignore +1 -0
- data/cloud-mu.gemspec +2 -2
- data/extras/clean-stock-amis +0 -0
- data/extras/generate-stock-images +0 -0
- data/extras/list-stock-amis +0 -0
- data/extras/vault_tools/export_vaults.sh +0 -0
- data/extras/vault_tools/recreate_vaults.sh +0 -0
- data/extras/vault_tools/test_vaults.sh +0 -0
- data/kitchen.yml +97 -0
- data/modules/mu.rb +14 -2
- data/modules/mu/cloud.rb +26 -0
- data/modules/mu/clouds/aws.rb +1 -2
- data/modules/mu/clouds/aws/container_cluster.rb +2 -1
- data/modules/mu/clouds/aws/database.rb +2 -2
- data/modules/mu/clouds/aws/loadbalancer.rb +1 -1
- data/modules/mu/clouds/aws/search_domain.rb +1 -1
- data/modules/mu/clouds/aws/server.rb +9 -1
- data/modules/mu/clouds/aws/vpc.rb +1 -2
- data/modules/mu/config.rb +83 -3
- data/modules/mu/config/bucket.yml +1 -1
- data/modules/mu/config/cache_cluster.yml +1 -9
- data/modules/mu/config/container_cluster.yml +1 -1
- data/modules/mu/config/database.yml +3 -3
- data/modules/mu/config/log.yml +8 -3
- data/modules/mu/config/msg_queue.yml +1 -1
- data/modules/mu/config/nosqldb.yml +1 -1
- data/modules/mu/config/notifier.yml +1 -1
- data/modules/mu/config/search_domain.yml +2 -2
- data/modules/mu/config/server.yml +23 -3
- data/modules/mu/config/server_pool.yml +5 -2
- data/modules/mu/config/storage_pool.yml +1 -1
- data/modules/mu/config/vpc.rb +6 -6
- data/modules/mu/config/vpc.yml +54 -3
- data/modules/mu/groomers/chef.rb +27 -0
- data/modules/mu/mommacat.rb +113 -18
- metadata +18 -22
- data/Berksfile.lock +0 -179
- data/bin/mu-azure-tests +0 -43
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +0 -33
- data/modules/mu/kittens.rb +0 -20651
- data/modules/mu/mu.yaml.rb +0 -276
- data/modules/scratchpad.erb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0ab46aed6ed1aaf58e3d8de76de9ea27adc49cbd754b51cc4ef7e6354a78a26
|
4
|
+
data.tar.gz: 5b341646d7533692813097af86fb37c46f1ba23fb0faf6acfe09688a3456e13c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9c62154b428aa93f247fbf61589372744a167814f0403a339640e1e96042c8ece774b57617127860e7cfa46dc95c0c666022c3872beac77987f496cea65ad00
|
7
|
+
data.tar.gz: 12a4ced1bb6cbfe64ef666699a34bafe1aaf0228d080d6f8ee3584bcaec967084eca3d3a4167a405e05d1f8bc0d171093f7bab46e5648d1ff3339750a36c60e8
|
data/Dockerfile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
FROM ruby:2.5-slim
|
2
|
+
|
3
|
+
RUN mkdir -p /opt/mu/etc/ /home/mu /usr/local/ruby-current/lib/ruby/gems/2.5.0/gems/var/
|
4
|
+
|
5
|
+
WORKDIR /home/mu
|
6
|
+
|
7
|
+
RUN apt-get update
|
8
|
+
|
9
|
+
RUN apt-get install -y ruby2.5-dev dnsutils ansible build-essential
|
10
|
+
|
11
|
+
RUN apt-get upgrade -y
|
12
|
+
|
13
|
+
COPY ./cloud-mu-*.gem /home/mu
|
14
|
+
|
15
|
+
RUN gem install ./cloud-mu-*.gem thin -N
|
16
|
+
|
17
|
+
RUN rm cloud-mu-*.gem
|
18
|
+
|
19
|
+
RUN apt-get remove -y build-essential ruby2.5-dev
|
20
|
+
|
21
|
+
RUN apt-get autoremove -y
|
22
|
+
|
23
|
+
EXPOSE 2260
|
24
|
+
|
25
|
+
CMD /usr/sbin/init
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
mu -- Cloudamatic Automation Tooling
|
2
2
|
===
|
3
3
|
[![pipeline status](https://gitlab.com/cloudamatic/mu/badges/master/pipeline.svg)](https://gitlab.com/cloudamatic/mu/commits/master)
|
4
|
-
[![Gem Version](https://badge.fury.io/rb/cloud-mu.svg)](https://badge.fury.io/rb/cloud-mu)
|
5
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/dd4e5d867890336accd1/maintainability)](https://codeclimate.com/github/cloudamatic/mu/maintainability)
|
6
|
-
[![
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/cloud-mu.svg)](https://badge.fury.io/rb/cloud-mu)
|
6
|
+
[![Docker Version](https://images.microbadger.com/badges/version/egtlabs/mu.svg)](https://microbadger.com/images/egtlabs/mu)
|
7
7
|
|
8
8
|
# About mu
|
9
9
|
**Mu** is the deployer and developer toolset for the Cloudamatic suite of services, designed to provision, orchestrate and manage complex platforms and applications. At [eGT Labs](https://www.eglobaltech.com/egt-labs/), we use mu for rapid prototyping of cloud migration efforts for federal customers, for managing cloud applications throughout their lifecycles, and as a tools library for cloud maintenance tasks.
|
data/bin/mu-node-manage
CHANGED
@@ -599,7 +599,7 @@ def updateAWSMetaData(deploys = MU::MommaCat.listDeploys, nodes = [])
|
|
599
599
|
|
600
600
|
MU.log "Updating #{nodename} userdata (#{server["conf"]["platform"]})"
|
601
601
|
begin
|
602
|
-
MU::Cloud::AWS.ec2(server['region']).modify_instance_attribute(
|
602
|
+
MU::Cloud::AWS.ec2(region: server['region']).modify_instance_attribute(
|
603
603
|
instance_id: id,
|
604
604
|
attribute: "userData",
|
605
605
|
value: Base64.encode64(userdata)
|
data/chefignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.kitchen
|
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.0.
|
21
|
-
s.date = '2019-11-
|
20
|
+
s.version = '3.0.1'
|
21
|
+
s.date = '2019-11-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"
|
data/extras/clean-stock-amis
CHANGED
File without changes
|
File without changes
|
data/extras/list-stock-amis
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/kitchen.yml
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
driver:
|
2
|
+
name: ec2
|
3
|
+
region: us-east-1
|
4
|
+
subnet_id: subnet-00f6ebfde53bbdccd
|
5
|
+
instance_type: t2.medium
|
6
|
+
iam_profile_name: mu-master-role
|
7
|
+
associate_public_ip: true
|
8
|
+
interface: dns
|
9
|
+
shared_credentials_profile: test_kitchen
|
10
|
+
instance_initiated_shutdown_behavior: terminate
|
11
|
+
tags:
|
12
|
+
Name: kitchen-mu-node
|
13
|
+
created-by: mu-pipeline
|
14
|
+
sudo: true
|
15
|
+
|
16
|
+
provisioner:
|
17
|
+
name: chef_zero
|
18
|
+
roles_path: roles
|
19
|
+
chef_license: accept
|
20
|
+
|
21
|
+
verifier:
|
22
|
+
name: shell
|
23
|
+
|
24
|
+
platforms:
|
25
|
+
- name: centos-7
|
26
|
+
vm_tags:
|
27
|
+
osdistro: centos7
|
28
|
+
|
29
|
+
- name: amazon2
|
30
|
+
vm_tags:
|
31
|
+
osdistro: amazon2
|
32
|
+
|
33
|
+
- name: centos-7-az
|
34
|
+
driver:
|
35
|
+
name: azurerm
|
36
|
+
subscription_id: '3d20ddd8-4652-4074-adda-0d127ef1f0e0'
|
37
|
+
location: 'East US'
|
38
|
+
#image_urn: 'tunnelbiz:centos70-min:centos7-min:0.1.1'
|
39
|
+
machine_size: 'Standard_B2s'
|
40
|
+
vm_name: mu-install
|
41
|
+
vm_tags:
|
42
|
+
osdistro: centos7
|
43
|
+
|
44
|
+
suites:
|
45
|
+
- name: mu-install-aws
|
46
|
+
provisioner:
|
47
|
+
name: shell
|
48
|
+
script:
|
49
|
+
- "./kitchen_vars"
|
50
|
+
- "./install/installer"
|
51
|
+
- "./install/mu-master.yaml"
|
52
|
+
command:
|
53
|
+
- sudo yum install -y bind-utils
|
54
|
+
- sudo chown root:root /tmp/installer
|
55
|
+
- sudo chmod u+x /tmp/installer
|
56
|
+
- sudo chown root:root /tmp/mu-master.yaml
|
57
|
+
- source /tmp/kitchen_vars
|
58
|
+
- env
|
59
|
+
- myip="$(dig +short myip.opendns.com @resolver1.opendns.com)"
|
60
|
+
- sudo /tmp/installer -p $myip -m zach@zach.systems -o 2260 -h "$(echo $HOSTNAME | sed s/\\./-/g)" -n
|
61
|
+
root_path: '/tmp/'
|
62
|
+
includes:
|
63
|
+
- centos-7
|
64
|
+
- amazon2
|
65
|
+
|
66
|
+
- name: mu-install-azure
|
67
|
+
provisioner:
|
68
|
+
name: shell
|
69
|
+
script:
|
70
|
+
- "./install/installer"
|
71
|
+
- "./install/mu-master.yaml"
|
72
|
+
command:
|
73
|
+
- myip="$(dig +short myip.opendns.com @resolver1.opendns.com)"
|
74
|
+
- sudo ll /tmp/ && sudo MU_BRANCH=development /tmp/installer -p $myip -m zach@zach.systems -o 2260 -h "$(echo $HOSTNAME | sed s/\\./-/g)" -n
|
75
|
+
- sudo mu-deploy /tmp/mu-master.yaml -p name=stange-mu -p cloud=Azure
|
76
|
+
root_path: '/tmp/'
|
77
|
+
includes:
|
78
|
+
- centos-7-az
|
79
|
+
|
80
|
+
#- name: mu-node
|
81
|
+
# run_list:
|
82
|
+
# - recipe[mu-tools::newclient]
|
83
|
+
# - recipe[mu-tools::gcloud]
|
84
|
+
# - role[mu-node]
|
85
|
+
# includes:
|
86
|
+
# - ubuntu
|
87
|
+
# - centos-7
|
88
|
+
# - centos-6
|
89
|
+
# - rhel-7
|
90
|
+
# - rhel-6
|
91
|
+
# - amazon
|
92
|
+
# - amazon2
|
93
|
+
# - windows
|
94
|
+
|
95
|
+
# - name: mu-master
|
96
|
+
# run_list:
|
97
|
+
# - role[mu-master]
|
data/modules/mu.rb
CHANGED
@@ -343,6 +343,17 @@ module MU
|
|
343
343
|
((Gem.paths and Gem.paths.home and File.realpath(File.expand_path(File.dirname(__FILE__))).match(/^#{Gem.paths.home}/)) or !Dir.exist?("/opt/mu"))
|
344
344
|
end
|
345
345
|
|
346
|
+
# Are we operating in a gem?
|
347
|
+
def self.inGem?
|
348
|
+
return @in_gem if defined? @in_gem
|
349
|
+
|
350
|
+
if Gem.paths and Gem.paths.home and File.dirname(__FILE__).match(/^#{Gem.paths.home}/)
|
351
|
+
@in_gem = true
|
352
|
+
else
|
353
|
+
@in_gem = false
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
346
357
|
# The main (root) Mu user's data directory.
|
347
358
|
@@mainDataDir = File.expand_path(@@myRoot+"/../var")
|
348
359
|
# The main (root) Mu user's data directory.
|
@@ -631,8 +642,9 @@ module MU
|
|
631
642
|
!$MU_CFG['public_address'].empty? and @@my_public_ip != $MU_CFG['public_address']
|
632
643
|
@@mu_public_addr = $MU_CFG['public_address']
|
633
644
|
if !@@mu_public_addr.match(/^\d+\.\d+\.\d+\.\d+$/)
|
634
|
-
|
635
|
-
|
645
|
+
hostname = IO.readlines("/etc/hostname")[0].gsub /\n/, ''
|
646
|
+
|
647
|
+
@@mu_public_ip = File.open('/etc/hosts').grep(/.*#{hostname}.*/).first.match(/^\d+\.\d+\.\d+\.\d+/)[0]
|
636
648
|
else
|
637
649
|
@@mu_public_ip = @@mu_public_addr
|
638
650
|
end
|
data/modules/mu/cloud.rb
CHANGED
@@ -1142,6 +1142,30 @@ module MU
|
|
1142
1142
|
|
1143
1143
|
# Remove all metadata and cloud resources associated with this object
|
1144
1144
|
def destroy
|
1145
|
+
if self.class.cfg_name == "server"
|
1146
|
+
begin
|
1147
|
+
ip = canonicalIP
|
1148
|
+
MU::MommaCat.removeIPFromSSHKnownHosts(ip) if ip
|
1149
|
+
if @deploy and @deploy.deployment and
|
1150
|
+
@deploy.deployment['servers'] and @config['name'] and
|
1151
|
+
me = @deploy.deployment['servers'][@config['name']][@mu_name]
|
1152
|
+
if me
|
1153
|
+
["private_ip_address", "public_ip_address"].each { |field|
|
1154
|
+
if me[field]
|
1155
|
+
MU::MommaCat.removeIPFromSSHKnownHosts(me[field])
|
1156
|
+
end
|
1157
|
+
}
|
1158
|
+
if me["private_ip_list"]
|
1159
|
+
me["private_ip_list"].each { |ip|
|
1160
|
+
MU::MommaCat.removeIPFromSSHKnownHosts(ip)
|
1161
|
+
}
|
1162
|
+
end
|
1163
|
+
end
|
1164
|
+
end
|
1165
|
+
rescue MU::MuError => e
|
1166
|
+
MU.log e.message, MU::WARN
|
1167
|
+
end
|
1168
|
+
end
|
1145
1169
|
if !@cloudobj.nil? and !@cloudobj.groomer.nil?
|
1146
1170
|
@cloudobj.groomer.cleanup
|
1147
1171
|
elsif !@groomer.nil?
|
@@ -1952,6 +1976,7 @@ puts "CHOOSING #{@vpc.to_s} 'cause it has #{@config['vpc']['subnet_name']}"
|
|
1952
1976
|
:keys => [ssh_keydir+"/"+nat_ssh_key, ssh_keydir+"/"+@deploy.ssh_key_name],
|
1953
1977
|
:verify_host_key => false,
|
1954
1978
|
# :verbose => :info,
|
1979
|
+
:host_key => "ssh-rsa",
|
1955
1980
|
:port => 22,
|
1956
1981
|
:auth_methods => ['publickey'],
|
1957
1982
|
:proxy => proxy
|
@@ -1967,6 +1992,7 @@ puts "CHOOSING #{@vpc.to_s} 'cause it has #{@config['vpc']['subnet_name']}"
|
|
1967
1992
|
:keys => [ssh_keydir+"/"+@deploy.ssh_key_name],
|
1968
1993
|
:verify_host_key => false,
|
1969
1994
|
# :verbose => :info,
|
1995
|
+
:host_key => "ssh-rsa",
|
1970
1996
|
:port => 22,
|
1971
1997
|
:auth_methods => ['publickey']
|
1972
1998
|
)
|
data/modules/mu/clouds/aws.rb
CHANGED
@@ -164,7 +164,6 @@ module MU
|
|
164
164
|
# @param r [String]
|
165
165
|
# @return [String]
|
166
166
|
def self.validate_region(r, credentials: nil)
|
167
|
-
require "aws-sdk-core"
|
168
167
|
begin
|
169
168
|
MU::Cloud::AWS.ec2(region: r, credentials: credentials).describe_availability_zones.availability_zones.first.region_name
|
170
169
|
rescue ::Aws::EC2::Errors::UnauthorizedOperation => e
|
@@ -1339,8 +1338,8 @@ module MU
|
|
1339
1338
|
# @param region [String]: Amazon region so we know what endpoint to use
|
1340
1339
|
# @param api [String]: Which API are we wrapping?
|
1341
1340
|
def initialize(region: MU.curRegion, api: "EC2", credentials: nil)
|
1342
|
-
@credentials = MU::Cloud::AWS.credConfig(credentials, name_only: true)
|
1343
1341
|
@cred_obj = MU::Cloud::AWS.loadCredentials(credentials)
|
1342
|
+
@credentials = MU::Cloud::AWS.credConfig(credentials, name_only: true)
|
1344
1343
|
|
1345
1344
|
if !@cred_obj
|
1346
1345
|
raise MuError, "Unable to locate valid AWS credentials for #{api} API. #{credentials ? "Credentials requested were '#{credentials}'": ""}"
|
@@ -66,6 +66,7 @@ module MU
|
|
66
66
|
]
|
67
67
|
}
|
68
68
|
end
|
69
|
+
params.delete(:version) if params[:version] == "latest"
|
69
70
|
|
70
71
|
MU.log "Creating EKS cluster #{@mu_name}", details: params
|
71
72
|
resp = MU::Cloud::AWS.eks(region: @config['region'], credentials: @config['credentials']).create_cluster(params)
|
@@ -91,7 +92,7 @@ module MU
|
|
91
92
|
sleep 5
|
92
93
|
retry
|
93
94
|
else
|
94
|
-
MU.log e.message, MU::WARN, details:
|
95
|
+
MU.log e.message, MU::WARN, details: params
|
95
96
|
sleep 5
|
96
97
|
retry
|
97
98
|
end
|
@@ -928,7 +928,7 @@ module MU
|
|
928
928
|
basename[0..29].gsub(/[^a-z0-9]/i, "")
|
929
929
|
elsif config["engine"].match(/^sqlserver/)
|
930
930
|
basename[0..127].gsub(/[^a-z0-9]/i, "")
|
931
|
-
elsif config["engine"].match(/^mysql/)
|
931
|
+
elsif config["engine"].match(/^(mysql|maria)/)
|
932
932
|
basename[0..15].gsub(/[^a-z0-9]/i, "")
|
933
933
|
elsif config["engine"].match(/^aurora/)
|
934
934
|
basename[0..15].gsub(/[^a-z0-9]/i, "")
|
@@ -1603,7 +1603,7 @@ module MU
|
|
1603
1603
|
db["license_model"] ||=
|
1604
1604
|
if ["postgres", "postgresql", "aurora-postgresql"].include?(db["engine"])
|
1605
1605
|
"postgresql-license"
|
1606
|
-
elsif db["engine"]
|
1606
|
+
elsif ["mysql", "mariadb"].include?(db["engine"])
|
1607
1607
|
"general-public-license"
|
1608
1608
|
else
|
1609
1609
|
"license-included"
|
@@ -188,7 +188,7 @@ module MU
|
|
188
188
|
if @config['targetgroups']
|
189
189
|
MU.log "Configuring target groups and health checks check for ELB #{@mu_name}", details: @config['healthcheck']
|
190
190
|
@config['targetgroups'].each { |tg|
|
191
|
-
tg_name = @deploy.getResourceName(tg["name"], max_length: 32)
|
191
|
+
tg_name = @deploy.getResourceName(tg["name"], max_length: 32, allowed_chars: /[A-Za-z0-9-]/)
|
192
192
|
tg_descriptor = {
|
193
193
|
:name => tg_name,
|
194
194
|
:protocol => tg['proto'],
|
@@ -67,7 +67,7 @@ module MU
|
|
67
67
|
domain_name: @deploydata['domain_name']
|
68
68
|
).domain_status
|
69
69
|
else
|
70
|
-
raise
|
70
|
+
raise MuError "#{@mu_name} can't find its official Elasticsearch domain name!"
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -120,8 +120,10 @@ module MU
|
|
120
120
|
@config['mu_name'] = @mu_name
|
121
121
|
|
122
122
|
end
|
123
|
+
|
123
124
|
@config['instance_secret'] ||= Password.random(50)
|
124
125
|
|
126
|
+
@groomer = MU::Groomer.new(self) unless MU.inGem?
|
125
127
|
end
|
126
128
|
|
127
129
|
@@userdata_semaphore = Mutex.new
|
@@ -938,11 +940,17 @@ module MU
|
|
938
940
|
|
939
941
|
# See if this node already exists in our config management. If it does,
|
940
942
|
# we're done.
|
941
|
-
if
|
943
|
+
if MU.inGem?
|
944
|
+
MU.log "Deploying from a gem, not grooming"
|
945
|
+
|
946
|
+
return true
|
947
|
+
elsif @groomer.haveBootstrapped?
|
942
948
|
MU.log "Node #{node} has already been bootstrapped, skipping groomer setup.", MU::NOTICE
|
949
|
+
|
943
950
|
if @config['groom'].nil? or @config['groom']
|
944
951
|
@groomer.saveDeployData
|
945
952
|
end
|
953
|
+
|
946
954
|
MU::MommaCat.unlock(instance.instance_id+"-orchestrate")
|
947
955
|
MU::MommaCat.unlock(instance.instance_id+"-groom")
|
948
956
|
return true
|
@@ -1161,7 +1161,6 @@ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
|
|
1161
1161
|
# @param region [String]: The cloud provider region
|
1162
1162
|
# @return [void]
|
1163
1163
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
1164
|
-
|
1165
1164
|
tagfilters = [
|
1166
1165
|
{name: "tag:MU-ID", values: [MU.deploy_id]}
|
1167
1166
|
]
|
@@ -1172,7 +1171,7 @@ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
|
|
1172
1171
|
vpcs = []
|
1173
1172
|
retries = 0
|
1174
1173
|
begin
|
1175
|
-
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs(filters: tagfilters).vpcs
|
1174
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs(filters: tagfilters, max_results: 1000).vpcs
|
1176
1175
|
vpcs = resp if !resp.empty?
|
1177
1176
|
rescue Aws::EC2::Errors::InvalidVpcIDNotFound => e
|
1178
1177
|
if retries < 5
|
data/modules/mu/config.rb
CHANGED
@@ -317,6 +317,13 @@ module MU
|
|
317
317
|
}
|
318
318
|
end
|
319
319
|
|
320
|
+
# A way of dynamically defining +attr_reader+ without leaking memory
|
321
|
+
def self.define_reader(name)
|
322
|
+
define_method(name) {
|
323
|
+
instance_variable_get("@#{name.to_s}")
|
324
|
+
}
|
325
|
+
end
|
326
|
+
|
320
327
|
# @param cfg [Hash]: A Basket of Kittens configuration hash containing
|
321
328
|
# lookup information for a cloud object
|
322
329
|
def initialize(cfg)
|
@@ -327,7 +334,7 @@ module MU
|
|
327
334
|
elsif !cfg[field.to_sym].nil?
|
328
335
|
self.instance_variable_set("@#{field.to_s}".to_sym, cfg[field.to_sym])
|
329
336
|
end
|
330
|
-
|
337
|
+
MU::Config::Ref.define_reader(field)
|
331
338
|
}
|
332
339
|
if cfg['tag'] and cfg['tag']['key'] and
|
333
340
|
!cfg['tag']['key'].empty? and cfg['tag']['value']
|
@@ -985,6 +992,15 @@ return
|
|
985
992
|
|
986
993
|
@config['credentials'] ||= @default_credentials
|
987
994
|
|
995
|
+
if @config['cloud'] and !MU::Cloud.availableClouds.include?(@config['cloud'])
|
996
|
+
if MU::Cloud.supportedClouds.include?(@config['cloud'])
|
997
|
+
MU.log "Cloud provider #{@config['cloud']} declared, but no #{@config['cloud']} credentials available", MU::ERR
|
998
|
+
else
|
999
|
+
MU.log "Cloud provider #{@config['cloud']} is not supported", MU::ERR, details: MU::Cloud.supportedClouds
|
1000
|
+
end
|
1001
|
+
exit 1
|
1002
|
+
end
|
1003
|
+
|
988
1004
|
types = MU::Cloud.resource_types.values.map { |v| v[:cfg_plural] }
|
989
1005
|
|
990
1006
|
MU::Cloud.resource_types.values.map { |v| v[:cfg_plural] }.each { |type|
|
@@ -1274,6 +1290,16 @@ $CONFIGURABLES
|
|
1274
1290
|
}
|
1275
1291
|
ok = true
|
1276
1292
|
|
1293
|
+
if descriptor['cloud'] and
|
1294
|
+
!MU::Cloud.availableClouds.include?(descriptor['cloud'])
|
1295
|
+
if MU::Cloud.supportedClouds.include?(descriptor['cloud'])
|
1296
|
+
MU.log "#{cfg_name} #{descriptor['name']} is configured with cloud #{descriptor['cloud']}, but no #{descriptor['cloud']} credentials available", MU::ERR
|
1297
|
+
else
|
1298
|
+
MU.log "#{cfg_name} #{descriptor['name']}: Cloud provider #{descriptor['cloud']} is not supported", MU::ERR, details: MU::Cloud.supportedClouds
|
1299
|
+
end
|
1300
|
+
return false
|
1301
|
+
end
|
1302
|
+
|
1277
1303
|
descriptor["#MU_CLOUDCLASS"] = classname
|
1278
1304
|
|
1279
1305
|
applyInheritedDefaults(descriptor, cfg_plural)
|
@@ -1975,7 +2001,7 @@ $CONFIGURABLES
|
|
1975
2001
|
conf_chunk.map! { |item|
|
1976
2002
|
# If we're working on a resource type, go get implementation-specific
|
1977
2003
|
# schema information so that we set those defaults correctly.
|
1978
|
-
realschema = if type and schema_chunk["items"] and schema_chunk["items"]["properties"] and item["cloud"]
|
2004
|
+
realschema = if type and schema_chunk["items"] and schema_chunk["items"]["properties"] and item["cloud"] and MU::Cloud.supportedClouds.include?(item['cloud'])
|
1979
2005
|
|
1980
2006
|
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(item["cloud"]).const_get(type)
|
1981
2007
|
toplevel_required, cloudschema = cloudclass.schema(self)
|
@@ -2126,6 +2152,10 @@ $CONFIGURABLES
|
|
2126
2152
|
kitten['cloud'] ||= @config['cloud']
|
2127
2153
|
kitten['cloud'] ||= MU::Config.defaultCloud
|
2128
2154
|
|
2155
|
+
if !MU::Cloud.supportedClouds.include?(kitten['cloud'])
|
2156
|
+
return
|
2157
|
+
end
|
2158
|
+
|
2129
2159
|
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud'])
|
2130
2160
|
shortclass, cfg_name, cfg_plural, classname = MU::Cloud.getResourceNames(type)
|
2131
2161
|
resclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud']).const_get(shortclass)
|
@@ -2198,6 +2228,7 @@ $CONFIGURABLES
|
|
2198
2228
|
count = count + @kittens[type].size
|
2199
2229
|
}
|
2200
2230
|
|
2231
|
+
|
2201
2232
|
if count == 0
|
2202
2233
|
MU.log "You must declare at least one resource to create", MU::ERR
|
2203
2234
|
ok = false
|
@@ -2437,8 +2468,10 @@ $CONFIGURABLES
|
|
2437
2468
|
# and turn into documentation.
|
2438
2469
|
def self.printSchema(kitten_rb, class_hierarchy, schema, in_array = false, required = false, prefix: nil)
|
2439
2470
|
return if schema.nil?
|
2471
|
+
|
2440
2472
|
if schema["type"] == "object"
|
2441
|
-
printme =
|
2473
|
+
printme = []
|
2474
|
+
|
2442
2475
|
if !schema["properties"].nil?
|
2443
2476
|
# order sub-elements by whether they're required, so we can use YARD's
|
2444
2477
|
# grouping tags on them
|
@@ -2453,6 +2486,53 @@ $CONFIGURABLES
|
|
2453
2486
|
printme << "# @!group Optional parameters" if schema["required"].nil? or schema["required"].size == 0
|
2454
2487
|
prop_list.each { |name|
|
2455
2488
|
prop = schema["properties"][name]
|
2489
|
+
|
2490
|
+
if class_hierarchy.size == 1
|
2491
|
+
|
2492
|
+
_shortclass, cfg_name, cfg_plural, _classname = MU::Cloud.getResourceNames(name)
|
2493
|
+
if cfg_name
|
2494
|
+
example_path = MU.myRoot+"/modules/mu/config/"+cfg_name+".yml"
|
2495
|
+
if File.exist?(example_path)
|
2496
|
+
example = "#\n# Examples:\n#\n"
|
2497
|
+
# XXX these variables are all parameters from the BoKs in
|
2498
|
+
# modules/tests. A really clever implementation would read
|
2499
|
+
# and parse them to get default values, perhaps, instead of
|
2500
|
+
# hard-coding them here.
|
2501
|
+
instance_type = "t2.medium"
|
2502
|
+
db_size = "db.t2.medium"
|
2503
|
+
vpc_name = "some_vpc"
|
2504
|
+
logs_name = "some_loggroup"
|
2505
|
+
queues_name = "some_queue"
|
2506
|
+
server_pools_name = "some_server_pool"
|
2507
|
+
["simple", "complex"].each { |complexity|
|
2508
|
+
erb = ERB.new(File.read(example_path), nil, "<>")
|
2509
|
+
example += "# !!!yaml\n"
|
2510
|
+
example += "# ---\n"
|
2511
|
+
example += "# appname: #{complexity}\n"
|
2512
|
+
example += "# #{cfg_plural}:\n"
|
2513
|
+
firstline = true
|
2514
|
+
erb.result(binding).split(/\n/).each { |l|
|
2515
|
+
l.sub!(/#.*/, "")
|
2516
|
+
next if l.empty? or l.match(/^\s+$/)
|
2517
|
+
if firstline
|
2518
|
+
l = "- "+l
|
2519
|
+
firstline = false
|
2520
|
+
else
|
2521
|
+
l = " "+l
|
2522
|
+
end
|
2523
|
+
example += "# "+l+" "+"\n"
|
2524
|
+
}
|
2525
|
+
example += "# \n#\n" if complexity == "simple"
|
2526
|
+
}
|
2527
|
+
schema["properties"][name]["items"]["description"] ||= ""
|
2528
|
+
if !schema["properties"][name]["items"]["description"].empty?
|
2529
|
+
schema["properties"][name]["items"]["description"] += "\n"
|
2530
|
+
end
|
2531
|
+
schema["properties"][name]["items"]["description"] += example
|
2532
|
+
end
|
2533
|
+
end
|
2534
|
+
end
|
2535
|
+
|
2456
2536
|
if !schema["required"].nil? and schema["required"].include?(name)
|
2457
2537
|
printme << "# @!group Required parameters" if !req
|
2458
2538
|
req = true
|