cloud-mu 2.1.0beta → 3.0.0beta
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 +5 -5
- data/Berksfile +4 -5
- data/Berksfile.lock +179 -0
- data/README.md +1 -6
- data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +0 -0
- data/ansible/roles/mu-installer/README.md +33 -0
- data/ansible/roles/mu-installer/defaults/main.yml +2 -0
- data/ansible/roles/mu-installer/handlers/main.yml +2 -0
- data/ansible/roles/mu-installer/meta/main.yml +60 -0
- data/ansible/roles/mu-installer/tasks/main.yml +13 -0
- data/ansible/roles/mu-installer/tests/inventory +2 -0
- data/ansible/roles/mu-installer/tests/test.yml +5 -0
- data/ansible/roles/mu-installer/vars/main.yml +2 -0
- data/bin/mu-adopt +125 -0
- data/bin/mu-aws-setup +4 -4
- data/bin/mu-azure-setup +265 -0
- data/bin/mu-azure-tests +43 -0
- data/bin/mu-cleanup +20 -8
- data/bin/mu-configure +224 -98
- data/bin/mu-deploy +8 -3
- data/bin/mu-gcp-setup +16 -8
- data/bin/mu-gen-docs +92 -8
- data/bin/mu-load-config.rb +52 -12
- data/bin/mu-momma-cat +36 -0
- data/bin/mu-node-manage +34 -27
- data/bin/mu-self-update +2 -2
- data/bin/mu-ssh +12 -8
- data/bin/mu-upload-chef-artifacts +11 -4
- data/bin/mu-user-manage +3 -0
- data/cloud-mu.gemspec +8 -11
- data/cookbooks/firewall/libraries/helpers_iptables.rb +2 -2
- data/cookbooks/firewall/metadata.json +1 -1
- data/cookbooks/firewall/recipes/default.rb +5 -9
- data/cookbooks/mu-firewall/attributes/default.rb +2 -0
- data/cookbooks/mu-firewall/metadata.rb +1 -1
- data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +0 -0
- data/cookbooks/mu-master/Berksfile +2 -2
- data/cookbooks/mu-master/files/default/check_mem.pl +0 -0
- data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
- data/cookbooks/mu-master/metadata.rb +5 -4
- data/cookbooks/mu-master/recipes/389ds.rb +1 -1
- data/cookbooks/mu-master/recipes/basepackages.rb +30 -10
- data/cookbooks/mu-master/recipes/default.rb +59 -7
- data/cookbooks/mu-master/recipes/firewall-holes.rb +1 -1
- data/cookbooks/mu-master/recipes/init.rb +65 -47
- data/cookbooks/mu-master/recipes/{eks-kubectl.rb → kubectl.rb} +4 -10
- data/cookbooks/mu-master/recipes/sssd.rb +2 -1
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +6 -6
- data/cookbooks/mu-master/templates/default/web_app.conf.erb +2 -2
- data/cookbooks/mu-master/templates/mods/ldap.conf.erb +4 -0
- data/cookbooks/mu-php54/Berksfile +1 -2
- data/cookbooks/mu-php54/metadata.rb +4 -5
- data/cookbooks/mu-php54/recipes/default.rb +1 -1
- data/cookbooks/mu-splunk/templates/default/splunk-init.erb +0 -0
- data/cookbooks/mu-tools/Berksfile +3 -2
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
- data/cookbooks/mu-tools/libraries/helper.rb +20 -8
- data/cookbooks/mu-tools/metadata.rb +5 -2
- data/cookbooks/mu-tools/recipes/apply_security.rb +2 -3
- data/cookbooks/mu-tools/recipes/eks.rb +1 -1
- data/cookbooks/mu-tools/recipes/gcloud.rb +5 -30
- data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
- data/cookbooks/mu-tools/recipes/rsyslog.rb +1 -0
- data/cookbooks/mu-tools/recipes/selinux.rb +19 -0
- data/cookbooks/mu-tools/recipes/split_var_partitions.rb +0 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +256 -122
- data/cookbooks/mu-tools/resources/disk.rb +3 -1
- data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +1 -1
- data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
- data/cookbooks/mu-tools/templates/default/{kubeconfig.erb → kubeconfig-eks.erb} +0 -0
- data/cookbooks/mu-tools/templates/default/kubeconfig-gke.erb +27 -0
- data/cookbooks/mu-tools/templates/windows-10/sshd_config.erb +137 -0
- data/cookbooks/mu-utility/recipes/nat.rb +4 -0
- data/extras/alpha.png +0 -0
- data/extras/beta.png +0 -0
- data/extras/clean-stock-amis +2 -2
- data/extras/generate-stock-images +131 -0
- data/extras/git-fix-permissions-hook +0 -0
- data/extras/image-generators/AWS/centos6.yaml +17 -0
- data/extras/image-generators/{aws → AWS}/centos7-govcloud.yaml +0 -0
- data/extras/image-generators/{aws → AWS}/centos7.yaml +0 -0
- data/extras/image-generators/{aws → AWS}/rhel7.yaml +0 -0
- data/extras/image-generators/{aws → AWS}/win2k12.yaml +0 -0
- data/extras/image-generators/{aws → AWS}/win2k16.yaml +0 -0
- data/extras/image-generators/{aws → AWS}/windows.yaml +0 -0
- data/extras/image-generators/{gcp → Google}/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +18 -0
- data/extras/python_rpm/build.sh +0 -0
- data/extras/release.png +0 -0
- data/extras/ruby_rpm/build.sh +0 -0
- data/extras/ruby_rpm/muby.spec +1 -1
- data/install/README.md +43 -5
- data/install/deprecated-bash-library.sh +0 -0
- data/install/installer +1 -1
- data/install/jenkinskeys.rb +0 -0
- data/install/mu-master.yaml +55 -0
- data/modules/mommacat.ru +41 -7
- data/modules/mu.rb +444 -149
- data/modules/mu/adoption.rb +500 -0
- data/modules/mu/cleanup.rb +235 -158
- data/modules/mu/cloud.rb +675 -138
- data/modules/mu/clouds/aws.rb +156 -24
- data/modules/mu/clouds/aws/alarm.rb +4 -14
- data/modules/mu/clouds/aws/bucket.rb +60 -18
- data/modules/mu/clouds/aws/cache_cluster.rb +8 -20
- data/modules/mu/clouds/aws/collection.rb +12 -22
- data/modules/mu/clouds/aws/container_cluster.rb +209 -118
- data/modules/mu/clouds/aws/database.rb +120 -45
- data/modules/mu/clouds/aws/dnszone.rb +7 -18
- data/modules/mu/clouds/aws/endpoint.rb +5 -15
- data/modules/mu/clouds/aws/firewall_rule.rb +144 -72
- data/modules/mu/clouds/aws/folder.rb +4 -11
- data/modules/mu/clouds/aws/function.rb +6 -16
- data/modules/mu/clouds/aws/group.rb +4 -12
- data/modules/mu/clouds/aws/habitat.rb +11 -13
- data/modules/mu/clouds/aws/loadbalancer.rb +40 -28
- data/modules/mu/clouds/aws/log.rb +5 -13
- data/modules/mu/clouds/aws/msg_queue.rb +9 -24
- data/modules/mu/clouds/aws/nosqldb.rb +4 -12
- data/modules/mu/clouds/aws/notifier.rb +6 -13
- data/modules/mu/clouds/aws/role.rb +69 -40
- data/modules/mu/clouds/aws/search_domain.rb +17 -20
- data/modules/mu/clouds/aws/server.rb +184 -94
- data/modules/mu/clouds/aws/server_pool.rb +33 -38
- data/modules/mu/clouds/aws/storage_pool.rb +5 -12
- data/modules/mu/clouds/aws/user.rb +59 -33
- data/modules/mu/clouds/aws/userdata/linux.erb +18 -30
- data/modules/mu/clouds/aws/userdata/windows.erb +9 -9
- data/modules/mu/clouds/aws/vpc.rb +214 -145
- data/modules/mu/clouds/azure.rb +978 -44
- data/modules/mu/clouds/azure/container_cluster.rb +413 -0
- data/modules/mu/clouds/azure/firewall_rule.rb +500 -0
- data/modules/mu/clouds/azure/habitat.rb +167 -0
- data/modules/mu/clouds/azure/loadbalancer.rb +205 -0
- data/modules/mu/clouds/azure/role.rb +211 -0
- data/modules/mu/clouds/azure/server.rb +810 -0
- data/modules/mu/clouds/azure/user.rb +257 -0
- data/modules/mu/clouds/azure/userdata/README.md +4 -0
- data/modules/mu/clouds/azure/userdata/linux.erb +137 -0
- data/modules/mu/clouds/azure/userdata/windows.erb +275 -0
- data/modules/mu/clouds/azure/vpc.rb +782 -0
- data/modules/mu/clouds/cloudformation.rb +12 -9
- data/modules/mu/clouds/cloudformation/firewall_rule.rb +5 -13
- data/modules/mu/clouds/cloudformation/server.rb +10 -1
- data/modules/mu/clouds/cloudformation/server_pool.rb +1 -0
- data/modules/mu/clouds/cloudformation/vpc.rb +0 -2
- data/modules/mu/clouds/google.rb +554 -117
- data/modules/mu/clouds/google/bucket.rb +173 -32
- data/modules/mu/clouds/google/container_cluster.rb +1112 -157
- data/modules/mu/clouds/google/database.rb +24 -47
- data/modules/mu/clouds/google/firewall_rule.rb +344 -89
- data/modules/mu/clouds/google/folder.rb +156 -79
- data/modules/mu/clouds/google/group.rb +272 -82
- data/modules/mu/clouds/google/habitat.rb +177 -52
- data/modules/mu/clouds/google/loadbalancer.rb +9 -34
- data/modules/mu/clouds/google/role.rb +1211 -0
- data/modules/mu/clouds/google/server.rb +491 -227
- data/modules/mu/clouds/google/server_pool.rb +233 -48
- data/modules/mu/clouds/google/user.rb +479 -125
- data/modules/mu/clouds/google/userdata/linux.erb +3 -3
- data/modules/mu/clouds/google/userdata/windows.erb +9 -9
- data/modules/mu/clouds/google/vpc.rb +381 -223
- data/modules/mu/config.rb +689 -214
- data/modules/mu/config/bucket.rb +1 -1
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/cache_cluster.yml +0 -4
- data/modules/mu/config/container_cluster.rb +18 -9
- data/modules/mu/config/database.rb +6 -23
- data/modules/mu/config/firewall_rule.rb +9 -15
- data/modules/mu/config/folder.rb +22 -21
- data/modules/mu/config/habitat.rb +22 -21
- data/modules/mu/config/loadbalancer.rb +2 -2
- data/modules/mu/config/role.rb +9 -40
- data/modules/mu/config/server.rb +26 -5
- data/modules/mu/config/server_pool.rb +1 -1
- data/modules/mu/config/storage_pool.rb +2 -2
- data/modules/mu/config/user.rb +4 -0
- data/modules/mu/config/vpc.rb +350 -110
- data/modules/mu/defaults/{amazon_images.yaml → AWS.yaml} +37 -39
- data/modules/mu/defaults/Azure.yaml +17 -0
- data/modules/mu/defaults/Google.yaml +24 -0
- data/modules/mu/defaults/README.md +1 -1
- data/modules/mu/deploy.rb +168 -125
- data/modules/mu/groomer.rb +2 -1
- data/modules/mu/groomers/ansible.rb +104 -32
- data/modules/mu/groomers/chef.rb +96 -44
- data/modules/mu/kittens.rb +20602 -0
- data/modules/mu/logger.rb +38 -11
- data/modules/mu/master.rb +90 -8
- data/modules/mu/master/chef.rb +2 -3
- data/modules/mu/master/ldap.rb +0 -1
- data/modules/mu/master/ssl.rb +250 -0
- data/modules/mu/mommacat.rb +917 -513
- data/modules/scratchpad.erb +1 -1
- data/modules/tests/super_complex_bok.yml +0 -0
- data/modules/tests/super_simple_bok.yml +0 -0
- data/roles/mu-master.json +2 -1
- data/spec/azure_creds +5 -0
- data/spec/mu.yaml +56 -0
- data/spec/mu/clouds/azure_spec.rb +164 -27
- data/spec/spec_helper.rb +5 -0
- data/test/clean_up.py +0 -0
- data/test/exec_inspec.py +0 -0
- data/test/exec_mu_install.py +0 -0
- data/test/exec_retry.py +0 -0
- data/test/smoke_test.rb +0 -0
- metadata +90 -118
- data/cookbooks/mu-jenkins/Berksfile +0 -14
- data/cookbooks/mu-jenkins/CHANGELOG.md +0 -13
- data/cookbooks/mu-jenkins/LICENSE +0 -37
- data/cookbooks/mu-jenkins/README.md +0 -105
- data/cookbooks/mu-jenkins/attributes/default.rb +0 -42
- data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +0 -73
- data/cookbooks/mu-jenkins/files/default/deploy_config.xml +0 -44
- data/cookbooks/mu-jenkins/metadata.rb +0 -21
- data/cookbooks/mu-jenkins/recipes/default.rb +0 -195
- data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +0 -54
- data/cookbooks/mu-jenkins/recipes/public_key.rb +0 -24
- data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +0 -24
- data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +0 -14
- data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +0 -6
- data/cookbooks/nagios/Berksfile +0 -11
- data/cookbooks/nagios/CHANGELOG.md +0 -589
- data/cookbooks/nagios/CONTRIBUTING.md +0 -11
- data/cookbooks/nagios/LICENSE +0 -37
- data/cookbooks/nagios/README.md +0 -328
- data/cookbooks/nagios/TESTING.md +0 -2
- data/cookbooks/nagios/attributes/config.rb +0 -171
- data/cookbooks/nagios/attributes/default.rb +0 -228
- data/cookbooks/nagios/chefignore +0 -102
- data/cookbooks/nagios/definitions/command.rb +0 -33
- data/cookbooks/nagios/definitions/contact.rb +0 -33
- data/cookbooks/nagios/definitions/contactgroup.rb +0 -33
- data/cookbooks/nagios/definitions/host.rb +0 -33
- data/cookbooks/nagios/definitions/hostdependency.rb +0 -33
- data/cookbooks/nagios/definitions/hostescalation.rb +0 -34
- data/cookbooks/nagios/definitions/hostgroup.rb +0 -33
- data/cookbooks/nagios/definitions/nagios_conf.rb +0 -38
- data/cookbooks/nagios/definitions/resource.rb +0 -33
- data/cookbooks/nagios/definitions/service.rb +0 -33
- data/cookbooks/nagios/definitions/servicedependency.rb +0 -33
- data/cookbooks/nagios/definitions/serviceescalation.rb +0 -34
- data/cookbooks/nagios/definitions/servicegroup.rb +0 -33
- data/cookbooks/nagios/definitions/timeperiod.rb +0 -33
- data/cookbooks/nagios/libraries/base.rb +0 -314
- data/cookbooks/nagios/libraries/command.rb +0 -91
- data/cookbooks/nagios/libraries/contact.rb +0 -230
- data/cookbooks/nagios/libraries/contactgroup.rb +0 -112
- data/cookbooks/nagios/libraries/custom_option.rb +0 -36
- data/cookbooks/nagios/libraries/data_bag_helper.rb +0 -23
- data/cookbooks/nagios/libraries/default.rb +0 -90
- data/cookbooks/nagios/libraries/host.rb +0 -412
- data/cookbooks/nagios/libraries/hostdependency.rb +0 -181
- data/cookbooks/nagios/libraries/hostescalation.rb +0 -173
- data/cookbooks/nagios/libraries/hostgroup.rb +0 -119
- data/cookbooks/nagios/libraries/nagios.rb +0 -282
- data/cookbooks/nagios/libraries/resource.rb +0 -59
- data/cookbooks/nagios/libraries/service.rb +0 -455
- data/cookbooks/nagios/libraries/servicedependency.rb +0 -215
- data/cookbooks/nagios/libraries/serviceescalation.rb +0 -195
- data/cookbooks/nagios/libraries/servicegroup.rb +0 -144
- data/cookbooks/nagios/libraries/timeperiod.rb +0 -160
- data/cookbooks/nagios/libraries/users_helper.rb +0 -54
- data/cookbooks/nagios/metadata.rb +0 -25
- data/cookbooks/nagios/recipes/_load_databag_config.rb +0 -153
- data/cookbooks/nagios/recipes/_load_default_config.rb +0 -241
- data/cookbooks/nagios/recipes/apache.rb +0 -48
- data/cookbooks/nagios/recipes/default.rb +0 -204
- data/cookbooks/nagios/recipes/nginx.rb +0 -82
- data/cookbooks/nagios/recipes/pagerduty.rb +0 -143
- data/cookbooks/nagios/recipes/server_package.rb +0 -40
- data/cookbooks/nagios/recipes/server_source.rb +0 -164
- data/cookbooks/nagios/templates/default/apache2.conf.erb +0 -96
- data/cookbooks/nagios/templates/default/cgi.cfg.erb +0 -266
- data/cookbooks/nagios/templates/default/commands.cfg.erb +0 -13
- data/cookbooks/nagios/templates/default/contacts.cfg.erb +0 -37
- data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +0 -25
- data/cookbooks/nagios/templates/default/hosts.cfg.erb +0 -15
- data/cookbooks/nagios/templates/default/htpasswd.users.erb +0 -6
- data/cookbooks/nagios/templates/default/nagios.cfg.erb +0 -22
- data/cookbooks/nagios/templates/default/nginx.conf.erb +0 -62
- data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +0 -185
- data/cookbooks/nagios/templates/default/resource.cfg.erb +0 -27
- data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +0 -15
- data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +0 -14
- data/cookbooks/nagios/templates/default/services.cfg.erb +0 -14
- data/cookbooks/nagios/templates/default/templates.cfg.erb +0 -31
- data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +0 -13
- data/extras/image-generators/aws/centos6.yaml +0 -18
- data/modules/mu/defaults/google_images.yaml +0 -16
- data/roles/mu-master-jenkins.json +0 -24
|
@@ -17,47 +17,28 @@ module MU
|
|
|
17
17
|
class Google
|
|
18
18
|
# A database as configured in {MU::Config::BasketofKittens::databases}
|
|
19
19
|
class Database < MU::Cloud::Database
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
attr_reader :config
|
|
26
|
-
attr_reader :groomer
|
|
27
|
-
|
|
28
|
-
# @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
|
|
29
|
-
# @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::databases}
|
|
30
|
-
def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
|
|
31
|
-
@deploy = mommacat
|
|
32
|
-
@config = MU::Config.manxify(kitten_cfg)
|
|
33
|
-
@cloud_id ||= cloud_id
|
|
34
|
-
# @mu_name = mu_name ? mu_name : @deploy.getResourceName(@config["name"])
|
|
20
|
+
|
|
21
|
+
# 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.
|
|
22
|
+
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
|
23
|
+
def initialize(**args)
|
|
24
|
+
super
|
|
35
25
|
@config["groomer"] = MU::Config.defaultGroomer unless @config["groomer"]
|
|
36
26
|
@groomclass = MU::Groomer.loadGroomer(@config["groomer"])
|
|
37
27
|
|
|
38
|
-
|
|
39
|
-
@
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@project_id = project.nil? ? @config['project'] : project.cloudobj.cloud_id
|
|
28
|
+
@mu_name ||=
|
|
29
|
+
if @config and @config['engine'] and @config["engine"].match(/^sqlserver/)
|
|
30
|
+
@deploy.getResourceName(@config["name"], max_length: 15)
|
|
31
|
+
else
|
|
32
|
+
@deploy.getResourceName(@config["name"], max_length: 63)
|
|
44
33
|
end
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if @config and @config['engine'] and @config["engine"].match(/^sqlserver/)
|
|
48
|
-
@deploy.getResourceName(@config["name"], max_length: 15)
|
|
49
|
-
else
|
|
50
|
-
@deploy.getResourceName(@config["name"], max_length: 63)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
@mu_name.gsub(/(--|-$)/i, "").gsub(/(_)/, "-").gsub!(/^[^a-z]/i, "")
|
|
54
|
-
end
|
|
34
|
+
|
|
35
|
+
@mu_name.gsub(/(--|-$)/i, "").gsub(/(_)/, "-").gsub!(/^[^a-z]/i, "")
|
|
55
36
|
end
|
|
56
37
|
|
|
57
38
|
# Called automatically by {MU::Deploy#createResources}
|
|
58
39
|
# @return [String]: The cloud provider's identifier for this database instance.
|
|
59
40
|
def create
|
|
60
|
-
@project_id = MU::Cloud::Google.projectLookup(@config['project'], @deploy).
|
|
41
|
+
@project_id = MU::Cloud::Google.projectLookup(@config['project'], @deploy).cloud_id
|
|
61
42
|
labels = {}
|
|
62
43
|
MU::MommaCat.listStandardTags.each_pair { |name, value|
|
|
63
44
|
if !value.nil?
|
|
@@ -85,19 +66,15 @@ module MU
|
|
|
85
66
|
end
|
|
86
67
|
|
|
87
68
|
# Locate an existing Database or Databases and return an array containing matching GCP resource descriptors for those that match.
|
|
88
|
-
# @param cloud_id [String]: The cloud provider's identifier for this resource.
|
|
89
|
-
# @param region [String]: The cloud provider region
|
|
90
|
-
# @param tag_key [String]: A tag key to search.
|
|
91
|
-
# @param tag_value [String]: The value of the tag specified by tag_key to match when searching by tag.
|
|
92
|
-
# @param flags [Hash]: Optional flags
|
|
93
69
|
# @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching Databases
|
|
94
|
-
def self.find(
|
|
95
|
-
|
|
70
|
+
def self.find(**args)
|
|
71
|
+
args[:project] ||= args[:habitat]
|
|
72
|
+
args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
|
|
96
73
|
end
|
|
97
74
|
|
|
98
75
|
# Called automatically by {MU::Deploy#createResources}
|
|
99
76
|
def groom
|
|
100
|
-
@project_id = MU::Cloud::Google.projectLookup(@config['project'], @deploy).
|
|
77
|
+
@project_id = MU::Cloud::Google.projectLookup(@config['project'], @deploy).cloud_id
|
|
101
78
|
end
|
|
102
79
|
|
|
103
80
|
# Register a description of this database instance with this deployment's metadata.
|
|
@@ -134,13 +111,13 @@ module MU
|
|
|
134
111
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
135
112
|
flags["project"] ||= MU::Cloud::Google.defaultProject(credentials)
|
|
136
113
|
skipsnapshots||= flags["skipsnapshots"]
|
|
137
|
-
instances = MU::Cloud::Google.sql(credentials: credentials).list_instances(flags['project'], filter: %Q{userLabels.mu-id:"#{MU.deploy_id.downcase}"})
|
|
138
|
-
if instances and instances.items
|
|
139
|
-
instances.items.each { |instance|
|
|
140
|
-
MU.log "Deleting Cloud SQL instance #{instance.name}"
|
|
141
|
-
MU::Cloud::Google.sql(credentials: credentials).delete_instance(flags['project'], instance.name) if !noop
|
|
142
|
-
}
|
|
143
|
-
end
|
|
114
|
+
# instances = MU::Cloud::Google.sql(credentials: credentials).list_instances(flags['project'], filter: %Q{userLabels.mu-id:"#{MU.deploy_id.downcase}"})
|
|
115
|
+
# if instances and instances.items
|
|
116
|
+
# instances.items.each { |instance|
|
|
117
|
+
# MU.log "Deleting Cloud SQL instance #{instance.name}"
|
|
118
|
+
# MU::Cloud::Google.sql(credentials: credentials).delete_instance(flags['project'], instance.name) if !noop
|
|
119
|
+
# }
|
|
120
|
+
# end
|
|
144
121
|
end
|
|
145
122
|
|
|
146
123
|
# Cloud-specific configuration properties.
|
|
@@ -18,57 +18,49 @@ module MU
|
|
|
18
18
|
class Google
|
|
19
19
|
# A firewall ruleset as configured in {MU::Config::BasketofKittens::firewall_rules}
|
|
20
20
|
class FirewallRule < MU::Cloud::FirewallRule
|
|
21
|
-
|
|
22
|
-
@deploy = nil
|
|
23
|
-
@config = nil
|
|
24
|
-
@project_id = nil
|
|
25
21
|
@admin_sgs = Hash.new
|
|
26
22
|
@admin_sg_semaphore = Mutex.new
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@cloud_id ||= MU::Cloud::Google.nameStr(@mu_name+"-ingress-allow")
|
|
42
|
-
@config['project'] ||= MU::Cloud::Google.defaultProject(@config['credentials'])
|
|
43
|
-
if !@project_id
|
|
44
|
-
project = MU::Cloud::Google.projectLookup(@config['project'], @deploy, sibling_only: true, raise_on_fail: false)
|
|
45
|
-
@project_id = project.nil? ? @config['project'] : project.cloudobj.cloud_id
|
|
46
|
-
end
|
|
24
|
+
# Firewall protocols supported by GCP as of early 2019
|
|
25
|
+
PROTOS = ["udp", "tcp", "icmp", "esp", "ah", "sctp", "ipip"]
|
|
26
|
+
|
|
27
|
+
# Our default subset of supported firewall protocols
|
|
28
|
+
STD_PROTOS = ["icmp", "tcp", "udp"]
|
|
29
|
+
|
|
30
|
+
# 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.
|
|
31
|
+
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
|
32
|
+
def initialize(**args)
|
|
33
|
+
super
|
|
34
|
+
|
|
35
|
+
if !@vpc.nil?
|
|
36
|
+
@mu_name ||= @deploy.getResourceName(@config['name'], need_unique_string: true, max_length: 61)
|
|
47
37
|
else
|
|
48
|
-
|
|
49
|
-
@mu_name = @deploy.getResourceName(@config['name'], need_unique_string: true, max_length: 61)
|
|
50
|
-
else
|
|
51
|
-
@mu_name = @deploy.getResourceName(@config['name'], max_length: 61)
|
|
52
|
-
end
|
|
38
|
+
@mu_name ||= @deploy.getResourceName(@config['name'], max_length: 61)
|
|
53
39
|
end
|
|
54
|
-
|
|
55
40
|
end
|
|
56
41
|
|
|
57
42
|
attr_reader :rulesets
|
|
58
43
|
|
|
59
44
|
# Called by {MU::Deploy#createResources}
|
|
60
45
|
def create
|
|
61
|
-
@
|
|
46
|
+
@cloud_id = @mu_name.downcase.gsub(/[^-a-z0-9]/, "-")
|
|
62
47
|
|
|
63
|
-
vpc_id = @vpc.
|
|
48
|
+
vpc_id = @vpc.url if !@vpc.nil?
|
|
64
49
|
vpc_id ||= @config['vpc']['vpc_id'] if @config['vpc'] and @config['vpc']['vpc_id']
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
51
|
+
if vpc_id.nil?
|
|
52
|
+
raise MuError, "Failed to resolve VPC for #{self}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
params = {
|
|
56
|
+
:name => @cloud_id,
|
|
57
|
+
:network => vpc_id
|
|
58
|
+
}
|
|
59
|
+
|
|
69
60
|
@config['rules'].each { |rule|
|
|
70
61
|
srcs = []
|
|
71
62
|
ruleobj = nil
|
|
63
|
+
# XXX 'all' and 'standard' keywords
|
|
72
64
|
if ["tcp", "udp"].include?(rule['proto']) and (rule['port_range'] or rule['port'])
|
|
73
65
|
ruleobj = MU::Cloud::Google.compute(:Firewall)::Allowed.new(
|
|
74
66
|
ip_protocol: rule['proto'],
|
|
@@ -83,55 +75,59 @@ module MU
|
|
|
83
75
|
rule['hosts'].each { |cidr| srcs << cidr }
|
|
84
76
|
end
|
|
85
77
|
|
|
86
|
-
["ingress"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
:name => setname,
|
|
92
|
-
:direction => dir.upcase,
|
|
93
|
-
:network => vpc_id
|
|
94
|
-
}
|
|
95
|
-
if @deploy
|
|
96
|
-
allrules[setname][:description] = @deploy.deploy_id
|
|
97
|
-
end
|
|
98
|
-
['source_service_accounts', 'source_tags', 'target_tags', 'target_service_accounts'].each { |filter|
|
|
99
|
-
if config[filter] and config[filter].size > 0
|
|
100
|
-
allrules[setname][filter.to_sym] = config[filter].dup
|
|
101
|
-
end
|
|
102
|
-
}
|
|
103
|
-
action = rule['deny'] ? :denied : :allowed
|
|
104
|
-
allrules[setname][action] ||= []
|
|
105
|
-
allrules[setname][action] << ruleobj
|
|
106
|
-
ipparam = dir == "ingress" ? :source_ranges : :destination_ranges
|
|
107
|
-
allrules[setname][ipparam] ||= []
|
|
108
|
-
allrules[setname][ipparam].concat(srcs)
|
|
109
|
-
allrules[setname][:priority] = rule['weight'] if rule['weight']
|
|
110
|
-
end
|
|
111
|
-
}
|
|
112
|
-
}
|
|
78
|
+
dir = (rule["ingress"] or !rule["egress"]) ? "INGRESS" : "EGRESS"
|
|
79
|
+
if params[:direction] and params[:direction] != dir
|
|
80
|
+
MU.log "Google Cloud firewalls cannot mix ingress and egress rules", MU::ERR, details: @config['rules']
|
|
81
|
+
raise MuError, "Google Cloud firewalls cannot mix ingress and egress rules"
|
|
82
|
+
end
|
|
113
83
|
|
|
114
|
-
|
|
115
|
-
threads = []
|
|
84
|
+
params[:direction] = dir
|
|
116
85
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
86
|
+
if @deploy
|
|
87
|
+
params[:description] = @deploy.deploy_id
|
|
88
|
+
end
|
|
89
|
+
filters = if dir == "INGRESS"
|
|
90
|
+
['source_service_accounts', 'source_tags']
|
|
91
|
+
else
|
|
92
|
+
['target_service_accounts', 'target_tags']
|
|
93
|
+
end
|
|
94
|
+
filters.each { |filter|
|
|
95
|
+
if config[filter] and config[filter].size > 0
|
|
96
|
+
params[filter.to_sym] = config[filter].dup
|
|
97
|
+
end
|
|
124
98
|
}
|
|
99
|
+
action = rule['deny'] ? :denied : :allowed
|
|
100
|
+
params[action] ||= []
|
|
101
|
+
params[action] << ruleobj
|
|
102
|
+
ipparam = dir == "INGRESS" ? :source_ranges : :destination_ranges
|
|
103
|
+
params[ipparam] ||= []
|
|
104
|
+
params[ipparam].concat(srcs)
|
|
105
|
+
params[:priority] = rule['weight'] if rule['weight']
|
|
125
106
|
}
|
|
126
107
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
108
|
+
fwobj = MU::Cloud::Google.compute(:Firewall).new(params)
|
|
109
|
+
MU.log "Creating firewall #{@cloud_id} in project #{@project_id}", details: fwobj
|
|
110
|
+
begin
|
|
111
|
+
MU::Cloud::Google.compute(credentials: @config['credentials']).insert_firewall(@project_id, fwobj)
|
|
112
|
+
rescue ::Google::Apis::ClientError => e
|
|
113
|
+
MU.log @config['project']+"/"+@config['name']+": "+@cloud_id, MU::ERR, details: @config['vpc']
|
|
114
|
+
MU.log e.inspect, MU::ERR, details: fwobj
|
|
115
|
+
if e.message.match(/Invalid value for field/)
|
|
116
|
+
dependencies(use_cache: false, debug: true)
|
|
117
|
+
end
|
|
118
|
+
raise e
|
|
119
|
+
end
|
|
120
|
+
# Make sure it actually got made before we move on
|
|
121
|
+
desc = nil
|
|
122
|
+
begin
|
|
123
|
+
desc = MU::Cloud::Google.compute(credentials: @config['credentials']).get_firewall(@project_id, @cloud_id)
|
|
124
|
+
sleep 1
|
|
125
|
+
end while desc.nil?
|
|
126
|
+
desc
|
|
130
127
|
end
|
|
131
128
|
|
|
132
129
|
# Called by {MU::Deploy#createResources}
|
|
133
130
|
def groom
|
|
134
|
-
@project_id = MU::Cloud::Google.projectLookup(@config['project'], @deploy).cloudobj.cloud_id
|
|
135
131
|
end
|
|
136
132
|
|
|
137
133
|
# Log metadata about this ruleset to the currently running deployment
|
|
@@ -141,7 +137,7 @@ module MU
|
|
|
141
137
|
)
|
|
142
138
|
sg_data ||= {}
|
|
143
139
|
sg_data["group_id"] = @cloud_id
|
|
144
|
-
sg_data["project_id"] =
|
|
140
|
+
sg_data["project_id"] = habitat_id
|
|
145
141
|
sg_data["cloud_id"] = @cloud_id
|
|
146
142
|
|
|
147
143
|
return sg_data
|
|
@@ -158,24 +154,31 @@ module MU
|
|
|
158
154
|
def addRule(hosts, proto: "tcp", port: nil, egress: false, port_range: "0-65535")
|
|
159
155
|
end
|
|
160
156
|
|
|
161
|
-
# Locate
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
# @
|
|
168
|
-
|
|
169
|
-
|
|
157
|
+
# Locate and return cloud provider descriptors of this resource type
|
|
158
|
+
# which match the provided parameters, or all visible resources if no
|
|
159
|
+
# filters are specified. At minimum, implementations of +find+ must
|
|
160
|
+
# honor +credentials+ and +cloud_id+ arguments. We may optionally
|
|
161
|
+
# support other search methods, such as +tag_key+ and +tag_value+, or
|
|
162
|
+
# cloud-specific arguments like +project+. See also {MU::MommaCat.findStray}.
|
|
163
|
+
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
|
164
|
+
# @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
|
|
165
|
+
def self.find(**args)
|
|
166
|
+
args[:project] ||= args[:habitat]
|
|
167
|
+
args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
|
|
170
168
|
|
|
171
169
|
found = {}
|
|
172
|
-
resp =
|
|
170
|
+
resp = begin
|
|
171
|
+
MU::Cloud::Google.compute(credentials: args[:credentials]).list_firewalls(args[:project])
|
|
172
|
+
rescue ::Google::Apis::ClientError => e
|
|
173
|
+
raise e if !e.message.match(/^(?:notFound|forbidden): /)
|
|
174
|
+
end
|
|
173
175
|
if resp and resp.items
|
|
174
176
|
resp.items.each { |fw|
|
|
175
|
-
next if !cloud_id.nil? and fw.name != cloud_id
|
|
177
|
+
next if !args[:cloud_id].nil? and fw.name != args[:cloud_id]
|
|
176
178
|
found[fw.name] = fw
|
|
177
179
|
}
|
|
178
180
|
end
|
|
181
|
+
|
|
179
182
|
found
|
|
180
183
|
end
|
|
181
184
|
|
|
@@ -199,6 +202,8 @@ module MU
|
|
|
199
202
|
# @return [void]
|
|
200
203
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
201
204
|
flags["project"] ||= MU::Cloud::Google.defaultProject(credentials)
|
|
205
|
+
return if !MU::Cloud::Google::Habitat.isLive?(flags["project"], credentials)
|
|
206
|
+
|
|
202
207
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
|
203
208
|
"firewall",
|
|
204
209
|
flags["project"],
|
|
@@ -207,18 +212,167 @@ module MU
|
|
|
207
212
|
)
|
|
208
213
|
end
|
|
209
214
|
|
|
215
|
+
# Reverse-map our cloud description into a runnable config hash.
|
|
216
|
+
# We assume that any values we have in +@config+ are placeholders, and
|
|
217
|
+
# calculate our own accordingly based on what's live in the cloud.
|
|
218
|
+
def toKitten(rootparent: nil, billing: nil, habitats: nil)
|
|
219
|
+
|
|
220
|
+
if cloud_desc.name.match(/^[a-f0-9]+$/)
|
|
221
|
+
gke_ish = true
|
|
222
|
+
cloud_desc.target_tags.each { |tag|
|
|
223
|
+
gke_ish = false if !tag.match(/^gke-/)
|
|
224
|
+
}
|
|
225
|
+
if gke_ish
|
|
226
|
+
MU.log "FirewallRule #{cloud_desc.name} appears to belong to a ContainerCluster, skipping adoption", MU::DEBUG
|
|
227
|
+
return nil
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
bok = {
|
|
232
|
+
"cloud" => "Google",
|
|
233
|
+
"project" => @config['project'],
|
|
234
|
+
"credentials" => @config['credentials']
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
bok['rules'] = []
|
|
238
|
+
bok['name'] = cloud_desc.name.dup
|
|
239
|
+
bok['cloud_id'] = cloud_desc.name.dup
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
cloud_desc.network.match(/(?:^|\/)projects\/(.*?)\/.*?\/networks\/([^\/]+)(?:$|\/)/)
|
|
243
|
+
vpc_proj = Regexp.last_match[1]
|
|
244
|
+
vpc_id = Regexp.last_match[2]
|
|
245
|
+
|
|
246
|
+
if vpc_id == "default" and !@config['project']
|
|
247
|
+
raise MuError, "FirewallRule toKitten: I'm in 'default' VPC but can't figure out what project I'm in"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# XXX make sure this is sane (that these rules come with default VPCs)
|
|
251
|
+
if vpc_id == "default" and ["default-allow-icmp", "default-allow-http"].include?(cloud_desc.name)
|
|
252
|
+
return nil
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
if vpc_id != "default"
|
|
256
|
+
bok['vpc'] = MU::Config::Ref.get(
|
|
257
|
+
id: vpc_id,
|
|
258
|
+
habitat: MU::Config::Ref.get(
|
|
259
|
+
id: vpc_proj,
|
|
260
|
+
cloud: "Google",
|
|
261
|
+
credentials: @credentials,
|
|
262
|
+
type: "habitats"
|
|
263
|
+
),
|
|
264
|
+
cloud: "Google",
|
|
265
|
+
credentials: @config['credentials'],
|
|
266
|
+
type: "vpcs"
|
|
267
|
+
)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
byport = {}
|
|
271
|
+
|
|
272
|
+
rule_list = []
|
|
273
|
+
is_deny = false
|
|
274
|
+
if cloud_desc.denied
|
|
275
|
+
rule_list = cloud_desc.denied
|
|
276
|
+
is_deny = true
|
|
277
|
+
else
|
|
278
|
+
rule_list = cloud_desc.allowed
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
rule_list.each { |rule|
|
|
282
|
+
hosts = if cloud_desc.direction == "INGRESS"
|
|
283
|
+
cloud_desc.source_ranges ? cloud_desc.source_ranges : ["0.0.0.0/0"]
|
|
284
|
+
else
|
|
285
|
+
cloud_desc.destination_ranges ? cloud_desc.destination_ranges : ["0.0.0.0/0"]
|
|
286
|
+
end
|
|
287
|
+
hosts.map! { |h|
|
|
288
|
+
h = h+"/32" if h.match(/^\d+\.\d+\.\d+\.\d+$/)
|
|
289
|
+
h
|
|
290
|
+
}
|
|
291
|
+
proto = rule.ip_protocol ? rule.ip_protocol : "all"
|
|
292
|
+
|
|
293
|
+
if rule.ports
|
|
294
|
+
rule.ports.each { |ports|
|
|
295
|
+
ports = "0-65535" if ["1-65535", "1-65536", "0-65536"].include?(ports)
|
|
296
|
+
byport[ports] ||= {}
|
|
297
|
+
byport[ports][hosts] ||= []
|
|
298
|
+
byport[ports][hosts] << proto
|
|
299
|
+
}
|
|
300
|
+
else
|
|
301
|
+
byport["0-65535"] ||= {}
|
|
302
|
+
byport["0-65535"][hosts] ||= []
|
|
303
|
+
byport["0-65535"][hosts] << proto
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
byport.each_pair { |ports, hostlists|
|
|
309
|
+
hostlists.each_pair { |hostlist, protos|
|
|
310
|
+
protolist = if protos.sort.uniq == PROTOS.sort.uniq
|
|
311
|
+
["all"]
|
|
312
|
+
elsif protos.sort.uniq == ["icmp", "tcp", "udp"]
|
|
313
|
+
["standard"]
|
|
314
|
+
else
|
|
315
|
+
protos
|
|
316
|
+
end
|
|
317
|
+
protolist.each { |proto|
|
|
318
|
+
rule = {
|
|
319
|
+
"proto" => proto,
|
|
320
|
+
"hosts" => hostlist
|
|
321
|
+
}
|
|
322
|
+
rule["deny"] = true if is_deny
|
|
323
|
+
if cloud_desc.priority and cloud_desc.priority != 1000
|
|
324
|
+
rule["weight"] = cloud_desc.priority
|
|
325
|
+
end
|
|
326
|
+
if ports.match(/-/)
|
|
327
|
+
rule["port_range"] = ports
|
|
328
|
+
else
|
|
329
|
+
rule["port"] = ports.to_i
|
|
330
|
+
end
|
|
331
|
+
if cloud_desc.source_service_accounts
|
|
332
|
+
rule["source_service_accounts"] = cloud_desc.source_service_accounts
|
|
333
|
+
end
|
|
334
|
+
if cloud_desc.source_tags
|
|
335
|
+
rule["source_tags"] = cloud_desc.source_tags
|
|
336
|
+
end
|
|
337
|
+
if cloud_desc.target_service_accounts
|
|
338
|
+
rule["target_service_accounts"] = cloud_desc.target_service_accounts
|
|
339
|
+
end
|
|
340
|
+
if cloud_desc.target_tags
|
|
341
|
+
rule["target_tags"] = cloud_desc.target_tags
|
|
342
|
+
end
|
|
343
|
+
if cloud_desc.direction == "EGRESS"
|
|
344
|
+
rule['egress'] = true
|
|
345
|
+
rule['ingress'] = false
|
|
346
|
+
end
|
|
347
|
+
bok['rules'] << rule
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
bok
|
|
353
|
+
end
|
|
354
|
+
|
|
210
355
|
# Cloud-specific configuration properties.
|
|
211
356
|
# @param config [MU::Config]: The calling MU::Config object
|
|
212
357
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
|
213
|
-
def self.schema(config)
|
|
358
|
+
def self.schema(config = nil)
|
|
214
359
|
toplevel_required = []
|
|
215
|
-
# ['source_ranges', 'source_service_accounts', 'source_tags', 'target_ranges', 'target_service_accounts'].each { |filter|
|
|
216
360
|
schema = {
|
|
217
361
|
"rules" => {
|
|
218
362
|
"items" => {
|
|
219
363
|
"properties" => {
|
|
364
|
+
"weight" => {
|
|
365
|
+
"type" => "integer",
|
|
366
|
+
"description" => "Explicitly set a priority for this firewall rule, between 0 and 65535, with lower numbered priority rules having greater precedence."
|
|
367
|
+
},
|
|
368
|
+
"deny" => {
|
|
369
|
+
"type" => "boolean",
|
|
370
|
+
"default" => false,
|
|
371
|
+
"description" => "Set this rule to +DENY+ traffic instead of +ALLOW+"
|
|
372
|
+
},
|
|
220
373
|
"proto" => {
|
|
221
|
-
"
|
|
374
|
+
"description" => "The protocol to allow with this rule. The +standard+ keyword will expand to a series of identical rules covering +icmp+, +tcp+, and +udp; the +all+ keyword will expand to a series of identical rules for all supported protocols.",
|
|
375
|
+
"enum" => PROTOS + ["all", "standard"]
|
|
222
376
|
},
|
|
223
377
|
"source_tags" => {
|
|
224
378
|
"type" => "array",
|
|
@@ -265,6 +419,107 @@ module MU
|
|
|
265
419
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
|
266
420
|
def self.validateConfig(acl, config)
|
|
267
421
|
ok = true
|
|
422
|
+
acl['project'] ||= MU::Cloud::Google.defaultProject(acl['credentials'])
|
|
423
|
+
|
|
424
|
+
if acl['vpc']
|
|
425
|
+
acl['vpc']['project'] ||= acl['project']
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
acl['rules'] ||= []
|
|
429
|
+
|
|
430
|
+
# Firewall entries without rules are illegal in GCP, so insert a
|
|
431
|
+
# default-deny placeholder.
|
|
432
|
+
if acl['rules'].empty?
|
|
433
|
+
acl['rules'] << {
|
|
434
|
+
"deny" => true,
|
|
435
|
+
"proto" => "all",
|
|
436
|
+
"hosts" => ["0.0.0.0/0"],
|
|
437
|
+
"weight" => 65535
|
|
438
|
+
}
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# First, expand some of our protocol shorthand into a real list
|
|
442
|
+
append = []
|
|
443
|
+
delete = []
|
|
444
|
+
acl['rules'].each { |r|
|
|
445
|
+
if !r['egress']
|
|
446
|
+
if !r['source_tags'] and !r['source_service_accounts'] and
|
|
447
|
+
(!r['hosts'] or r['hosts'].empty?)
|
|
448
|
+
r['hosts'] = ['0.0.0.0/0']
|
|
449
|
+
end
|
|
450
|
+
else
|
|
451
|
+
if !r['destination_tags'] and !r['destination_service_accounts'] and
|
|
452
|
+
(!r['hosts'] or r['hosts'].empty?)
|
|
453
|
+
r['hosts'] = ['0.0.0.0/0']
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
if r['proto'] == "standard"
|
|
458
|
+
STD_PROTOS.each { |p|
|
|
459
|
+
newrule = r.dup
|
|
460
|
+
newrule['proto'] = p
|
|
461
|
+
append << newrule
|
|
462
|
+
}
|
|
463
|
+
delete << r
|
|
464
|
+
elsif r['proto'] == "all"
|
|
465
|
+
PROTOS.each { |p|
|
|
466
|
+
newrule = r.dup
|
|
467
|
+
newrule['proto'] = p
|
|
468
|
+
append << newrule
|
|
469
|
+
}
|
|
470
|
+
delete << r
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
}
|
|
474
|
+
delete.each { |r|
|
|
475
|
+
acl['rules'].delete(r)
|
|
476
|
+
}
|
|
477
|
+
acl['rules'].concat(append)
|
|
478
|
+
|
|
479
|
+
# Next, bucket these by what combination of allow/deny and
|
|
480
|
+
# ingress/egress rule they are. If we have more than one
|
|
481
|
+
# classification
|
|
482
|
+
rules_by_class = {
|
|
483
|
+
"allow-ingress" => [],
|
|
484
|
+
"allow-egress" => [],
|
|
485
|
+
"deny-ingress" => [],
|
|
486
|
+
"deny-egress" => [],
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
acl['rules'].each { |rule|
|
|
490
|
+
if rule['deny']
|
|
491
|
+
if rule['egress']
|
|
492
|
+
rules_by_class["deny-egress"] << rule
|
|
493
|
+
else
|
|
494
|
+
rules_by_class["deny-ingress"] << rule
|
|
495
|
+
end
|
|
496
|
+
else
|
|
497
|
+
if rule['egress']
|
|
498
|
+
rules_by_class["allow-egress"] << rule
|
|
499
|
+
else
|
|
500
|
+
rules_by_class["allow-ingress"] << rule
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
rules_by_class.reject! { |k, v| v.size == 0 }
|
|
506
|
+
|
|
507
|
+
# Generate other firewall rule objects to cover the other behaviors
|
|
508
|
+
# we've requested, if indeed we've done so.
|
|
509
|
+
if rules_by_class.size > 1
|
|
510
|
+
keep = rules_by_class.keys.first
|
|
511
|
+
acl['rules'] = rules_by_class[keep]
|
|
512
|
+
rules_by_class.delete(keep)
|
|
513
|
+
rules_by_class.each_pair { |behaviors, rules|
|
|
514
|
+
newrule = acl.dup
|
|
515
|
+
newrule['name'] += "-"+behaviors
|
|
516
|
+
newrule['rules'] = rules
|
|
517
|
+
ok = false if !config.insertKitten(newrule, "firewall_rules")
|
|
518
|
+
|
|
519
|
+
}
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
ok
|
|
268
523
|
end
|
|
269
524
|
|
|
270
525
|
private
|