cloud-mu 3.5.0 → 3.6.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|