cloud-mu 3.1.4 → 3.3.1
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 +4 -4
- data/Dockerfile +5 -1
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +16 -12
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- 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-node-manage +15 -16
- data/bin/mu-run-tests +37 -12
- data/cloud-mu.gemspec +5 -3
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +1 -1
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/modules/mommacat.ru +1 -1
- data/modules/mu.rb +158 -107
- data/modules/mu/adoption.rb +386 -59
- data/modules/mu/cleanup.rb +214 -303
- data/modules/mu/cloud.rb +128 -1632
- 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 +926 -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 +169 -0
- data/modules/mu/config.rb +135 -82
- 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 +7 -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 +5 -6
- 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 +92 -14
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +38 -37
- data/modules/mu/config/search_domain.rb +1 -1
- data/modules/mu/config/server.rb +12 -13
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +3 -7
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +11 -0
- data/modules/mu/config/user.rb +1 -1
- data/modules/mu/config/vpc.rb +27 -23
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +91 -68
- 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 +16 -1
- data/modules/mu/groomers/ansible.rb +123 -21
- data/modules/mu/groomers/chef.rb +64 -11
- data/modules/mu/logger.rb +120 -144
- data/modules/mu/master.rb +97 -4
- data/modules/mu/master/ssl.rb +0 -1
- data/modules/mu/mommacat.rb +154 -867
- data/modules/mu/mommacat/daemon.rb +23 -14
- data/modules/mu/mommacat/naming.rb +110 -3
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +225 -192
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +281 -64
- 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 +708 -749
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +75 -57
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +212 -242
- data/modules/mu/{clouds → providers}/aws/folder.rb +1 -1
- data/modules/mu/{clouds → providers}/aws/function.rb +289 -134
- 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 +466 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +50 -41
- 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 +94 -57
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +173 -42
- data/modules/mu/{clouds → providers}/aws/server.rb +782 -1107
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +36 -46
- 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 +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +429 -849
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +13 -0
- 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 +10 -0
- 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 +29 -6
- data/modules/mu/{clouds → providers}/google/bucket.rb +5 -5
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +59 -37
- data/modules/mu/{clouds → providers}/google/database.rb +5 -12
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +5 -5
- data/modules/mu/{clouds → providers}/google/folder.rb +5 -9
- data/modules/mu/{clouds → providers}/google/function.rb +14 -8
- 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 +5 -5
- data/modules/mu/{clouds → providers}/google/role.rb +50 -31
- data/modules/mu/{clouds → providers}/google/server.rb +142 -55
- data/modules/mu/{clouds → providers}/google/server_pool.rb +14 -14
- data/modules/mu/{clouds → providers}/google/user.rb +34 -24
- 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 +46 -15
- 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 +23 -0
- 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/includes-and-params.yaml +2 -1
- 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 +2 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +3 -5
- data/modules/tests/win2k12.yaml +25 -0
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +169 -93
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1974
- data/modules/mu/clouds/aws/endpoint.rb +0 -596
- data/modules/tests/needwork/win2k12.yaml +0 -13
|
@@ -61,7 +61,7 @@ module MU
|
|
|
61
61
|
if @config['parent']['name'] and !@config['parent']['id']
|
|
62
62
|
@config['parent']['deploy_id'] = @deploy.deploy_id
|
|
63
63
|
end
|
|
64
|
-
parent = MU::Cloud
|
|
64
|
+
parent = MU::Cloud.resourceClass("Google", "Folder").resolveParent(@config['parent'], credentials: @config['credentials'])
|
|
65
65
|
if !parent
|
|
66
66
|
MU.log "Unable to resolve parent resource of Google Project #{@config['name']}", MU::ERR, details: @config['parent']
|
|
67
67
|
raise "Unable to resolve parent resource of Google Project #{@config['name']}"
|
|
@@ -222,7 +222,7 @@ module MU
|
|
|
222
222
|
# @param noop [Boolean]: If true, will only print what would be done
|
|
223
223
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
224
224
|
# @return [void]
|
|
225
|
-
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
|
225
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, credentials: nil, flags: {})
|
|
226
226
|
resp = MU::Cloud::Google.resource_manager(credentials: credentials).list_projects
|
|
227
227
|
|
|
228
228
|
if resp and resp.projects
|
|
@@ -285,7 +285,7 @@ module MU
|
|
|
285
285
|
next if p.lifecycle_state == "DELETE_REQUESTED"
|
|
286
286
|
found[p.project_id] = p
|
|
287
287
|
}
|
|
288
|
-
@@list_projects_cache = found
|
|
288
|
+
@@list_projects_cache = found.clone
|
|
289
289
|
end
|
|
290
290
|
|
|
291
291
|
found
|
|
@@ -376,11 +376,7 @@ module MU
|
|
|
376
376
|
end
|
|
377
377
|
|
|
378
378
|
if habitat['parent'] and habitat['parent']['name'] and !habitat['parent']['deploy_id'] and configurator.haveLitterMate?(habitat['parent']['name'], "folders")
|
|
379
|
-
habitat[
|
|
380
|
-
habitat["dependencies"] << {
|
|
381
|
-
"type" => "folder",
|
|
382
|
-
"name" => habitat['parent']['name']
|
|
383
|
-
}
|
|
379
|
+
MU::Config.addDependency(habitat, habitat['parent']['name'], "folder")
|
|
384
380
|
end
|
|
385
381
|
|
|
386
382
|
ok
|
|
@@ -146,9 +146,9 @@ module MU
|
|
|
146
146
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
147
147
|
# @param region [String]: The cloud provider region
|
|
148
148
|
# @return [void]
|
|
149
|
-
def self.cleanup(noop: false, ignoremaster: false, region: nil, credentials: nil, flags: {})
|
|
150
|
-
flags["
|
|
151
|
-
return if !MU::Cloud
|
|
149
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: nil, credentials: nil, flags: {})
|
|
150
|
+
flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
|
|
151
|
+
return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
|
|
152
152
|
filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
|
|
153
153
|
if !ignoremaster and MU.mu_public_ip
|
|
154
154
|
filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
|
|
@@ -159,7 +159,7 @@ module MU
|
|
|
159
159
|
["forwarding_rule", "region_backend_service"].each { |type|
|
|
160
160
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
|
161
161
|
type,
|
|
162
|
-
flags["
|
|
162
|
+
flags["habitat"],
|
|
163
163
|
region,
|
|
164
164
|
noop
|
|
165
165
|
)
|
|
@@ -170,7 +170,7 @@ module MU
|
|
|
170
170
|
["global_forwarding_rule", "target_http_proxy", "target_https_proxy", "url_map", "backend_service", "health_check", "http_health_check", "https_health_check"].each { |type|
|
|
171
171
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
|
172
172
|
type,
|
|
173
|
-
flags["
|
|
173
|
+
flags["habitat"],
|
|
174
174
|
nil,
|
|
175
175
|
noop
|
|
176
176
|
)
|
|
@@ -271,13 +271,13 @@ module MU
|
|
|
271
271
|
my_org = MU::Cloud::Google.getOrg(credentials)
|
|
272
272
|
if my_org
|
|
273
273
|
scopes["organizations"] = [my_org.name]
|
|
274
|
-
folders = MU::Cloud
|
|
274
|
+
folders = MU::Cloud.resourceClass("Google", "Folder").find(credentials: credentials)
|
|
275
275
|
if folders and folders.size > 0
|
|
276
276
|
scopes["folders"] = folders.keys
|
|
277
277
|
end
|
|
278
278
|
end
|
|
279
279
|
|
|
280
|
-
projects = MU::Cloud
|
|
280
|
+
projects = MU::Cloud.resourceClass("Google", "Habitat").find(credentials: credentials)
|
|
281
281
|
if projects and projects.size > 0
|
|
282
282
|
scopes["projects"] = projects.keys
|
|
283
283
|
end
|
|
@@ -407,12 +407,12 @@ module MU
|
|
|
407
407
|
# email field (which is the "real" id most of the time)
|
|
408
408
|
real_id = nil
|
|
409
409
|
if entity_type == "group"
|
|
410
|
-
found = MU::Cloud
|
|
410
|
+
found = MU::Cloud.resourceClass("Google", "Group").find(cloud_id: entity_id, credentials: credentials)
|
|
411
411
|
if found[entity_id]
|
|
412
412
|
real_id = found[entity_id].id
|
|
413
413
|
end
|
|
414
414
|
elsif entity_type == "user"
|
|
415
|
-
found = MU::Cloud
|
|
415
|
+
found = MU::Cloud.resourceClass("Google", "User").find(cloud_id: entity_id, credentials: credentials)
|
|
416
416
|
if found[entity_id]
|
|
417
417
|
real_id = found[entity_id].id
|
|
418
418
|
end
|
|
@@ -465,7 +465,7 @@ module MU
|
|
|
465
465
|
# @param noop [Boolean]: If true, will only print what would be done
|
|
466
466
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
467
467
|
# @return [void]
|
|
468
|
-
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
|
468
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, credentials: nil, flags: {})
|
|
469
469
|
customer = MU::Cloud::Google.customerID(credentials)
|
|
470
470
|
my_org = MU::Cloud::Google.getOrg(credentials)
|
|
471
471
|
|
|
@@ -563,7 +563,7 @@ module MU
|
|
|
563
563
|
if args[:project]
|
|
564
564
|
canned = Hash[MU::Cloud::Google.iam(credentials: args[:credentials]).list_roles.roles.map { |r| [r.name, r] }]
|
|
565
565
|
begin
|
|
566
|
-
MU::Cloud
|
|
566
|
+
MU::Cloud.resourceClass("Google", "Habitat").bindings(args[:project], credentials: args[:credentials]).each { |binding|
|
|
567
567
|
found[binding.role] = canned[binding.role]
|
|
568
568
|
}
|
|
569
569
|
rescue ::Google::Apis::ClientError => e
|
|
@@ -591,10 +591,15 @@ module MU
|
|
|
591
591
|
bindings['by_scope']['projects'][args[:project]]
|
|
592
592
|
bindings['by_scope']['projects'][args[:project]].keys.each { |r|
|
|
593
593
|
if r.match(/^roles\//)
|
|
594
|
-
|
|
595
|
-
|
|
594
|
+
begin
|
|
595
|
+
role = MU::Cloud::Google.iam(credentials: args[:credentials]).get_role(r)
|
|
596
|
+
found[role.name] = role
|
|
597
|
+
rescue ::Google::Apis::ClientError => e
|
|
598
|
+
raise e if !e.message.match(/(?:forbidden|notFound): /)
|
|
599
|
+
MU.log "Failed MU::Cloud::Google.iam(credentials: #{args[:credentials]}).get_role(#{r})", MU::WARN, details: e.message
|
|
600
|
+
end
|
|
596
601
|
elsif !found[r]
|
|
597
|
-
MU.log "NEED TO GET #{r}", MU::WARN
|
|
602
|
+
# MU.log "NEED TO GET #{r}", MU::WARN
|
|
598
603
|
end
|
|
599
604
|
}
|
|
600
605
|
end
|
|
@@ -688,7 +693,7 @@ module MU
|
|
|
688
693
|
ids, _names, _privs = MU::Cloud::Google::Role.privilege_service_to_name(@config['credentials'])
|
|
689
694
|
cloud_desc.role_privileges.each { |priv|
|
|
690
695
|
if !ids[priv.service_id]
|
|
691
|
-
MU.log "Role privilege defined for a service id with no name I can find, writing with raw id", MU::
|
|
696
|
+
MU.log "Role privilege defined for a service id with no name I can find, writing with raw id", MU::DEBUG, details: priv
|
|
692
697
|
bok["import"] << priv.service_id+"/"+priv.privilege_name
|
|
693
698
|
else
|
|
694
699
|
bok["import"] << ids[priv.service_id]+"/"+priv.privilege_name
|
|
@@ -731,26 +736,45 @@ module MU
|
|
|
731
736
|
bindings[scopetype].each_pair { |scope_id, entity_types|
|
|
732
737
|
# If we've been given a habitat filter, skip over bindings
|
|
733
738
|
# that don't match it.
|
|
734
|
-
if scopetype == "projects"
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
739
|
+
if scopetype == "projects"
|
|
740
|
+
if (args[:habitats] and !args[:habitats].empty? and
|
|
741
|
+
!args[:habitats].include?(scope_id)) or
|
|
742
|
+
!MU::Cloud::Google.listHabitats(@credentials).include?(scope_id)
|
|
743
|
+
next
|
|
744
|
+
end
|
|
738
745
|
end
|
|
739
746
|
|
|
740
747
|
entity_types.each_pair { |entity_type, entities|
|
|
741
748
|
mu_entitytype = (entity_type == "serviceAccount" ? "user" : entity_type)+"s"
|
|
742
749
|
entities.each { |entity|
|
|
750
|
+
next if entity.nil?
|
|
751
|
+
foreign = if entity_type == "serviceAccount" and entity.match(/@(.*?)\.iam\.gserviceaccount\.com/)
|
|
752
|
+
!MU::Cloud::Google.listHabitats(@credentials).include?(Regexp.last_match[1])
|
|
753
|
+
end
|
|
754
|
+
|
|
743
755
|
entity_ref = if entity_type == "organizations"
|
|
744
756
|
{ "id" => ((org == my_org.name and @config['credentials']) ? @config['credentials'] : org) }
|
|
745
757
|
elsif entity_type == "domain"
|
|
746
758
|
{ "id" => entity }
|
|
747
759
|
else
|
|
760
|
+
shortclass, _cfg_name, _cfg_plural, _classname = MU::Cloud.getResourceNames(mu_entitytype)
|
|
761
|
+
if args[:types].include?(shortclass) and
|
|
762
|
+
!(entity_type == "serviceAccount" and
|
|
763
|
+
MU::Cloud::Google::User.cannedServiceAcctName?(entity))
|
|
764
|
+
MU.log "Role #{@cloud_id}: Skipping #{shortclass} binding for #{entity}; we are adopting that type and will set bindings from that resource", MU::DEBUG
|
|
765
|
+
next
|
|
766
|
+
end
|
|
767
|
+
|
|
748
768
|
MU::Config::Ref.get(
|
|
749
769
|
id: entity,
|
|
750
770
|
cloud: "Google",
|
|
751
771
|
type: mu_entitytype
|
|
752
772
|
)
|
|
753
773
|
end
|
|
774
|
+
if entity_ref.nil?
|
|
775
|
+
MU.log "I somehow ended up with a nil entity reference for #{entity_type} #{entity}", MU::ERR, details: [ bok, bindings ]
|
|
776
|
+
next
|
|
777
|
+
end
|
|
754
778
|
refmap ||= {}
|
|
755
779
|
refmap[entity_ref] ||= {}
|
|
756
780
|
refmap[entity_ref][scopetype] ||= []
|
|
@@ -769,6 +793,7 @@ module MU
|
|
|
769
793
|
}
|
|
770
794
|
}
|
|
771
795
|
}
|
|
796
|
+
|
|
772
797
|
bok["bindings"] ||= []
|
|
773
798
|
refmap.each_pair { |entity, scopes|
|
|
774
799
|
newbinding = { "entity" => entity }
|
|
@@ -891,7 +916,7 @@ module MU
|
|
|
891
916
|
end
|
|
892
917
|
|
|
893
918
|
role = MU::Cloud::Google.admin_directory(credentials: credentials).get_role(MU::Cloud::Google.customerID(credentials), binding.role_id)
|
|
894
|
-
MU.log "Failed to find entity #{binding.assigned_to} referenced in GSuite/Cloud Identity binding to role #{role.role_name}", MU::
|
|
919
|
+
MU.log "Failed to find entity #{binding.assigned_to} referenced in GSuite/Cloud Identity binding to role #{role.role_name}", MU::DEBUG, details: role
|
|
895
920
|
}
|
|
896
921
|
|
|
897
922
|
resp = MU::Cloud::Google.resource_manager(credentials: credentials).get_organization_iam_policy(my_org.name)
|
|
@@ -899,15 +924,17 @@ module MU
|
|
|
899
924
|
insertBinding("organizations", my_org.name, binding)
|
|
900
925
|
}
|
|
901
926
|
|
|
902
|
-
MU::Cloud
|
|
903
|
-
MU::Cloud
|
|
927
|
+
MU::Cloud.resourceClass("Google", "Folder").find(credentials: credentials).keys.each { |folder|
|
|
928
|
+
folder_bindings = MU::Cloud.resourceClass("Google", "Folder").bindings(folder, credentials: credentials)
|
|
929
|
+
next if !folder_bindings
|
|
930
|
+
folder_bindings.each { |binding|
|
|
904
931
|
insertBinding("folders", folder, binding)
|
|
905
932
|
}
|
|
906
933
|
}
|
|
907
934
|
end
|
|
908
|
-
MU::Cloud::Google
|
|
935
|
+
MU::Cloud::Google.listHabitats(credentials).each { |project|
|
|
909
936
|
begin
|
|
910
|
-
MU::Cloud
|
|
937
|
+
MU::Cloud.resourceClass("Google", "Habitat").bindings(project, credentials: credentials).each { |binding|
|
|
911
938
|
insertBinding("projects", project, binding)
|
|
912
939
|
}
|
|
913
940
|
rescue ::Google::Apis::ClientError => e
|
|
@@ -1090,7 +1117,7 @@ If this value is not specified, and the role name matches the name of an existin
|
|
|
1090
1117
|
MU.log "None of the directory service privileges available to credentials #{role['credentials']} map to the ones declared for role #{role['name']}", MU::ERR, details: role['import'].sort
|
|
1091
1118
|
ok = false
|
|
1092
1119
|
elsif missing.size > 0
|
|
1093
|
-
MU.log "Some directory service privileges declared for role #{role['name']} aren't available to credentials #{role['credentials']}, will skip", MU::
|
|
1120
|
+
MU.log "Some directory service privileges declared for role #{role['name']} aren't available to credentials #{role['credentials']}, will skip", MU::DEBUG, details: missing
|
|
1094
1121
|
end
|
|
1095
1122
|
end
|
|
1096
1123
|
end
|
|
@@ -1105,11 +1132,7 @@ If this value is not specified, and the role name matches the name of an existin
|
|
|
1105
1132
|
if role['role_source'] == "project"
|
|
1106
1133
|
role['project'] ||= MU::Cloud::Google.defaultProject(role['credentials'])
|
|
1107
1134
|
if configurator.haveLitterMate?(role['project'], "habitats")
|
|
1108
|
-
role['
|
|
1109
|
-
role['dependencies'] << {
|
|
1110
|
-
"type" => "habitat",
|
|
1111
|
-
"name" => role['project']
|
|
1112
|
-
}
|
|
1135
|
+
MU::Config.addDependency(role, role['project'], "habitat")
|
|
1113
1136
|
end
|
|
1114
1137
|
end
|
|
1115
1138
|
|
|
@@ -1117,14 +1140,10 @@ If this value is not specified, and the role name matches the name of an existin
|
|
|
1117
1140
|
role['bindings'].each { |binding|
|
|
1118
1141
|
if binding['entity'] and binding['entity']['name'] and
|
|
1119
1142
|
configurator.haveLitterMate?(binding['entity']['name'], binding['entity']['type'])
|
|
1120
|
-
role['
|
|
1121
|
-
role['dependencies'] << {
|
|
1122
|
-
"type" => binding['entity']['type'].sub(/s$/, ''),
|
|
1123
|
-
"name" => binding['entity']['name']
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1143
|
+
MU::Config.addDependency(role, binding['entity']['name'], binding['entity']['type'])
|
|
1126
1144
|
end
|
|
1127
1145
|
}
|
|
1146
|
+
role['bindings'].uniq!
|
|
1128
1147
|
end
|
|
1129
1148
|
|
|
1130
1149
|
ok
|
|
@@ -164,19 +164,26 @@ module MU
|
|
|
164
164
|
def self.diskConfig(config, create = true, disk_as_url = true, credentials: nil)
|
|
165
165
|
disks = []
|
|
166
166
|
if config['image_id'].nil? and config['basis'].nil?
|
|
167
|
-
pp config.keys
|
|
168
167
|
raise MuError, "Can't generate disk configuration for server #{config['name']} without an image ID or basis specified"
|
|
169
168
|
end
|
|
170
169
|
|
|
171
170
|
img = fetchImage(config['image_id'] || config['basis']['launch_config']['image_id'], credentials: credentials)
|
|
172
171
|
|
|
173
|
-
#
|
|
172
|
+
# if img.source_disk and img.source_disk.match(/projects\/([^\/]+)\/zones\/([^\/]+)\/disks\/(.*)/)
|
|
173
|
+
# _junk, proj, az, name = Regexp.last_match
|
|
174
|
+
# disk_desc = MU::Cloud::Google.compute(credentials: credentials).get_disk(proj, az, name)
|
|
175
|
+
# pp disk_desc
|
|
176
|
+
# raise "nah"
|
|
177
|
+
# end
|
|
178
|
+
|
|
174
179
|
disktype = "projects/#{config['project']}/zones/#{config['availability_zone']}/diskTypes/pd-standard"
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
disktype.gsub!(/.*?\/([^\/])$/, '\1') if !disk_as_url
|
|
183
|
+
|
|
177
184
|
imageobj = MU::Cloud::Google.compute(:AttachedDiskInitializeParams).new(
|
|
178
185
|
source_image: img.self_link,
|
|
179
|
-
disk_size_gb:
|
|
186
|
+
disk_size_gb: img.disk_size_gb,
|
|
180
187
|
disk_type: disktype,
|
|
181
188
|
)
|
|
182
189
|
disks << MU::Cloud::Google.compute(:AttachedDisk).new(
|
|
@@ -329,7 +336,7 @@ next if !create
|
|
|
329
336
|
end
|
|
330
337
|
metadata["startup-script"] = @userdata if @userdata and !@userdata.empty?
|
|
331
338
|
|
|
332
|
-
deploykey = @config[
|
|
339
|
+
deploykey = @config["ssh_user"]+":"+@deploy.ssh_public_key
|
|
333
340
|
if metadata["ssh-keys"]
|
|
334
341
|
metadata["ssh-keys"] += "\n"+deploykey
|
|
335
342
|
else
|
|
@@ -485,7 +492,7 @@ next if !create
|
|
|
485
492
|
return nil if @config.nil? or @deploy.nil?
|
|
486
493
|
|
|
487
494
|
nat_ssh_key = nat_ssh_user = nat_ssh_host = nil
|
|
488
|
-
if !@config["vpc"].nil? and !MU::Cloud
|
|
495
|
+
if !@config["vpc"].nil? and !MU::Cloud.resourceClass("Google", "VPC").haveRouteToInstance?(cloud_desc, credentials: @config['credentials'])
|
|
489
496
|
|
|
490
497
|
if !@nat.nil?
|
|
491
498
|
if @nat.cloud_desc.nil?
|
|
@@ -502,7 +509,8 @@ next if !create
|
|
|
502
509
|
|
|
503
510
|
if @config['ssh_user'].nil?
|
|
504
511
|
if windows?
|
|
505
|
-
@config['ssh_user'] =
|
|
512
|
+
@config['ssh_user'] = @config['windows_admin_user']
|
|
513
|
+
@config['ssh_user'] ||= "Administrator"
|
|
506
514
|
else
|
|
507
515
|
@config['ssh_user'] = "root"
|
|
508
516
|
end
|
|
@@ -615,7 +623,7 @@ next if !create
|
|
|
615
623
|
end
|
|
616
624
|
|
|
617
625
|
_nat_ssh_key, _nat_ssh_user, nat_ssh_host, _canonical_ip, _ssh_user, _ssh_key_name = getSSHConfig
|
|
618
|
-
if !nat_ssh_host and !MU::Cloud
|
|
626
|
+
if !nat_ssh_host and !MU::Cloud.resourceClass("Google", "VPC").haveRouteToInstance?(cloud_desc, credentials: @config['credentials'])
|
|
619
627
|
# XXX check if canonical_ip is in the private ranges
|
|
620
628
|
# raise MuError, "#{node} has no NAT host configured, and I have no other route to it"
|
|
621
629
|
end
|
|
@@ -800,29 +808,6 @@ next if !create
|
|
|
800
808
|
|
|
801
809
|
# punchAdminNAT
|
|
802
810
|
|
|
803
|
-
# MU::Cloud::AWS::Server.tagVolumes(@cloud_id)
|
|
804
|
-
|
|
805
|
-
# If we have a loadbalancer configured, attach us to it
|
|
806
|
-
# if !@config['loadbalancers'].nil?
|
|
807
|
-
# if @loadbalancers.nil?
|
|
808
|
-
# raise MuError, "#{@mu_name} is configured to use LoadBalancers, but none have been loaded by dependencies()"
|
|
809
|
-
# end
|
|
810
|
-
# @loadbalancers.each { |lb|
|
|
811
|
-
# lb.registerNode(@cloud_id)
|
|
812
|
-
# }
|
|
813
|
-
# end
|
|
814
|
-
|
|
815
|
-
# Let us into any databases we depend on.
|
|
816
|
-
# This is probelmtic with autscaling - old ips are not removed, and access to the database can easily be given at the BoK level
|
|
817
|
-
# if @dependencies.has_key?("database")
|
|
818
|
-
# @dependencies['database'].values.each { |db|
|
|
819
|
-
# db.allowHost(@deploydata["private_ip_address"]+"/32")
|
|
820
|
-
# if @deploydata["public_ip_address"]
|
|
821
|
-
# db.allowHost(@deploydata["public_ip_address"]+"/32")
|
|
822
|
-
# end
|
|
823
|
-
# }
|
|
824
|
-
# end
|
|
825
|
-
|
|
826
811
|
@groomer.saveDeployData
|
|
827
812
|
|
|
828
813
|
begin
|
|
@@ -1007,7 +992,7 @@ next if !create
|
|
|
1007
992
|
# Our deploydata gets corrupted often with server pools, this will cause us to use the wrong IP to identify a node
|
|
1008
993
|
# which will cause us to create certificates, DNS records and other artifacts with incorrect information which will cause our deploy to fail.
|
|
1009
994
|
# The cloud_id is always correct so lets use 'cloud_desc' to get the correct IPs
|
|
1010
|
-
if MU::Cloud
|
|
995
|
+
if MU::Cloud.resourceClass("Google", "VPC").haveRouteToInstance?(cloud_desc, credentials: @config['credentials']) or public_ips.size == 0
|
|
1011
996
|
@config['canonical_ip'] = private_ips.first
|
|
1012
997
|
return private_ips.first
|
|
1013
998
|
else
|
|
@@ -1016,10 +1001,109 @@ next if !create
|
|
|
1016
1001
|
end
|
|
1017
1002
|
end
|
|
1018
1003
|
|
|
1004
|
+
# Return all of the IP addresses, public and private, from all of our
|
|
1005
|
+
# network interfaces.
|
|
1006
|
+
# @return [Array<String>]
|
|
1007
|
+
def listIPs
|
|
1008
|
+
ips = []
|
|
1009
|
+
cloud_desc.network_interfaces.each { |iface|
|
|
1010
|
+
ips << iface.network_ip
|
|
1011
|
+
if iface.access_configs
|
|
1012
|
+
iface.access_configs.each { |acfg|
|
|
1013
|
+
ips << acfg.nat_ip if acfg.nat_ip
|
|
1014
|
+
}
|
|
1015
|
+
end
|
|
1016
|
+
}
|
|
1017
|
+
ips
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1019
1020
|
# return [String]: A password string.
|
|
1020
|
-
def getWindowsAdminPassword
|
|
1021
|
+
def getWindowsAdminPassword(use_cache: true)
|
|
1022
|
+
@config['windows_auth_vault'] ||= {
|
|
1023
|
+
"vault" => @mu_name,
|
|
1024
|
+
"item" => "windows_credentials",
|
|
1025
|
+
"password_field" => "password"
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
if use_cache
|
|
1029
|
+
begin
|
|
1030
|
+
win_admin_password = @groomer.getSecret(
|
|
1031
|
+
vault: @config['windows_auth_vault']['vault'],
|
|
1032
|
+
item: @config['windows_auth_vault']['item'],
|
|
1033
|
+
field: @config["windows_auth_vault"]["password_field"]
|
|
1034
|
+
)
|
|
1035
|
+
return win_admin_password if win_admin_password
|
|
1036
|
+
rescue MU::Groomer::MuNoSuchSecret, MU::Groomer::RunError
|
|
1037
|
+
end
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
require 'openssl/oaep'
|
|
1041
|
+
timeout = 300
|
|
1042
|
+
|
|
1043
|
+
serial_out = nil
|
|
1044
|
+
key = OpenSSL::PKey::RSA.generate 2048
|
|
1045
|
+
|
|
1046
|
+
missing_response = Proc.new {
|
|
1047
|
+
!serial_out or !serial_out.contents or serial_out.contents.empty? or JSON.parse(serial_out.contents)["userName"] != @config['windows_admin_username']
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
did_metadata = false
|
|
1051
|
+
MU.retrier(loop_if: missing_response, wait: 10, max: timeout/10) {
|
|
1052
|
+
serial_out = MU::Cloud::Google.compute(credentials: @credentials).get_instance_serial_port_output(@project_id, @config['availability_zone'], @cloud_id, port: 4)
|
|
1053
|
+
|
|
1054
|
+
if missing_response.call and
|
|
1055
|
+
!cloud_desc(use_cache: false).metadata.items.map { |i| i.key }.include?("windows-keys")
|
|
1056
|
+
keybytes = Base64.decode64(key.public_key.export.gsub(/-----(?:BEGIN|END) PUBLIC KEY-----/, ''))
|
|
1057
|
+
modulus = keybytes.byteslice(33,256)
|
|
1058
|
+
exponent = keybytes.byteslice(291,3)
|
|
1059
|
+
keydata = {
|
|
1060
|
+
"userName" => @config['windows_admin_username'],
|
|
1061
|
+
"modulus" => Base64.strict_encode64(modulus),
|
|
1062
|
+
"exponent" => Base64.strict_encode64(exponent),
|
|
1063
|
+
"email" => MU.muCfg['mu_admin_email'],
|
|
1064
|
+
"expireOn" => (Time.now.utc+timeout).strftime('%Y-%m-%dT%H:%M:%SZ')
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
new_items = cloud_desc.metadata.items.map { |item|
|
|
1068
|
+
MU::Cloud::Google.compute(:Metadata)::Item.new(
|
|
1069
|
+
key: item.key,
|
|
1070
|
+
value: item.value
|
|
1071
|
+
)
|
|
1072
|
+
}
|
|
1073
|
+
new_items.reject! { |item| item.key == "windows-keys" }
|
|
1074
|
+
new_items << MU::Cloud::Google.compute(:Metadata)::Item.new(
|
|
1075
|
+
key: "windows-keys",
|
|
1076
|
+
value: JSON.generate(keydata)
|
|
1077
|
+
)
|
|
1078
|
+
new_metadata = MU::Cloud::Google.compute(:Metadata).new(
|
|
1079
|
+
fingerprint: cloud_desc(use_cache: false).metadata.fingerprint,
|
|
1080
|
+
items: new_items
|
|
1081
|
+
)
|
|
1082
|
+
|
|
1083
|
+
MU::Cloud::Google.compute(credentials: @credentials).set_instance_metadata(@project_id, @config['availability_zone'], @cloud_id, new_metadata)
|
|
1084
|
+
end
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
return nil if missing_response.call
|
|
1088
|
+
|
|
1089
|
+
pwdata = JSON.parse(serial_out.contents)
|
|
1090
|
+
if pwdata['encryptedPassword'] and pwdata['userName'] == @config['windows_admin_username']
|
|
1091
|
+
decrypted_pw = key.private_decrypt_oaep(Base64.strict_decode64(pwdata['encryptedPassword']))
|
|
1092
|
+
creds = {
|
|
1093
|
+
"username" => @config['windows_admin_username'],
|
|
1094
|
+
"password" => decrypted_pw,
|
|
1095
|
+
"sshd_username" => "sshd_service",
|
|
1096
|
+
"sshd_password" => decrypted_pw
|
|
1097
|
+
}
|
|
1098
|
+
@groomer.saveSecret(vault: @mu_name, item: "windows_credentials", data: creds, permissions: "name:#{@mu_name}")
|
|
1099
|
+
|
|
1100
|
+
return decrypted_pw
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
nil
|
|
1021
1104
|
end
|
|
1022
1105
|
|
|
1106
|
+
|
|
1023
1107
|
# Add a volume to this instance
|
|
1024
1108
|
# @param dev [String]: Device name to use when attaching to instance
|
|
1025
1109
|
# @param size [String]: Size (in gb) of the new volume
|
|
@@ -1206,9 +1290,9 @@ next if !create
|
|
|
1206
1290
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
1207
1291
|
# @param region [String]: The cloud provider region
|
|
1208
1292
|
# @return [void]
|
|
1209
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
1210
|
-
flags["
|
|
1211
|
-
return if !MU::Cloud
|
|
1293
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
1294
|
+
flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
|
|
1295
|
+
return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
|
|
1212
1296
|
|
|
1213
1297
|
# XXX make damn sure MU.deploy_id is set
|
|
1214
1298
|
filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
|
|
@@ -1219,13 +1303,12 @@ next if !create
|
|
|
1219
1303
|
MU::Cloud::Google.listAZs(region).each { |az|
|
|
1220
1304
|
disks = []
|
|
1221
1305
|
resp = MU::Cloud::Google.compute(credentials: credentials).list_instances(
|
|
1222
|
-
flags["
|
|
1306
|
+
flags["habitat"],
|
|
1223
1307
|
az,
|
|
1224
1308
|
filter: filter
|
|
1225
1309
|
)
|
|
1226
1310
|
if !resp.items.nil? and resp.items.size > 0
|
|
1227
1311
|
resp.items.each { |instance|
|
|
1228
|
-
saname = instance.tags.items.first.gsub(/[^a-z]/, "") # XXX this nonsense again
|
|
1229
1312
|
MU.log "Terminating instance #{instance.name}"
|
|
1230
1313
|
if !instance.disks.nil? and instance.disks.size > 0
|
|
1231
1314
|
instance.disks.each { |disk|
|
|
@@ -1233,17 +1316,21 @@ next if !create
|
|
|
1233
1316
|
}
|
|
1234
1317
|
end
|
|
1235
1318
|
MU::Cloud::Google.compute(credentials: credentials).delete_instance(
|
|
1236
|
-
flags["
|
|
1319
|
+
flags["habitat"],
|
|
1237
1320
|
az,
|
|
1238
1321
|
instance.name
|
|
1239
1322
|
) if !noop
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1323
|
+
if instance.service_accounts
|
|
1324
|
+
instance.service_accounts.each { |sa|
|
|
1325
|
+
MU.log "Removing service account #{sa.email}"
|
|
1326
|
+
begin
|
|
1327
|
+
MU::Cloud::Google.iam(credentials: credentials).delete_project_service_account(
|
|
1328
|
+
"projects/#{flags["habitat"]}/serviceAccounts/#{sa.email}"
|
|
1329
|
+
) if !noop
|
|
1330
|
+
rescue ::Google::Apis::ClientError => e
|
|
1331
|
+
raise e if !e.message.match(/^notFound: /)
|
|
1332
|
+
end
|
|
1333
|
+
}
|
|
1247
1334
|
end
|
|
1248
1335
|
# XXX wait-loop on pending?
|
|
1249
1336
|
# pp deletia
|
|
@@ -1256,7 +1343,7 @@ next if !create
|
|
|
1256
1343
|
# XXX honor snapshotting
|
|
1257
1344
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
|
1258
1345
|
"disk",
|
|
1259
|
-
flags["
|
|
1346
|
+
flags["habitat"],
|
|
1260
1347
|
az,
|
|
1261
1348
|
noop
|
|
1262
1349
|
) if !noop
|
|
@@ -1269,10 +1356,10 @@ next if !create
|
|
|
1269
1356
|
def self.schema(config)
|
|
1270
1357
|
toplevel_required = []
|
|
1271
1358
|
schema = {
|
|
1272
|
-
"roles" => MU::Cloud
|
|
1359
|
+
"roles" => MU::Cloud.resourceClass("Google", "User").schema(config)[1]["roles"],
|
|
1273
1360
|
"windows_admin_username" => {
|
|
1274
1361
|
"type" => "string",
|
|
1275
|
-
"default" => "
|
|
1362
|
+
"default" => "muadmin"
|
|
1276
1363
|
},
|
|
1277
1364
|
"create_image" => {
|
|
1278
1365
|
"properties" => {
|
|
@@ -1380,8 +1467,7 @@ next if !create
|
|
|
1380
1467
|
foundmatch = false
|
|
1381
1468
|
MU::Cloud.availableClouds.each { |cloud|
|
|
1382
1469
|
next if cloud == "Google"
|
|
1383
|
-
|
|
1384
|
-
foreign_types = (cloudbase.listInstanceTypes).values.first
|
|
1470
|
+
foreign_types = (MU::Cloud.cloudClass(cloud).listInstanceTypes).values.first
|
|
1385
1471
|
if foreign_types.size == 1
|
|
1386
1472
|
foreign_types = foreign_types.values.first
|
|
1387
1473
|
end
|
|
@@ -1438,6 +1524,7 @@ next if !create
|
|
|
1438
1524
|
end
|
|
1439
1525
|
|
|
1440
1526
|
if server['service_account']
|
|
1527
|
+
server['service_account'] = server['service_account'].to_h
|
|
1441
1528
|
server['service_account']['cloud'] = "Google"
|
|
1442
1529
|
server['service_account']['habitat'] ||= server['project']
|
|
1443
1530
|
found = MU::Config::Ref.get(server['service_account'])
|
|
@@ -1446,12 +1533,12 @@ next if !create
|
|
|
1446
1533
|
ok = false
|
|
1447
1534
|
end
|
|
1448
1535
|
else
|
|
1449
|
-
server = MU::Cloud
|
|
1536
|
+
server = MU::Cloud.resourceClass("Google", "User").genericServiceAccount(server, configurator)
|
|
1450
1537
|
end
|
|
1451
1538
|
|
|
1452
1539
|
subnets = nil
|
|
1453
1540
|
if !server['vpc']
|
|
1454
|
-
vpcs = MU::Cloud
|
|
1541
|
+
vpcs = MU::Cloud.resourceClass("Google", "VPC").find(credentials: server['credentials'])
|
|
1455
1542
|
if vpcs["default"]
|
|
1456
1543
|
server["vpc"] ||= {}
|
|
1457
1544
|
server["vpc"]["vpc_id"] = vpcs["default"].self_link
|
|
@@ -1466,7 +1553,7 @@ next if !create
|
|
|
1466
1553
|
if !server['vpc']['subnet_id'] and server['vpc']['subnet_name'].nil?
|
|
1467
1554
|
if !subnets
|
|
1468
1555
|
if server["vpc"]["vpc_id"]
|
|
1469
|
-
vpcs = MU::Cloud
|
|
1556
|
+
vpcs = MU::Cloud.resourceClass("Google", "VPC").find(cloud_id: server["vpc"]["vpc_id"])
|
|
1470
1557
|
subnets = vpcs["default"].subnetworks.sample
|
|
1471
1558
|
end
|
|
1472
1559
|
end
|