cloud-mu 2.0.0.pre.alpha3 → 2.0.0.pre.alpha4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cloud-mu.gemspec +1 -1
- data/cookbooks/mu-firewall/Berksfile +1 -1
- data/install/installer +1 -1
- data/modules/mu/cloud.rb +0 -1
- data/modules/mu/clouds/aws.rb +5 -0
- data/modules/mu/clouds/aws/dnszone.rb +1 -1
- data/modules/mu/clouds/aws/habitat.rb +2 -5
- data/modules/mu/clouds/azure.rb +5 -0
- data/modules/mu/clouds/google.rb +35 -0
- data/modules/mu/clouds/google/folder.rb +120 -0
- data/modules/mu/clouds/google/habitat.rb +53 -9
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc4fa3ace543abb312bf853be83b0b229a61cf4cd1dbb00f7a4ac1c383fe2538
|
4
|
+
data.tar.gz: 35ed1769840efedaa2b2408e0f0c24c07417c77aeaf8cb43dd11f758970a9d47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38feb71676cf984e102f90e41b96849521762f3cf0bcfc2e06af0b69a45e9255b02ff503f84ca27346dedb501e362b07b26be172cec0e4e118302cd9af5853b9
|
7
|
+
data.tar.gz: 2cdacd00b476374c45a94dddf0ee5e60b018200dbf58e34510bef8cb0169ea03a7edc1f7726c7f742304687cdeade991b05a71f40cb0326590e1091e757aada1
|
data/cloud-mu.gemspec
CHANGED
data/install/installer
CHANGED
@@ -4,7 +4,7 @@ BOLD=`tput bold`
|
|
4
4
|
NORM=`tput sgr0`
|
5
5
|
CHEF_CLIENT_VERSION="14.4.56"
|
6
6
|
if [ "$MU_BRANCH" == "" ];then
|
7
|
-
MU_BRANCH="
|
7
|
+
MU_BRANCH="Azure_you_want_azure" # GIT HOOK EDITABLE DO NOT TOUCH
|
8
8
|
mydir="`dirname $0`"
|
9
9
|
cd $mydir
|
10
10
|
if git rev-parse --abbrev-ref HEAD > /dev/null 2>&1;then
|
data/modules/mu/cloud.rb
CHANGED
@@ -1424,7 +1424,6 @@ MU.log "in dependencies() and findLitterMate gave me "+sib_by_name.to_s+" on beh
|
|
1424
1424
|
# Wrapper for the cleanup class method of underlying cloud object implementations.
|
1425
1425
|
def self.cleanup(*flags)
|
1426
1426
|
params = flags.first
|
1427
|
-
|
1428
1427
|
clouds = MU::Cloud.supportedClouds
|
1429
1428
|
if params[:cloud]
|
1430
1429
|
clouds = [params[:cloud]]
|
data/modules/mu/clouds/aws.rb
CHANGED
@@ -327,6 +327,11 @@ module MU
|
|
327
327
|
# cloud.
|
328
328
|
# @return [Boolean]
|
329
329
|
def self.hosted?
|
330
|
+
if $MU_CFG.has_key?("aws_is_hosted")
|
331
|
+
@@is_in_aws = $MU_CFG["aws_is_hosted"]
|
332
|
+
return $MU_CFG["aws_is_hosted"]
|
333
|
+
end
|
334
|
+
|
330
335
|
require 'open-uri'
|
331
336
|
|
332
337
|
if !@@is_in_aws.nil?
|
@@ -514,7 +514,7 @@ module MU
|
|
514
514
|
sleep 10
|
515
515
|
retry
|
516
516
|
rescue Aws::Route53::Errors::InvalidChangeBatch, Aws::Route53::Errors::InvalidInput, Exception => e
|
517
|
-
return if e.message.match(/ but it already exists
|
517
|
+
return if e.message.match(/ but it already exists/) and !delete
|
518
518
|
MU.log "Failed to change DNS records, #{e.inspect}", MU::ERR, details: params
|
519
519
|
raise e if !delete
|
520
520
|
MU.log "Record #{name} (#{type}) in #{id} can't be deleted. Already removed? #{e.inspect}", MU::WARN, details: params if delete
|
@@ -104,14 +104,11 @@ module MU
|
|
104
104
|
|
105
105
|
if resp and resp.accounts
|
106
106
|
resp.accounts.each { |acct|
|
107
|
-
if acct.name.match(/^#{Regexp.quote(MU.deploy_id)}/)
|
108
|
-
MU.log "Would delete account #{acct.name} if that was a thing"
|
107
|
+
if acct.name.match(/^#{Regexp.quote(MU.deploy_id)}/) or acct.name.match(/BUNS/)
|
109
108
|
if !noop
|
110
109
|
pp acct
|
111
110
|
end
|
112
|
-
|
113
|
-
pp acct if acct.name.match(/BUNS/)
|
114
|
-
#https://687950501457.signin.aws.amazon.com/console/organizations/complete-signup
|
111
|
+
MU.log "AWS accounts cannot be deleted via the API. To delete #{acct.name}, you must sign in with its root user #{acct.email}, ensure that its signup process has been completed, then visit ", MU::NOTICE, details: ["https://console.aws.amazon.com/", acct.email, acct.id]
|
115
112
|
end
|
116
113
|
}
|
117
114
|
end
|
data/modules/mu/clouds/azure.rb
CHANGED
@@ -31,6 +31,11 @@ module MU
|
|
31
31
|
# Determine whether we (the Mu master, presumably) are hosted in Azure.
|
32
32
|
# @return [Boolean]
|
33
33
|
def self.hosted?
|
34
|
+
if $MU_CFG.has_key?("azure_is_hosted")
|
35
|
+
@@is_in_aws = $MU_CFG["azure_is_hosted"]
|
36
|
+
return $MU_CFG["azure_is_hosted"]
|
37
|
+
end
|
38
|
+
|
34
39
|
if !@@is_in_azure.nil?
|
35
40
|
return @@is_in_azure
|
36
41
|
end
|
data/modules/mu/clouds/google.rb
CHANGED
@@ -242,6 +242,10 @@ module MU
|
|
242
242
|
# cloud.
|
243
243
|
# @return [Boolean]
|
244
244
|
def self.hosted?
|
245
|
+
if $MU_CFG.has_key?("google_is_hosted")
|
246
|
+
@@is_in_aws = $MU_CFG["google_is_hosted"]
|
247
|
+
return $MU_CFG["google_is_hosted"]
|
248
|
+
end
|
245
249
|
if !@@is_in_gcp.nil?
|
246
250
|
return @@is_in_gcp
|
247
251
|
end
|
@@ -411,6 +415,8 @@ module MU
|
|
411
415
|
# Our credentials map to a project, an organizational structure in Google
|
412
416
|
# Cloud. This fetches the identifier of the project associated with our
|
413
417
|
# default credentials.
|
418
|
+
# @param credentials [String]
|
419
|
+
# @return [String]
|
414
420
|
def self.defaultProject(credentials = nil)
|
415
421
|
cfg = credConfig(credentials)
|
416
422
|
return myProject if !cfg or !cfg['project']
|
@@ -418,6 +424,21 @@ module MU
|
|
418
424
|
cfg['project']
|
419
425
|
end
|
420
426
|
|
427
|
+
# We want a default place to put new projects for the Habitat resource,
|
428
|
+
# so if we have a root folder, we can go ahead and use that.
|
429
|
+
# @param credentials [String]
|
430
|
+
# @return [String]
|
431
|
+
def self.defaultFolder(credentials = nil)
|
432
|
+
project = defaultProject(credentials)
|
433
|
+
resp = MU::Cloud::Google.resource_manager(credentials: credentials).get_project_ancestry(project)
|
434
|
+
resp.ancestor.each { |a|
|
435
|
+
if a.resource_id.type == "folder"
|
436
|
+
return a.resource_id.id
|
437
|
+
end
|
438
|
+
}
|
439
|
+
nil
|
440
|
+
end
|
441
|
+
|
421
442
|
# List all Google Cloud Platform projects available to our credentials
|
422
443
|
def self.listProjects(credentials = nil)
|
423
444
|
cfg = credConfig(credentials)
|
@@ -575,6 +596,19 @@ module MU
|
|
575
596
|
end
|
576
597
|
end
|
577
598
|
|
599
|
+
# Google's Cloud Resource Manager API V2, which apparently has all the folder bits
|
600
|
+
# @param subclass [<Google::Apis::CloudresourcemanagerV2beta1>]: If specified, will return the class ::Google::Apis::CloudresourcemanagerV2beta1::subclass instead of an API client instance
|
601
|
+
def self.folder(subclass = nil, credentials: nil)
|
602
|
+
require 'google/apis/cloudresourcemanager_v2beta1'
|
603
|
+
|
604
|
+
if subclass.nil?
|
605
|
+
@@resource2_api[credentials] ||= MU::Cloud::Google::Endpoint.new(api: "CloudresourcemanagerV2beta1::CloudResourceManagerService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
606
|
+
return @@resource2_api[credentials]
|
607
|
+
elsif subclass.is_a?(Symbol)
|
608
|
+
return Object.const_get("::Google").const_get("Apis").const_get("CloudresourcemanagerV2beta1").const_get(subclass)
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
578
612
|
# Google's Container API
|
579
613
|
# @param subclass [<Google::Apis::ContainerV1>]: If specified, will return the class ::Google::Apis::ContainerV1::subclass instead of an API client instance
|
580
614
|
def self.container(subclass = nil, credentials: nil)
|
@@ -909,6 +943,7 @@ module MU
|
|
909
943
|
@@iam_api = {}
|
910
944
|
@@logging_api = {}
|
911
945
|
@@resource_api = {}
|
946
|
+
@@resource2_api = {}
|
912
947
|
@@service_api = {}
|
913
948
|
@@admin_directory_api = {}
|
914
949
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# Copyright:: Copyright (c) 2019 eGlobalTech, Inc., all rights reserved
|
2
|
+
#
|
3
|
+
# Licensed under the BSD-3 license (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License in the root of the project or at
|
6
|
+
#
|
7
|
+
# http://egt-labs.com/mu/LICENSE.html
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module MU
|
16
|
+
class Cloud
|
17
|
+
class Google
|
18
|
+
# Creates an Google project as configured in {MU::Config::BasketofKittens::folders}
|
19
|
+
class Folder < MU::Cloud::Folder
|
20
|
+
@deploy = nil
|
21
|
+
@config = nil
|
22
|
+
|
23
|
+
attr_reader :mu_name
|
24
|
+
attr_reader :config
|
25
|
+
attr_reader :cloud_id
|
26
|
+
|
27
|
+
# @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
|
28
|
+
# @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::folders}
|
29
|
+
def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
|
30
|
+
@deploy = mommacat
|
31
|
+
@config = MU::Config.manxify(kitten_cfg)
|
32
|
+
@cloud_id ||= cloud_id
|
33
|
+
@mu_name ||= @deploy.getResourceName(@config["name"])
|
34
|
+
end
|
35
|
+
|
36
|
+
# Called automatically by {MU::Deploy#createResources}
|
37
|
+
def create
|
38
|
+
|
39
|
+
name_string = @deploy.getResourceName(@config["name"], max_length: 30).downcase
|
40
|
+
|
41
|
+
folder_obj = MU::Cloud::Google.folder(:Folder).new(
|
42
|
+
name: name_string,
|
43
|
+
display_name: name_string
|
44
|
+
)
|
45
|
+
pp folder_obj
|
46
|
+
MU.log "Creating folder #{@mu_name}", details: folder_obj
|
47
|
+
resp = MU::Cloud::Google.folder(credentials: @config['credentials']).create_folder(folder_obj)
|
48
|
+
|
49
|
+
@cloud_id = name_string.downcase
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return the cloud descriptor for the Folder
|
53
|
+
def cloud_desc
|
54
|
+
MU::Cloud::Google::Folder.find(cloud_id: @cloud_id).values.first
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return the metadata for this project's configuration
|
58
|
+
# @return [Hash]
|
59
|
+
def notify
|
60
|
+
desc = MU.structToHash(MU::Cloud::Google.folder(credentials: credentials).get_folder(@cloud_id))
|
61
|
+
desc["mu_name"] = @mu_name
|
62
|
+
desc["cloud_id"] = @cloud_id
|
63
|
+
desc
|
64
|
+
end
|
65
|
+
|
66
|
+
# Does this resource type exist as a global (cloud-wide) artifact, or
|
67
|
+
# is it localized to a region/zone?
|
68
|
+
# @return [Boolean]
|
69
|
+
def self.isGlobal?
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
# Remove all Google projects associated with the currently loaded deployment. Try to, anyway.
|
74
|
+
# @param noop [Boolean]: If true, will only print what would be done
|
75
|
+
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
76
|
+
# @param region [String]: The cloud provider region
|
77
|
+
# @return [void]
|
78
|
+
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
79
|
+
end
|
80
|
+
|
81
|
+
# Locate an existing project
|
82
|
+
# @param cloud_id [String]: The cloud provider's identifier for this resource.
|
83
|
+
# @param region [String]: The cloud provider region.
|
84
|
+
# @param flags [Hash]: Optional flags
|
85
|
+
# @return [OpenStruct]: The cloud provider's complete descriptions of matching project
|
86
|
+
def self.find(cloud_id: nil, region: MU.curRegion, credentials: nil, flags: {})
|
87
|
+
found = {}
|
88
|
+
if cloud_id
|
89
|
+
found[cloud_id] = MU::Cloud::Google.folder(credentials: credentials).get_folder(cloud_id)
|
90
|
+
else
|
91
|
+
end
|
92
|
+
|
93
|
+
found
|
94
|
+
end
|
95
|
+
|
96
|
+
# Cloud-specific configuration properties.
|
97
|
+
# @param config [MU::Config]: The calling MU::Config object
|
98
|
+
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
99
|
+
def self.schema(config)
|
100
|
+
toplevel_required = []
|
101
|
+
schema = {
|
102
|
+
}
|
103
|
+
[toplevel_required, schema]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::folders}, bare and unvalidated.
|
107
|
+
# @param folder [Hash]: The resource to process and validate
|
108
|
+
# @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
109
|
+
# @return [Boolean]: True if validation succeeded, False otherwise
|
110
|
+
def self.validateConfig(folder, configurator)
|
111
|
+
ok = true
|
112
|
+
|
113
|
+
|
114
|
+
ok
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -35,6 +35,31 @@ module MU
|
|
35
35
|
|
36
36
|
# Called automatically by {MU::Deploy#createResources}
|
37
37
|
def create
|
38
|
+
labels = {}
|
39
|
+
|
40
|
+
name_string = @deploy.getResourceName(@config["name"], max_length: 30).downcase
|
41
|
+
|
42
|
+
MU::MommaCat.listStandardTags.each_pair { |name, value|
|
43
|
+
if !value.nil?
|
44
|
+
labels[name.downcase] = value.downcase.gsub(/[^a-z0-9\-\_]/i, "_")
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
desc = {
|
49
|
+
name: name_string,
|
50
|
+
project_id: name_string,
|
51
|
+
labels: labels
|
52
|
+
}
|
53
|
+
if @config['folder'] and @config['folder']['id']
|
54
|
+
desc["parent"] = @config['folder']['id']
|
55
|
+
end
|
56
|
+
|
57
|
+
project_obj = MU::Cloud::Google.resource_manager(:Project).new(desc)
|
58
|
+
pp project_obj
|
59
|
+
MU.log "Creating project #{@mu_name}", details: project_obj
|
60
|
+
resp = MU::Cloud::Google.resource_manager(credentials: @config['credentials']).create_project(project_obj)
|
61
|
+
|
62
|
+
@cloud_id = name_string.downcase
|
38
63
|
end
|
39
64
|
|
40
65
|
# Return the cloud descriptor for the Habitat
|
@@ -42,17 +67,15 @@ module MU
|
|
42
67
|
MU::Cloud::Google::Habitat.find(cloud_id: @cloud_id).values.first
|
43
68
|
end
|
44
69
|
|
45
|
-
# Canonical Amazon Resource Number for this resource
|
46
|
-
# @return [String]
|
47
|
-
def arn
|
48
|
-
nil
|
49
|
-
end
|
50
|
-
|
51
70
|
# Return the metadata for this project's configuration
|
52
71
|
# @return [Hash]
|
53
72
|
def notify
|
54
|
-
|
55
|
-
|
73
|
+
desc = MU.structToHash(MU::Cloud::Google.resource_manager(credentials: credentials).list_projects(
|
74
|
+
filter: "name:#{cloud_id}"
|
75
|
+
).projects.first)
|
76
|
+
desc["mu_name"] = @mu_name
|
77
|
+
desc["cloud_id"] = @cloud_id
|
78
|
+
desc
|
56
79
|
end
|
57
80
|
|
58
81
|
# Does this resource type exist as a global (cloud-wide) artifact, or
|
@@ -76,7 +99,20 @@ module MU
|
|
76
99
|
# @param flags [Hash]: Optional flags
|
77
100
|
# @return [OpenStruct]: The cloud provider's complete descriptions of matching project
|
78
101
|
def self.find(cloud_id: nil, region: MU.curRegion, credentials: nil, flags: {})
|
79
|
-
{}
|
102
|
+
found = {}
|
103
|
+
if cloud_id
|
104
|
+
resp = MU::Cloud::Google.resource_manager(credentials: credentials).list_projects(
|
105
|
+
filter: "name:#{cloud_id}"
|
106
|
+
).projects.first
|
107
|
+
found[resp.name] = resp
|
108
|
+
else
|
109
|
+
resp = MU::Cloud::Google.resource_manager(credentials: credentials).list_projects().projects
|
110
|
+
resp.each { |p|
|
111
|
+
found[p.name] = p
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
found
|
80
116
|
end
|
81
117
|
|
82
118
|
# Cloud-specific configuration properties.
|
@@ -96,6 +132,14 @@ module MU
|
|
96
132
|
def self.validateConfig(habitat, configurator)
|
97
133
|
ok = true
|
98
134
|
|
135
|
+
if habitat['folder'] and habitat['folder']['name'] and !habitat['folder']['deploy_id']
|
136
|
+
habitat["dependencies"] ||= []
|
137
|
+
habitat["dependencies"] << {
|
138
|
+
"type" => "folder",
|
139
|
+
"name" => habitat['folder']['name']
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
99
143
|
ok
|
100
144
|
end
|
101
145
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloud-mu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.pre.
|
4
|
+
version: 2.0.0.pre.alpha4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Stange
|
@@ -863,6 +863,7 @@ files:
|
|
863
863
|
- modules/mu/clouds/google/container_cluster.rb
|
864
864
|
- modules/mu/clouds/google/database.rb
|
865
865
|
- modules/mu/clouds/google/firewall_rule.rb
|
866
|
+
- modules/mu/clouds/google/folder.rb
|
866
867
|
- modules/mu/clouds/google/group.rb
|
867
868
|
- modules/mu/clouds/google/habitat.rb
|
868
869
|
- modules/mu/clouds/google/loadbalancer.rb
|