cloud-mu 3.5.0 → 3.6.3
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/Berksfile +5 -2
- data/Berksfile.lock +135 -0
- data/ansible/roles/mu-base/README.md +33 -0
- data/ansible/roles/mu-base/defaults/main.yml +2 -0
- data/ansible/roles/mu-base/files/check_apm.cfg +1 -0
- data/ansible/roles/mu-base/files/check_apm.sh +18 -0
- data/ansible/roles/mu-base/files/check_disk.cfg +1 -0
- data/ansible/roles/mu-base/files/check_elastic_shards.cfg +1 -0
- data/ansible/roles/mu-base/files/check_elastic_shards.sh +12 -0
- data/ansible/roles/mu-base/files/check_logstash.cfg +1 -0
- data/ansible/roles/mu-base/files/check_logstash.sh +14 -0
- data/ansible/roles/mu-base/files/check_mem.cfg +1 -0
- data/ansible/roles/mu-base/files/check_updates.cfg +1 -0
- data/ansible/roles/mu-base/files/logrotate.conf +35 -0
- data/ansible/roles/mu-base/files/nrpe-apm-sudo +1 -0
- data/ansible/roles/mu-base/files/nrpe-elasticshards-sudo +2 -0
- data/ansible/roles/mu-base/handlers/main.yml +5 -0
- data/ansible/roles/mu-base/meta/main.yml +53 -0
- data/ansible/roles/mu-base/tasks/main.yml +113 -0
- data/ansible/roles/mu-base/templates/nrpe.cfg.j2 +231 -0
- data/ansible/roles/mu-base/tests/inventory +2 -0
- data/ansible/roles/mu-base/tests/test.yml +5 -0
- data/ansible/roles/mu-base/vars/main.yml +1 -0
- data/ansible/roles/mu-compliance/README.md +33 -0
- data/ansible/roles/mu-compliance/defaults/main.yml +2 -0
- data/ansible/roles/mu-compliance/files/U_MS_Windows_Server_2016_V2R1_STIG_SCAP_1-2_Benchmark.xml +15674 -0
- data/ansible/roles/mu-compliance/files/U_MS_Windows_Server_2019_V2R1_STIG_SCAP_1-2_Benchmark.xml +17553 -0
- data/ansible/roles/mu-compliance/handlers/main.yml +2 -0
- data/ansible/roles/mu-compliance/meta/main.yml +53 -0
- data/ansible/roles/mu-compliance/tasks/main.yml +45 -0
- data/ansible/roles/mu-compliance/tests/inventory +2 -0
- data/ansible/roles/mu-compliance/tests/test.yml +5 -0
- data/ansible/roles/mu-compliance/vars/main.yml +4 -0
- data/ansible/roles/mu-elastic/README.md +51 -0
- data/ansible/roles/mu-elastic/defaults/main.yml +2 -0
- data/ansible/roles/mu-elastic/files/jvm.options +93 -0
- data/ansible/roles/mu-elastic/handlers/main.yml +10 -0
- data/ansible/roles/mu-elastic/meta/main.yml +52 -0
- data/ansible/roles/mu-elastic/tasks/main.yml +186 -0
- data/ansible/roles/mu-elastic/templates/elasticsearch.yml.j2 +110 -0
- data/ansible/roles/mu-elastic/templates/kibana.yml.j2 +131 -0
- data/ansible/roles/mu-elastic/templates/password_set.expect.j2 +19 -0
- data/ansible/roles/mu-elastic/tests/inventory +2 -0
- data/ansible/roles/mu-elastic/tests/test.yml +5 -0
- data/ansible/roles/mu-elastic/vars/main.yml +2 -0
- data/ansible/roles/mu-logstash/README.md +51 -0
- data/ansible/roles/mu-logstash/defaults/main.yml +2 -0
- data/ansible/roles/mu-logstash/files/02-beats-input.conf +5 -0
- data/ansible/roles/mu-logstash/files/10-rails-filter.conf +16 -0
- data/ansible/roles/mu-logstash/files/jvm.options +84 -0
- data/ansible/roles/mu-logstash/files/logstash.yml +304 -0
- data/ansible/roles/mu-logstash/handlers/main.yml +20 -0
- data/ansible/roles/mu-logstash/meta/main.yml +52 -0
- data/ansible/roles/mu-logstash/tasks/main.yml +254 -0
- data/ansible/roles/mu-logstash/templates/20-cloudtrail.conf.j2 +28 -0
- data/ansible/roles/mu-logstash/templates/30-elasticsearch-output.conf.j2 +19 -0
- data/ansible/roles/mu-logstash/templates/apm-server.yml.j2 +33 -0
- data/ansible/roles/mu-logstash/templates/heartbeat.yml.j2 +29 -0
- data/ansible/roles/mu-logstash/templates/nginx/apm.conf.j2 +25 -0
- data/ansible/roles/mu-logstash/templates/nginx/default.conf.j2 +56 -0
- data/ansible/roles/mu-logstash/templates/nginx/elastic.conf.j2 +27 -0
- data/ansible/roles/mu-logstash/tests/inventory +2 -0
- data/ansible/roles/mu-logstash/tests/test.yml +5 -0
- data/ansible/roles/mu-logstash/vars/main.yml +2 -0
- data/ansible/roles/mu-rdp/README.md +33 -0
- data/ansible/roles/mu-rdp/meta/main.yml +53 -0
- data/ansible/roles/mu-rdp/tasks/main.yml +9 -0
- data/ansible/roles/mu-rdp/tests/inventory +2 -0
- data/ansible/roles/mu-rdp/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/tasks/main.yml +3 -0
- data/bin/mu-ansible-secret +1 -1
- data/bin/mu-aws-setup +4 -3
- data/bin/mu-azure-setup +5 -5
- data/bin/mu-configure +25 -17
- data/bin/mu-firewall-allow-clients +1 -0
- data/bin/mu-gcp-setup +3 -3
- data/bin/mu-load-config.rb +1 -0
- data/bin/mu-node-manage +66 -33
- data/bin/mu-self-update +2 -2
- data/bin/mu-upload-chef-artifacts +6 -1
- data/bin/mu-user-manage +1 -1
- data/cloud-mu.gemspec +25 -23
- data/cookbooks/firewall/CHANGELOG.md +417 -224
- data/cookbooks/firewall/LICENSE +202 -0
- data/cookbooks/firewall/README.md +153 -126
- data/cookbooks/firewall/TODO.md +6 -0
- data/cookbooks/firewall/attributes/firewalld.rb +7 -0
- data/cookbooks/firewall/attributes/iptables.rb +3 -3
- data/cookbooks/firewall/chefignore +115 -0
- data/cookbooks/firewall/libraries/helpers.rb +5 -0
- data/cookbooks/firewall/libraries/helpers_firewalld.rb +1 -1
- data/cookbooks/firewall/libraries/helpers_firewalld_dbus.rb +72 -0
- data/cookbooks/firewall/libraries/helpers_iptables.rb +3 -3
- data/cookbooks/firewall/libraries/helpers_nftables.rb +170 -0
- data/cookbooks/firewall/libraries/helpers_ufw.rb +7 -0
- data/cookbooks/firewall/libraries/helpers_windows.rb +8 -9
- data/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +9 -9
- data/cookbooks/firewall/libraries/provider_firewall_iptables.rb +7 -7
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +12 -8
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +13 -9
- data/cookbooks/firewall/libraries/provider_firewall_rule.rb +1 -1
- data/cookbooks/firewall/libraries/provider_firewall_ufw.rb +5 -5
- data/cookbooks/firewall/libraries/provider_firewall_windows.rb +4 -4
- data/cookbooks/firewall/libraries/resource_firewall_rule.rb +3 -3
- data/cookbooks/firewall/metadata.json +40 -1
- data/cookbooks/firewall/metadata.rb +15 -0
- data/cookbooks/firewall/recipes/default.rb +7 -7
- data/cookbooks/firewall/recipes/disable_firewall.rb +1 -1
- data/cookbooks/firewall/recipes/firewalld.rb +87 -0
- data/cookbooks/firewall/renovate.json +18 -0
- data/cookbooks/firewall/resources/firewalld.rb +28 -0
- data/cookbooks/firewall/resources/firewalld_config.rb +39 -0
- data/cookbooks/firewall/resources/firewalld_helpers.rb +106 -0
- data/cookbooks/firewall/resources/firewalld_icmptype.rb +88 -0
- data/cookbooks/firewall/resources/firewalld_ipset.rb +104 -0
- data/cookbooks/firewall/resources/firewalld_policy.rb +115 -0
- data/cookbooks/firewall/resources/firewalld_service.rb +98 -0
- data/cookbooks/firewall/resources/firewalld_zone.rb +118 -0
- data/cookbooks/firewall/resources/nftables.rb +71 -0
- data/cookbooks/firewall/resources/nftables_rule.rb +113 -0
- data/cookbooks/mu-activedirectory/Berksfile +1 -1
- data/cookbooks/mu-activedirectory/metadata.rb +1 -1
- data/cookbooks/mu-firewall/metadata.rb +2 -2
- data/cookbooks/mu-master/Berksfile +4 -3
- data/cookbooks/mu-master/attributes/default.rb +5 -2
- data/cookbooks/mu-master/files/default/check_elastic.sh +761 -0
- data/cookbooks/mu-master/files/default/check_kibana.rb +45 -0
- data/cookbooks/mu-master/libraries/mu.rb +24 -0
- data/cookbooks/mu-master/metadata.rb +5 -5
- data/cookbooks/mu-master/recipes/default.rb +31 -20
- data/cookbooks/mu-master/recipes/firewall-holes.rb +5 -0
- data/cookbooks/mu-master/recipes/init.rb +58 -19
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +251 -178
- data/cookbooks/mu-master/templates/default/nagios.conf.erb +5 -11
- data/cookbooks/mu-master/templates/default/web_app.conf.erb +3 -0
- data/cookbooks/mu-php54/Berksfile +1 -1
- data/cookbooks/mu-php54/metadata.rb +2 -2
- data/cookbooks/mu-tools/Berksfile +2 -3
- data/cookbooks/mu-tools/attributes/default.rb +3 -4
- data/cookbooks/mu-tools/files/amazon/etc/bashrc +90 -0
- data/cookbooks/mu-tools/files/amazon/etc/login.defs +292 -0
- data/cookbooks/mu-tools/files/amazon/etc/profile +77 -0
- data/cookbooks/mu-tools/files/amazon/etc/security/limits.conf +63 -0
- data/cookbooks/mu-tools/files/amazon/etc/sysconfig/init +19 -0
- data/cookbooks/mu-tools/files/amazon/etc/sysctl.conf +82 -0
- data/cookbooks/mu-tools/files/amazon-2023/etc/login.defs +294 -0
- data/cookbooks/mu-tools/files/default/logrotate.conf +35 -0
- data/cookbooks/mu-tools/files/default/nrpe_conf_d.pp +0 -0
- data/cookbooks/mu-tools/libraries/helper.rb +21 -9
- data/cookbooks/mu-tools/metadata.rb +4 -4
- data/cookbooks/mu-tools/recipes/apply_security.rb +3 -2
- data/cookbooks/mu-tools/recipes/aws_api.rb +23 -5
- data/cookbooks/mu-tools/recipes/base_repositories.rb +4 -1
- data/cookbooks/mu-tools/recipes/gcloud.rb +56 -56
- data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
- data/cookbooks/mu-tools/recipes/nrpe.rb +20 -2
- data/cookbooks/mu-tools/recipes/rsyslog.rb +12 -1
- data/cookbooks/mu-tools/recipes/set_local_fw.rb +1 -1
- data/data_bags/nagios_services/apm_backend_connect.json +5 -0
- data/data_bags/nagios_services/apm_listen.json +5 -0
- data/data_bags/nagios_services/elastic_shards.json +5 -0
- data/data_bags/nagios_services/logstash.json +5 -0
- data/data_bags/nagios_services/rhel7_updates.json +8 -0
- data/extras/image-generators/AWS/centos7.yaml +1 -0
- data/extras/image-generators/AWS/rhel7.yaml +21 -0
- data/extras/image-generators/AWS/win2k12r2.yaml +1 -0
- data/extras/image-generators/AWS/win2k16.yaml +1 -0
- data/extras/image-generators/AWS/win2k19.yaml +1 -0
- data/extras/list-stock-amis +0 -0
- data/extras/ruby_rpm/muby.spec +8 -5
- data/extras/vault_tools/export_vaults.sh +1 -1
- data/extras/vault_tools/recreate_vaults.sh +0 -0
- data/extras/vault_tools/test_vaults.sh +0 -0
- data/install/deprecated-bash-library.sh +1 -1
- data/install/installer +4 -2
- data/modules/mommacat.ru +3 -1
- data/modules/mu/adoption.rb +1 -1
- data/modules/mu/cloud/dnszone.rb +2 -2
- data/modules/mu/cloud/machine_images.rb +26 -25
- data/modules/mu/cloud/resource_base.rb +213 -182
- data/modules/mu/cloud/server_pool.rb +1 -1
- data/modules/mu/cloud/ssh_sessions.rb +7 -5
- data/modules/mu/cloud/wrappers.rb +2 -2
- data/modules/mu/cloud.rb +1 -1
- data/modules/mu/config/bucket.rb +1 -1
- data/modules/mu/config/function.rb +6 -1
- data/modules/mu/config/loadbalancer.rb +24 -2
- data/modules/mu/config/ref.rb +12 -0
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +42 -9
- data/modules/mu/config/server.rb +43 -27
- data/modules/mu/config/tail.rb +19 -10
- data/modules/mu/config.rb +6 -5
- data/modules/mu/defaults/AWS.yaml +78 -114
- data/modules/mu/deploy.rb +9 -2
- data/modules/mu/groomer.rb +12 -4
- data/modules/mu/groomers/ansible.rb +104 -20
- data/modules/mu/groomers/chef.rb +15 -6
- data/modules/mu/master.rb +9 -4
- data/modules/mu/mommacat/daemon.rb +4 -2
- data/modules/mu/mommacat/naming.rb +1 -2
- data/modules/mu/mommacat/storage.rb +7 -2
- data/modules/mu/mommacat.rb +33 -6
- data/modules/mu/providers/aws/database.rb +161 -8
- data/modules/mu/providers/aws/dnszone.rb +11 -6
- data/modules/mu/providers/aws/endpoint.rb +81 -6
- data/modules/mu/providers/aws/firewall_rule.rb +254 -172
- data/modules/mu/providers/aws/function.rb +65 -3
- data/modules/mu/providers/aws/loadbalancer.rb +39 -28
- data/modules/mu/providers/aws/log.rb +2 -1
- data/modules/mu/providers/aws/role.rb +25 -7
- data/modules/mu/providers/aws/server.rb +36 -12
- data/modules/mu/providers/aws/server_pool.rb +237 -127
- data/modules/mu/providers/aws/storage_pool.rb +7 -1
- data/modules/mu/providers/aws/user.rb +1 -1
- data/modules/mu/providers/aws/userdata/linux.erb +6 -2
- data/modules/mu/providers/aws/userdata/windows.erb +7 -5
- data/modules/mu/providers/aws/vpc.rb +49 -25
- data/modules/mu/providers/aws.rb +13 -8
- data/modules/mu/providers/azure/container_cluster.rb +1 -1
- data/modules/mu/providers/azure/loadbalancer.rb +2 -2
- data/modules/mu/providers/azure/server.rb +5 -2
- data/modules/mu/providers/azure/userdata/linux.erb +1 -1
- data/modules/mu/providers/azure.rb +11 -8
- data/modules/mu/providers/cloudformation/dnszone.rb +1 -1
- data/modules/mu/providers/google/container_cluster.rb +15 -2
- data/modules/mu/providers/google/folder.rb +2 -1
- data/modules/mu/providers/google/function.rb +130 -4
- data/modules/mu/providers/google/habitat.rb +2 -1
- data/modules/mu/providers/google/loadbalancer.rb +407 -160
- data/modules/mu/providers/google/role.rb +16 -3
- data/modules/mu/providers/google/server.rb +5 -1
- data/modules/mu/providers/google/user.rb +25 -18
- data/modules/mu/providers/google/userdata/linux.erb +1 -1
- data/modules/mu/providers/google/vpc.rb +53 -7
- data/modules/mu/providers/google.rb +39 -39
- data/modules/mu.rb +8 -8
- data/modules/tests/elk.yaml +46 -0
- data/test/mu-master-test/controls/all_in_one.rb +1 -1
- metadata +207 -112
- data/cookbooks/firewall/CONTRIBUTING.md +0 -2
- data/cookbooks/firewall/MAINTAINERS.md +0 -19
- data/cookbooks/firewall/libraries/matchers.rb +0 -30
- data/extras/image-generators/AWS/rhel71.yaml +0 -17
|
@@ -19,7 +19,6 @@ module MU
|
|
|
19
19
|
class LoadBalancer < MU::Cloud::LoadBalancer
|
|
20
20
|
|
|
21
21
|
@lb = nil
|
|
22
|
-
attr_reader :targetgroups
|
|
23
22
|
|
|
24
23
|
# Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like <tt>@vpc</tt>, for us.
|
|
25
24
|
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
|
@@ -39,13 +38,17 @@ module MU
|
|
|
39
38
|
@config['targetgroups'].each { |tg|
|
|
40
39
|
threads << Thread.new {
|
|
41
40
|
MU.dupGlobals(parent_thread_id)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
vpc_obj = myVpc(tg['vpc']).first if tg['vpc'] # XXX inherit top-level vpc config if it's set
|
|
42
|
+
|
|
43
|
+
# if !@config['private'] or ["INTERNAL_MANAGED", "INTERNAL_SELF_MANAGED"].include?(@config['scheme'])
|
|
44
|
+
backends[tg['name']] = if ["EXTERNAL", "EXTERNAL_MANAGED", "INTERNAL_MANAGED", "INTERNAL_SELF_MANAGED"].include?(@config['scheme'])
|
|
45
|
+
createBackendService(tg)
|
|
46
|
+
else
|
|
47
|
+
createBackendService(tg, region: @config['region'])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
targets[tg['name']] = createProxy(tg, backends[tg['name']], region: (@config['global'] ? nil : @config['region']))
|
|
51
|
+
# end
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
threads.each do |t|
|
|
@@ -53,30 +56,40 @@ module MU
|
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
|
|
59
|
+
@cloud_id = @mu_name
|
|
56
60
|
@config["listeners"].each { |l|
|
|
57
|
-
ruleobj =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
ip_protocol: realproto,
|
|
67
|
-
port_range: l['lb_port'].to_s
|
|
68
|
-
)
|
|
61
|
+
ruleobj = ::Google::Apis::ComputeV1::ForwardingRule.new(
|
|
62
|
+
name: MU::Cloud::Google.nameStr(@mu_name+"-"+l['targetgroup']),
|
|
63
|
+
description: @deploy.deploy_id,
|
|
64
|
+
load_balancing_scheme: @config['scheme']
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if ["INTERNAL_MANAGED", "INTERNAL_SELF_MANAGED"].include?(@config['scheme'])
|
|
68
|
+
ruleobj.ip_protocol = "TCP"
|
|
69
|
+
ruleobj.all_ports = true
|
|
69
70
|
else
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ports: [l['lb_port'].to_s]
|
|
78
|
-
)
|
|
71
|
+
if @config["private"]
|
|
72
|
+
ruleobj.ports = [l['lb_port'].to_s]
|
|
73
|
+
ruleobj.ip_protocol = l['lb_protocol']
|
|
74
|
+
else
|
|
75
|
+
ruleobj.ip_protocol = ["HTTP", "HTTPS"].include?(l['lb_protocol']) ? l['lb_protocol'] : "TCP"
|
|
76
|
+
ruleobj.port_range = l['lb_port'].to_s
|
|
77
|
+
end
|
|
79
78
|
end
|
|
79
|
+
|
|
80
|
+
if @config['private'] and l['vpc'] # XXX inherit top-level vpc config if it's set
|
|
81
|
+
vpc_obj, _n = myVpc(l['vpc'])
|
|
82
|
+
ruleobj.network = vpc_obj.url.sub(/^.*?\/projects\//, 'projects/')
|
|
83
|
+
ruleobj.subnetwork = mySubnets(vpc_obj, l["vpc"]).first.url
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if targets[l['targetgroup']]
|
|
87
|
+
ruleobj.target = targets[l['targetgroup']].self_link
|
|
88
|
+
else
|
|
89
|
+
ruleobj.backend_service = backends[l['targetgroup']].self_link
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
@cloud_desc_cache ||= {}
|
|
80
93
|
if @config['global']
|
|
81
94
|
MU.log "Creating Global Forwarding Rule #{@mu_name}", MU::NOTICE, details: ruleobj
|
|
82
95
|
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_global_forwarding_rule(
|
|
@@ -84,6 +97,7 @@ module MU
|
|
|
84
97
|
ruleobj
|
|
85
98
|
)
|
|
86
99
|
else
|
|
100
|
+
ruleobj.network_tier = "STANDARD"
|
|
87
101
|
MU.log "Creating regional Forwarding Rule #{@mu_name} in #{@config['region']}", MU::NOTICE, details: ruleobj
|
|
88
102
|
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_forwarding_rule(
|
|
89
103
|
@project_id,
|
|
@@ -95,25 +109,83 @@ module MU
|
|
|
95
109
|
|
|
96
110
|
end
|
|
97
111
|
|
|
112
|
+
# Called automatically by {MU::Deploy#createResources}
|
|
113
|
+
def groom
|
|
114
|
+
if @config['targetgroups']
|
|
115
|
+
@config['targetgroups'].each { |tg|
|
|
116
|
+
if tg['target']
|
|
117
|
+
backend_name = MU::Cloud::Google.nameStr(@deploy.getResourceName(tg["name"]))
|
|
118
|
+
serverless = (tg['target']['type'] == "functions")
|
|
119
|
+
region_arg = (serverless or !@config['global']) ? @config['region'] : nil
|
|
120
|
+
neg_desc = createNetworkEndpointGroup(tg['name'], tg['target'], region: region_arg)
|
|
121
|
+
registerTarget(neg_desc.self_link, backends: [backend_name], serverless: serverless)
|
|
122
|
+
end
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
cloud_desc.each_pair { |rule, desc|
|
|
127
|
+
MU.log "LoadBalancer #{@config['name']} (#{rule}) is at #{desc.ip_address}", MU::SUMMARY
|
|
128
|
+
}
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
@cloud_desc_cache = nil
|
|
132
|
+
@backend_cache = nil
|
|
133
|
+
# Return the cloud descriptor for this LoadBalancer, or specifically
|
|
134
|
+
# its forwarding rule(s) since there's really no one artifact.
|
|
135
|
+
# @return [Google::Apis::Core::Hashable]
|
|
136
|
+
def cloud_desc(use_cache: true)
|
|
137
|
+
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
|
138
|
+
rules = {}
|
|
139
|
+
|
|
140
|
+
@config["listeners"].each { |l|
|
|
141
|
+
name = MU::Cloud::Google.nameStr(@cloud_id+"-"+l['targetgroup'])
|
|
142
|
+
rule = if @config['global']
|
|
143
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).get_global_forwarding_rule(
|
|
144
|
+
@project_id,
|
|
145
|
+
name
|
|
146
|
+
)
|
|
147
|
+
else
|
|
148
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).get_forwarding_rule(
|
|
149
|
+
@project_id,
|
|
150
|
+
@config['region'],
|
|
151
|
+
name
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
rule = rule.first if !rule.respond_to?(:name)
|
|
155
|
+
rules[rule.name] = rule
|
|
156
|
+
if rule.respond_to?(:backend_service) and !rule.backend_service.nil?
|
|
157
|
+
@backend_cache ||= []
|
|
158
|
+
@backend_cache << rule.backend_service.gsub(/.*?\//, '')
|
|
159
|
+
elsif rule.respond_to?(:target) and !rule.target.nil?
|
|
160
|
+
proxy = self.class.desc_from_url(rule.target, @project_id, credentials: @credentials)
|
|
161
|
+
if proxy.respond_to?(:url_map) and !proxy.url_map.nil?
|
|
162
|
+
urlmap = self.class.desc_from_url(proxy.url_map, @project_id, credentials: @credentials)
|
|
163
|
+
if urlmap.respond_to?(:default_service) and !urlmap.default_service.nil?
|
|
164
|
+
backend = self.class.desc_from_url(urlmap.default_service, @project_id, credentials: @credentials)
|
|
165
|
+
@backend_cache ||= []
|
|
166
|
+
@backend_cache << backend
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
}
|
|
171
|
+
rules = nil if rules.empty?
|
|
172
|
+
@backend_cache.uniq! if @backend_cache
|
|
173
|
+
@cloud_desc_cache = rules
|
|
174
|
+
|
|
175
|
+
rules
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
|
|
98
179
|
# Return the metadata for this LoadBalancer
|
|
99
180
|
# @return [Hash]
|
|
100
181
|
def notify
|
|
182
|
+
descs = cloud_desc(use_cache: false).dup
|
|
101
183
|
rules = {}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
resp = MU::Cloud::Google.compute(credentials: @config['credentials']).list_forwarding_rules(
|
|
108
|
-
@project_id,
|
|
109
|
-
@config['region'],
|
|
110
|
-
filter: "description eq #{@deploy.deploy_id}"
|
|
111
|
-
)
|
|
112
|
-
end
|
|
113
|
-
if !resp.nil? and !resp.items.nil?
|
|
114
|
-
resp.items.each { |rule|
|
|
115
|
-
rules[rule.name] = rule.to_h
|
|
116
|
-
rules[rule.name].delete(:label_fingerprint)
|
|
184
|
+
if descs
|
|
185
|
+
descs.each_pair { |name, rule|
|
|
186
|
+
rules[name] = MU.structToHash(rule, stringify_keys: true)
|
|
187
|
+
rules[name].delete("label_fingerprint")
|
|
188
|
+
rules[name].delete("fingerprint")
|
|
117
189
|
}
|
|
118
190
|
end
|
|
119
191
|
rules["project_id"] = @project_id
|
|
@@ -123,16 +195,42 @@ module MU
|
|
|
123
195
|
|
|
124
196
|
# Register a Server node with an existing LoadBalancer.
|
|
125
197
|
#
|
|
126
|
-
# @param
|
|
127
|
-
# @param
|
|
128
|
-
def
|
|
198
|
+
# @param target [String] A node or URL or something to register.
|
|
199
|
+
# @param backends [Array<String>] The target group(s) of which this node should be made a member.
|
|
200
|
+
def registerTarget(target, backends: nil, serverless: false)
|
|
201
|
+
cloud_desc
|
|
202
|
+
|
|
203
|
+
@backend_cache.each { |b|
|
|
204
|
+
next if backends and !backends.include?(b.name)
|
|
205
|
+
|
|
206
|
+
b.backends ||= []
|
|
207
|
+
if serverless
|
|
208
|
+
b.health_checks = []
|
|
209
|
+
b.timeout_sec = nil
|
|
210
|
+
b.port_name = nil
|
|
211
|
+
end
|
|
212
|
+
next if b.backends.map { |ext| ext.group }.include?(target)
|
|
213
|
+
b.backends << MU::Cloud::Google.compute(:Backend).new(
|
|
214
|
+
group: target
|
|
215
|
+
)
|
|
216
|
+
MU.log "Adding target #{target} to backend service #{b.name}", details: b
|
|
217
|
+
b.self_link =~ /\/projects\/[^\/]+\/([^\/]+)\/backendServices/
|
|
218
|
+
region = Regexp.last_match[1] == "global" ? nil : Regexp.last_match[1]
|
|
219
|
+
method = "update_#{region ? "region_" : ""}backend_service".to_sym
|
|
220
|
+
args = [@project_id]
|
|
221
|
+
args << region if region
|
|
222
|
+
args << b.name
|
|
223
|
+
args << b
|
|
224
|
+
MU::Cloud::Google.compute(credentials: @credentials).send(method, *args)
|
|
225
|
+
}
|
|
226
|
+
|
|
129
227
|
end
|
|
130
228
|
|
|
131
229
|
# Does this resource type exist as a global (cloud-wide) artifact, or
|
|
132
230
|
# is it localized to a region/zone?
|
|
133
231
|
# @return [Boolean]
|
|
134
232
|
def self.isGlobal?
|
|
135
|
-
|
|
233
|
+
false # XXX it's both, actually
|
|
136
234
|
end
|
|
137
235
|
|
|
138
236
|
# Denote whether this resource implementation is experiment, ready for
|
|
@@ -148,34 +246,59 @@ module MU
|
|
|
148
246
|
# @return [void]
|
|
149
247
|
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: nil, credentials: nil, flags: {})
|
|
150
248
|
flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
|
|
249
|
+
|
|
151
250
|
return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
|
|
152
|
-
filter =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
251
|
+
filter = "description eq #{deploy_id}" # most of these objects don't support labels
|
|
252
|
+
# filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
|
|
253
|
+
# if !ignoremaster and MU.mu_public_ip
|
|
254
|
+
# filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
|
|
255
|
+
# end
|
|
256
|
+
|
|
156
257
|
MU.log "Placeholder: Google LoadBalancer artifacts do not support labels, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: filter
|
|
157
258
|
|
|
158
|
-
if
|
|
159
|
-
|
|
259
|
+
# if flags['global']
|
|
260
|
+
# XXX network_endpoint_group is actually a zonal artifact, ugh
|
|
261
|
+
# resp = MU::Cloud::Google.compute(credentials: credentials).list_network_endpoint_groups(flags["habitat"], filter: "description eq #{deploy_id}")
|
|
262
|
+
# if resp and resp.items
|
|
263
|
+
# resp.items.each { |neg|
|
|
264
|
+
# MU.log "Removing Network Endpoint Group #{neg.name}"
|
|
265
|
+
# MU::Cloud::Google.compute(credentials: credentials).delete_network_endpoint_group(flags["habitat"], neg.name) if !noop
|
|
266
|
+
# }
|
|
267
|
+
# end
|
|
268
|
+
|
|
269
|
+
["global_forwarding_rule", "target_tcp_proxy", "target_grpc_proxy", "target_ssl_proxy", "target_http_proxy", "target_https_proxy", "url_map", "backend_service", "health_check", "http_health_check", "https_health_check"].each { |type|
|
|
160
270
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
|
161
271
|
type,
|
|
162
272
|
flags["habitat"],
|
|
163
|
-
|
|
164
|
-
noop
|
|
273
|
+
nil,
|
|
274
|
+
noop,
|
|
275
|
+
filter
|
|
165
276
|
)
|
|
166
277
|
}
|
|
167
|
-
end
|
|
278
|
+
# end
|
|
279
|
+
|
|
280
|
+
if region
|
|
281
|
+
# Network Endpoint Groups don't have labels, so our deploy id gets
|
|
282
|
+
# shoved into the description.
|
|
283
|
+
resp = MU::Cloud::Google.compute(credentials: credentials).list_region_network_endpoint_groups(flags["habitat"], region, filter: "description eq #{deploy_id}")
|
|
284
|
+
if resp and resp.items
|
|
285
|
+
resp.items.each { |neg|
|
|
286
|
+
MU.log "Removing regional Network Endpoint Group #{neg.name}"
|
|
287
|
+
MU::Cloud::Google.compute(credentials: credentials).delete_region_network_endpoint_group(flags["habitat"], region, neg.name) if !noop
|
|
288
|
+
}
|
|
289
|
+
end
|
|
168
290
|
|
|
169
|
-
|
|
170
|
-
["global_forwarding_rule", "target_http_proxy", "target_https_proxy", "url_map", "backend_service", "health_check", "http_health_check", "https_health_check"].each { |type|
|
|
291
|
+
["forwarding_rule", "region_url_map", "region_backend_service", "region_network_endpoint_group", "region_target_http_proxy", "region_target_https_proxy", "region_health_check"].each { |type|
|
|
171
292
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
|
172
293
|
type,
|
|
173
294
|
flags["habitat"],
|
|
174
|
-
|
|
175
|
-
noop
|
|
295
|
+
region,
|
|
296
|
+
noop,
|
|
297
|
+
filter
|
|
176
298
|
)
|
|
177
299
|
}
|
|
178
300
|
end
|
|
301
|
+
|
|
179
302
|
end
|
|
180
303
|
|
|
181
304
|
# Cloud-specific configuration properties.
|
|
@@ -184,6 +307,29 @@ module MU
|
|
|
184
307
|
def self.schema(_config)
|
|
185
308
|
toplevel_required = []
|
|
186
309
|
schema = {
|
|
310
|
+
"targetgroups" => {
|
|
311
|
+
"items" => {
|
|
312
|
+
"properties" => {
|
|
313
|
+
"proto" => {
|
|
314
|
+
"enum" => ["HTTP", "HTTPS", "TCP", "SSL", "GRPC"]
|
|
315
|
+
},
|
|
316
|
+
"target" => MU::Config::Ref.schema(parent_obj: "loadbalancer", type: "functions"),
|
|
317
|
+
"vpc" => MU::Config::VPC.reference(MU::Config::VPC::ONE_SUBNET, MU::Config::VPC::NO_NAT_OPTS, "public")
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
"listeners" => {
|
|
322
|
+
"items" => {
|
|
323
|
+
"properties" => {
|
|
324
|
+
"vpc" => MU::Config::VPC.reference(MU::Config::VPC::ONE_SUBNET, MU::Config::VPC::NO_NAT_OPTS, "public")
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
"scheme" => {
|
|
329
|
+
"type" => "string",
|
|
330
|
+
"enum" => ["EXTERNAL", "INTERNAL", "INTERNAL_MANAGED", "INTERNAL_SELF_MANAGED"],
|
|
331
|
+
"description" => "Choose +EXTERNAL+ for external HTTP(S), SSL Proxy, TCP Proxy and Network Load Balancing; +INTERNAL+ for Internal TCP/ UDP Load Balancing; +INTERNAL_MANAGED+ for Internal HTTP(S) Load Balancing; +INTERNAL_SELF_MANAGED+ for Traffic Director. If not specified, will default to +EXTERNAL+ or +INTERNAL+ depending on the value of the {private} flag."
|
|
332
|
+
},
|
|
187
333
|
"named_ports" => {
|
|
188
334
|
"type" => "array",
|
|
189
335
|
"items" => {
|
|
@@ -211,6 +357,9 @@ module MU
|
|
|
211
357
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
|
212
358
|
def self.validateConfig(lb, _configurator)
|
|
213
359
|
ok = true
|
|
360
|
+
|
|
361
|
+
lb['region'] ||= MU::Cloud::Google.myRegion(lb['credentials'])
|
|
362
|
+
|
|
214
363
|
if lb['classic']
|
|
215
364
|
MU.log "LoadBalancer 'classic' flag has no meaning in Google Cloud", MU::WARN
|
|
216
365
|
end
|
|
@@ -236,15 +385,19 @@ module MU
|
|
|
236
385
|
end
|
|
237
386
|
|
|
238
387
|
if lb['private'] and lb['global']
|
|
239
|
-
MU.log "Private Google Cloud LoadBalancer requested, setting 'global' flag to false", MU::
|
|
388
|
+
MU.log "Private Google Cloud LoadBalancer requested, setting 'global' flag to false", MU::DEBUG
|
|
240
389
|
lb['global'] = false
|
|
241
390
|
end
|
|
242
391
|
|
|
392
|
+
lb['scheme'] ||= lb['private'] ? "INTERNAL" : "EXTERNAL"
|
|
393
|
+
|
|
243
394
|
lb["listeners"].each { |l|
|
|
244
|
-
if lb["
|
|
245
|
-
MU.log "Only TCP and UDP listeners are valid for private LoadBalancers in Google Cloud", MU::ERR
|
|
246
|
-
ok = false
|
|
395
|
+
if lb['scheme'] == "INTERNAL" and !["TCP", "UDP"].include?(l['lb_protocol'])
|
|
396
|
+
# MU.log "Only TCP and UDP listeners are valid for private LoadBalancers in Google Cloud", MU::ERR
|
|
397
|
+
# ok = false
|
|
247
398
|
end
|
|
399
|
+
l['instance_protocol'] ||= l['lb_protocol']
|
|
400
|
+
l['instance_port'] ||= l['lb_port']
|
|
248
401
|
|
|
249
402
|
if lb['global'] and l['lb_protocol'] == "UDP"
|
|
250
403
|
MU.log "UDP LoadBalancers can only be per-region in Google Cloud. Setting 'global' to false.", MU::WARN
|
|
@@ -256,34 +409,36 @@ module MU
|
|
|
256
409
|
end
|
|
257
410
|
}
|
|
258
411
|
|
|
259
|
-
lb[
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
else
|
|
267
|
-
# health checks are required; create a generic one
|
|
268
|
-
tg["healthcheck"] = {
|
|
269
|
-
"timeout" => 5,
|
|
270
|
-
"interval" => 30,
|
|
271
|
-
"unhealthy_threshold" => 2,
|
|
272
|
-
"healthy_threshold" => 2,
|
|
273
|
-
}
|
|
274
|
-
if tg["proto"] == "HTTP" or tg["proto"] == "HTTPS"
|
|
275
|
-
if lb['private']
|
|
276
|
-
MU.log "Private GCP LoadBalancers can only target TCP or UDP protocols, changing #{tg["proto"]} to TCP", MU::NOTICE
|
|
277
|
-
tg["proto"] = "TCP"
|
|
412
|
+
if lb['scheme'] != "INTERNAL_MANAGED"
|
|
413
|
+
lb["targetgroups"].each { |tg|
|
|
414
|
+
if tg["healthcheck"]
|
|
415
|
+
target = tg["healthcheck"]['target'].match(/^([^:]+):(\d+)(.*)/)
|
|
416
|
+
if tg["proto"] != target[1]
|
|
417
|
+
MU.log "LoadBalancer #{lb['name']} can't mix and match target group and health check protocols in Google Cloud", MU::ERR, details: tg
|
|
418
|
+
ok = false
|
|
278
419
|
end
|
|
279
|
-
tg["healthcheck"]["target"] = tg["proto"]+":"+tg["port"].to_s+"/"
|
|
280
|
-
tg["healthcheck"]["httpcode"] = "200,301,302"
|
|
281
420
|
else
|
|
282
|
-
|
|
421
|
+
# health checks are required; create a generic one
|
|
422
|
+
tg["healthcheck"] = {
|
|
423
|
+
"timeout" => 5,
|
|
424
|
+
"interval" => 30,
|
|
425
|
+
"unhealthy_threshold" => 2,
|
|
426
|
+
"healthy_threshold" => 2,
|
|
427
|
+
}
|
|
428
|
+
if tg["proto"] == "HTTP" or tg["proto"] == "HTTPS"
|
|
429
|
+
if lb['scheme'] == "INTERNAL"
|
|
430
|
+
MU.log "INTERNAL GCP LoadBalancers can only target TCP or UDP protocols, changing #{tg["proto"]} to TCP", MU::NOTICE
|
|
431
|
+
tg["proto"] = "TCP"
|
|
432
|
+
end
|
|
433
|
+
tg["healthcheck"]["target"] = tg["proto"]+":"+tg["port"].to_s+"/"
|
|
434
|
+
tg["healthcheck"]["httpcode"] = "200,301,302"
|
|
435
|
+
else
|
|
436
|
+
tg["healthcheck"]["target"] = tg["proto"]+":"+tg["port"].to_s
|
|
437
|
+
end
|
|
438
|
+
MU.log "No healthcheck declared for target group #{tg['name']} in LoadBalancer #{lb['name']}, creating one.", details: tg
|
|
283
439
|
end
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
440
|
+
}
|
|
441
|
+
end
|
|
287
442
|
|
|
288
443
|
ok
|
|
289
444
|
end
|
|
@@ -296,60 +451,153 @@ module MU
|
|
|
296
451
|
|
|
297
452
|
private
|
|
298
453
|
|
|
299
|
-
|
|
300
|
-
|
|
454
|
+
# Construct the method call to fetch descriptors for various backend
|
|
455
|
+
# components out of the chunks in a URL, as it might be referenced from
|
|
456
|
+
# another resource.
|
|
457
|
+
def self.desc_from_url(url, project_id, credentials: nil)
|
|
458
|
+
regions = MU::Cloud::Google.listRegions + ["global"]
|
|
459
|
+
loc_pattern = "("+regions.map { |r|
|
|
460
|
+
'regions\/'+Regexp.quote(r)
|
|
461
|
+
}.join("|")+"|global)"
|
|
462
|
+
args = []
|
|
463
|
+
resource_name = nil
|
|
464
|
+
url =~ /\/projects\/#{Regexp.quote(project_id)}\/(#{loc_pattern})\//
|
|
465
|
+
location = Regexp.last_match[1]
|
|
466
|
+
global = (location == "global")
|
|
467
|
+
region = global ? nil : location.sub(/regions\//, '')
|
|
468
|
+
|
|
469
|
+
if url =~ /\/#{location}\/target(Https?|Http|Ssl|Grpc|Tcp)Proxies\/([^\/]+)$/i
|
|
470
|
+
proxytype = Regexp.last_match[1]
|
|
471
|
+
resource_name = Regexp.last_match[2]
|
|
472
|
+
args << "get_#{global ? "" : "region_"}target_#{proxytype.downcase}_proxy".to_sym
|
|
473
|
+
elsif url =~ /\/#{location}\/urlMaps\/([^\/]+)$/i
|
|
474
|
+
resource_name = Regexp.last_match[1]
|
|
475
|
+
args << "get_#{global ? "" : "region_"}url_map".to_sym
|
|
476
|
+
elsif url =~ /\/#{location}\/backendServices\/([^\/]+)$/i
|
|
477
|
+
resource_name = Regexp.last_match[1]
|
|
478
|
+
args << "get_#{global ? "" : "region_"}backend_service".to_sym
|
|
479
|
+
else
|
|
480
|
+
MU.log "I don't know how to extract a resource from #{url}", MU::ERR
|
|
481
|
+
end
|
|
482
|
+
args << project_id
|
|
483
|
+
args << region if !global and region
|
|
484
|
+
args << resource_name
|
|
301
485
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
default_service: backend.self_link
|
|
308
|
-
)
|
|
309
|
-
MU.log "Creating url map #{tg['name']}", details: urlmap_obj
|
|
310
|
-
urlmap = MU::Cloud::Google.compute(credentials: @config['credentials']).insert_url_map(
|
|
311
|
-
@project_id,
|
|
312
|
-
urlmap_obj
|
|
313
|
-
)
|
|
486
|
+
MU::Cloud::Google.compute(credentials: credentials).send(*args)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def createProxy(tg, backend, region: nil)
|
|
490
|
+
name = MU::Cloud::Google.nameStr(@deploy.getResourceName(tg["name"]))
|
|
314
491
|
|
|
315
492
|
desc = {
|
|
316
493
|
:name => name,
|
|
317
494
|
:description => @deploy.deploy_id,
|
|
318
|
-
:url_map => urlmap.self_link
|
|
319
495
|
}
|
|
320
496
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
@project_id,
|
|
326
|
-
target_obj
|
|
327
|
-
)
|
|
328
|
-
else
|
|
497
|
+
realproto = @config['scheme'] == "INTERNAL_MANAGED" ? "TCP" : tg['proto']
|
|
498
|
+
proxytype = ("Target"+realproto.capitalize+"Proxy").to_sym
|
|
499
|
+
|
|
500
|
+
if ["HTTPS", "SSL"].include?(realproto)
|
|
329
501
|
certdata = @deploy.nodeSSLCerts(self, false, 2048)
|
|
330
502
|
cert_pem = certdata[0].to_s+File.read("/etc/pki/Mu_CA.pem")
|
|
331
503
|
gcpcert = MU::Cloud::Google.createSSLCertificate(@mu_name.downcase+"-"+tg['name'], cert_pem, certdata[1], credentials: @config['credentials'])
|
|
332
504
|
|
|
333
505
|
# TODO we need a method like MU::Cloud::AWS.findSSLCertificate, with option to hunt down an existing one
|
|
334
506
|
desc[:ssl_certificates] = [gcpcert.self_link]
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
507
|
+
elsif realproto == "TCP"
|
|
508
|
+
desc[:service] = backend.self_link
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
if ["HTTP", "HTTPS"].include?(realproto)
|
|
512
|
+
urlmap_obj = MU::Cloud::Google.compute(:UrlMap).new(
|
|
513
|
+
name: name,
|
|
514
|
+
description: @deploy.deploy_id,
|
|
515
|
+
# TODO this is where path_matchers, host_rules, and tests go (the sophisticated
|
|
516
|
+
# Layer 7 stuff)
|
|
517
|
+
default_service: backend.self_link,
|
|
518
|
+
path_matchers: [MU::Cloud::Google.compute(:PathMatcher).new(
|
|
519
|
+
name: "star",
|
|
520
|
+
default_service: backend.self_link,
|
|
521
|
+
paths: ["*"]
|
|
522
|
+
)],
|
|
523
|
+
host_rules: [MU::Cloud::Google.compute(:HostRule).new(
|
|
524
|
+
hosts: ["*"],
|
|
525
|
+
path_matcher: "star"
|
|
526
|
+
)]
|
|
527
|
+
)
|
|
528
|
+
MU.log "Creating #{region ? region+" " : ""}url map #{tg['name']}", details: urlmap_obj
|
|
529
|
+
|
|
530
|
+
urlmap = if region
|
|
531
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_region_url_map(
|
|
532
|
+
@project_id,
|
|
533
|
+
region,
|
|
534
|
+
urlmap_obj
|
|
535
|
+
)
|
|
536
|
+
else
|
|
537
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_url_map(
|
|
538
|
+
@project_id,
|
|
539
|
+
urlmap_obj
|
|
540
|
+
)
|
|
541
|
+
end
|
|
542
|
+
desc[:url_map] = urlmap.self_link
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
target_obj = MU::Cloud::Google.compute(proxytype).new(desc)
|
|
546
|
+
MU.log "Creating #{region ? region+" " : ""}#{realproto} target proxy #{tg['name']}", details: target_obj
|
|
547
|
+
|
|
548
|
+
if region and ["HTTP", "HTTPS"].include?(realproto)
|
|
549
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).send(("insert_region_target_"+realproto.downcase+"_proxy").to_sym, @project_id, region, target_obj)
|
|
550
|
+
else
|
|
551
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).send(("insert_target_"+realproto.downcase+"_proxy").to_sym, @project_id, target_obj)
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
def createNetworkEndpointGroup(basename, target, region: nil, type: "SERVERLESS", vpc: nil)
|
|
557
|
+
function = MU::Config::Ref.get(target).kitten
|
|
558
|
+
if !function
|
|
559
|
+
MU::Config::Ref.get(target).kitten(debug: true)
|
|
560
|
+
raise MuError.new "Failed to locate Cloud Function from reference", details: target
|
|
561
|
+
end
|
|
562
|
+
neg_name = @deploy.getResourceName(basename, max_length: 19, never_gen_unique: true).downcase
|
|
563
|
+
begin
|
|
564
|
+
if region
|
|
565
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).get_region_network_endpoint_group(@project_id, region, neg_name)
|
|
566
|
+
else
|
|
567
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).get_global_network_endpoint_group(@project_id, neg_name)
|
|
568
|
+
end
|
|
569
|
+
rescue ::Google::Apis::ClientError => e
|
|
570
|
+
raise e if e.message !~ /notFound:/
|
|
571
|
+
neg_obj = MU::Cloud::Google.compute(:NetworkEndpointGroup).new(
|
|
572
|
+
name: neg_name,
|
|
573
|
+
description: @deploy.deploy_id,
|
|
574
|
+
cloud_function: MU::Cloud::Google.compute(:NetworkEndpointGroupCloudFunction).new(
|
|
575
|
+
function: function.cloud_id.gsub(/.*?\//, '')
|
|
576
|
+
),
|
|
577
|
+
network_endpoint_type: type
|
|
340
578
|
)
|
|
579
|
+
neg_obj.network = vpc.url if vpc and type != "SERVERLESS"
|
|
580
|
+
MU.log "Creating Network Endpoint Group #{neg_name}", details: neg_obj
|
|
581
|
+
if region
|
|
582
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_region_network_endpoint_group(@project_id, @config['region'], neg_obj)
|
|
583
|
+
else
|
|
584
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_global_network_endpoint_group(@project_id, neg_obj)
|
|
585
|
+
end
|
|
586
|
+
retry
|
|
341
587
|
end
|
|
588
|
+
|
|
342
589
|
end
|
|
343
590
|
|
|
344
|
-
def createBackendService(tg)
|
|
591
|
+
def createBackendService(tg, region: nil)
|
|
345
592
|
desc = {
|
|
346
593
|
:name => MU::Cloud::Google.nameStr(@deploy.getResourceName(tg["name"])),
|
|
347
594
|
:description => @deploy.deploy_id,
|
|
348
|
-
:load_balancing_scheme => @config['
|
|
349
|
-
:global => @config['global'],
|
|
595
|
+
:load_balancing_scheme => @config['scheme'],
|
|
350
596
|
:protocol => tg['proto'],
|
|
351
597
|
:timeout_sec => @config['idle_timeout']
|
|
352
598
|
}
|
|
599
|
+
desc[:global] = region.nil?
|
|
600
|
+
desc[:backends] = []
|
|
353
601
|
# TODO EXTERNAL only: port_name, enable_cdn
|
|
354
602
|
if @config['connection_draining_timeout'] > 0
|
|
355
603
|
desc[:connection_draining] = MU::Cloud::Google.compute(:ConnectionDraining).new(
|
|
@@ -376,21 +624,19 @@ module MU
|
|
|
376
624
|
hc = createHealthCheck(tg["healthcheck"], tg["name"])
|
|
377
625
|
desc[:health_checks] = [hc.self_link]
|
|
378
626
|
end
|
|
627
|
+
if ["EXTERNAL", "INTERNAL_MANAGED", "INTERNAL_SELF_MANAGED"].include?(@config['scheme'])
|
|
628
|
+
desc[:port_name] = "placeholder" # relevant when an actual instance group backend is added, required for some reason even if not relevant
|
|
629
|
+
end
|
|
379
630
|
|
|
380
631
|
backend_obj = MU::Cloud::Google.compute(:BackendService).new(desc)
|
|
381
|
-
MU.log "Creating backend service #{MU::Cloud::Google.nameStr(@deploy.getResourceName(tg["name"]))}", details: backend_obj
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
return MU::Cloud::Google.compute(credentials: @config['credentials']).insert_backend_service(
|
|
390
|
-
@project_id,
|
|
391
|
-
backend_obj
|
|
392
|
-
)
|
|
393
|
-
end
|
|
632
|
+
MU.log "Creating #{region ? region : "global"} backend service #{MU::Cloud::Google.nameStr(@deploy.getResourceName(tg["name"]))}", MU::NOTICE, details: backend_obj
|
|
633
|
+
|
|
634
|
+
method = "insert_#{region ? "region_": ""}backend_service".to_sym
|
|
635
|
+
args = [@project_id]
|
|
636
|
+
args << region if region
|
|
637
|
+
args << backend_obj
|
|
638
|
+
|
|
639
|
+
MU::Cloud::Google.compute(credentials: @credentials).send(method, *args)
|
|
394
640
|
end
|
|
395
641
|
|
|
396
642
|
def createHealthCheck(hc, namebase)
|
|
@@ -401,8 +647,8 @@ module MU
|
|
|
401
647
|
path = target[3]
|
|
402
648
|
name = MU::Cloud::Google.nameStr(@deploy.getResourceName(namebase+"-hc-"+proto.downcase+"-"+port.to_s))
|
|
403
649
|
|
|
404
|
-
|
|
405
|
-
|
|
650
|
+
httpcheck = if ["HTTP", "HTTPS", "HTTP2"].include?(proto)
|
|
651
|
+
MU::Cloud::Google.compute("#{proto.capitalize}HealthCheck".to_sym).new(
|
|
406
652
|
check_interval_sec: hc["interval"],
|
|
407
653
|
timeout_sec: hc["timeout"],
|
|
408
654
|
unhealthy_threshold: hc["unhealthy_threshold"],
|
|
@@ -412,20 +658,12 @@ module MU
|
|
|
412
658
|
port: port,
|
|
413
659
|
request_path: path ? path : "/"
|
|
414
660
|
)
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
hc_obj
|
|
422
|
-
)
|
|
423
|
-
else
|
|
424
|
-
return MU::Cloud::Google.compute(credentials: @config['credentials']).insert_https_health_check(
|
|
425
|
-
@project_id,
|
|
426
|
-
hc_obj
|
|
427
|
-
)
|
|
428
|
-
end
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
if proto == "HTTP" or proto == "HTTPS" and @config['global']
|
|
664
|
+
MU.log "Creating global #{proto} health check #{name}", details: httpcheck
|
|
665
|
+
method = "insert_#{proto.downcase}_health_check"
|
|
666
|
+
return MU::Cloud::Google.compute(credentials: @config['credentials']).send(method, @project_id, httpcheck)
|
|
429
667
|
else
|
|
430
668
|
desc = {
|
|
431
669
|
:check_interval_sec => hc["interval"],
|
|
@@ -433,10 +671,10 @@ module MU
|
|
|
433
671
|
:unhealthy_threshold => hc["unhealthy_threshold"],
|
|
434
672
|
:healthy_threshold => hc["healthy_threshold"],
|
|
435
673
|
:description => @deploy.deploy_id,
|
|
436
|
-
:name => name
|
|
674
|
+
:name => name,
|
|
675
|
+
:type => proto
|
|
437
676
|
}
|
|
438
677
|
if proto == "TCP"
|
|
439
|
-
desc[:type] = "TCP"
|
|
440
678
|
desc[:tcp_health_check] = MU::Cloud::Google.compute(:TcpHealthCheck).new(
|
|
441
679
|
port: port,
|
|
442
680
|
proxy_header: "NONE",
|
|
@@ -444,27 +682,36 @@ module MU
|
|
|
444
682
|
response: ""
|
|
445
683
|
)
|
|
446
684
|
elsif proto == "SSL"
|
|
447
|
-
desc[:type] = "SSL"
|
|
448
685
|
desc[:ssl_health_check] = MU::Cloud::Google.compute(:SslHealthCheck).new(
|
|
449
686
|
port: port,
|
|
450
687
|
proxy_header: "NONE",
|
|
451
688
|
request: "", # XXX needs to be configurable
|
|
452
689
|
response: "" # XXX needs to be configurable
|
|
453
690
|
)
|
|
454
|
-
elsif proto == "
|
|
455
|
-
desc[:
|
|
691
|
+
elsif proto == "GRPC"
|
|
692
|
+
desc[:grpc_health_check] = MU::Cloud::Google.compute(:GrpcHealthCheck).new(
|
|
693
|
+
port: port,
|
|
694
|
+
port_specification: "USE_FIXED_PORT",
|
|
695
|
+
port_name: "", # XXX needs to be configurable
|
|
696
|
+
grpc_service_name: "" # XXX needs to be configurable
|
|
697
|
+
)
|
|
698
|
+
elsif proto == "UDP" # XXX deprecated I think?
|
|
456
699
|
desc[:udp_health_check] = MU::Cloud::Google.compute(:UdpHealthCheck).new(
|
|
457
700
|
port: port,
|
|
458
701
|
request: "ORLY", # XXX needs to be configurable
|
|
459
702
|
response: "YARLY" # XXX needs to be configurable
|
|
460
703
|
)
|
|
704
|
+
elsif ["HTTP", "HTTPS", "HTTP2"].include?(proto)
|
|
705
|
+
desc["#{proto.downcase}_health_check".to_sym] = httpcheck
|
|
461
706
|
end
|
|
462
707
|
hc_obj = MU::Cloud::Google.compute(:HealthCheck).new(desc)
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
708
|
+
method = "insert_#{@config['global'] ? "" : "region_" }health_check"
|
|
709
|
+
args = [@project_id]
|
|
710
|
+
args << @config['region'] if !@config['global']
|
|
711
|
+
args << hc_obj
|
|
712
|
+
|
|
713
|
+
MU.log "Creating #{@config['global'] ? "global" : @config['region'] } health check #{name}", details: hc_obj
|
|
714
|
+
return MU::Cloud::Google.compute(credentials: @config['credentials']).send(method, *args)
|
|
468
715
|
end
|
|
469
716
|
|
|
470
717
|
end
|