cloud-mu 2.0.0.pre.alpha3 → 2.0.0.pre.alpha4

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: 674e427624161a3b7026346a10320e7dcf5331222d8cc683d186c3d648fc0c77
4
- data.tar.gz: 71c6ddb375bf199f767fa2b8143b98f7de422d6095921c5db0d0cf191bac39bb
3
+ metadata.gz: fc4fa3ace543abb312bf853be83b0b229a61cf4cd1dbb00f7a4ac1c383fe2538
4
+ data.tar.gz: 35ed1769840efedaa2b2408e0f0c24c07417c77aeaf8cb43dd11f758970a9d47
5
5
  SHA512:
6
- metadata.gz: 8cac89b0d850377f39635f40aafc4fe148fc6b38c971da05592a55dba83a7f8847c3734eddbdb830724e2cda51c7c3968c38facd22eab15814b892913641b2ab
7
- data.tar.gz: bce36278c7e00872d5f1f553d41f24abf0593d0a8f1bf076e071d472932e1aa727f196a8e34b37dc4ba3465068420305c3079cd472d9c8a26a9ed65edc06ddc0
6
+ metadata.gz: 38feb71676cf984e102f90e41b96849521762f3cf0bcfc2e06af0b69a45e9255b02ff503f84ca27346dedb501e362b07b26be172cec0e4e118302cd9af5853b9
7
+ data.tar.gz: 2cdacd00b476374c45a94dddf0ee5e60b018200dbf58e34510bef8cb0169ea03a7edc1f7726c7f742304687cdeade991b05a71f40cb0326590e1091e757aada1
data/cloud-mu.gemspec CHANGED
@@ -17,7 +17,7 @@ end
17
17
 
18
18
  Gem::Specification.new do |s|
19
19
  s.name = 'cloud-mu'
20
- s.version = '2.0.0-alpha3'
20
+ s.version = '2.0.0-alpha4'
21
21
  s.date = '2018-12-11'
22
22
  s.require_paths = ['modules']
23
23
  s.required_ruby_version = '>= 2.4'
@@ -6,4 +6,4 @@ metadata
6
6
  # Mu Cookbooks
7
7
 
8
8
  # Supermarket Cookbooks
9
- cookbook 'firewall', '~> 2.6.5'
9
+ cookbook 'firewall', '~> 2.7.0'
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="i_yam_what_i_yam" # GIT HOOK EDITABLE DO NOT TOUCH
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]]
@@ -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$/) and !delete
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
- else
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
@@ -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
@@ -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.alpha3
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