gclouder 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +104 -0
- data/bin/gclouder +7 -0
- data/lib/gclouder/config/arguments.rb +35 -0
- data/lib/gclouder/config/cli_args.rb +77 -0
- data/lib/gclouder/config/cluster.rb +66 -0
- data/lib/gclouder/config/defaults.rb +35 -0
- data/lib/gclouder/config/files/project.rb +24 -0
- data/lib/gclouder/config/project.rb +34 -0
- data/lib/gclouder/config/resource_representations.rb +31 -0
- data/lib/gclouder/config_loader.rb +25 -0
- data/lib/gclouder/config_section.rb +26 -0
- data/lib/gclouder/dependencies.rb +11 -0
- data/lib/gclouder/gcloud.rb +39 -0
- data/lib/gclouder/gsutil.rb +25 -0
- data/lib/gclouder/header.rb +9 -0
- data/lib/gclouder/helpers.rb +77 -0
- data/lib/gclouder/logging.rb +181 -0
- data/lib/gclouder/mappings/argument.rb +31 -0
- data/lib/gclouder/mappings/file.rb +31 -0
- data/lib/gclouder/mappings/property.rb +31 -0
- data/lib/gclouder/mappings/resource_representation.rb +31 -0
- data/lib/gclouder/monkey_patches/array.rb +19 -0
- data/lib/gclouder/monkey_patches/boolean.rb +12 -0
- data/lib/gclouder/monkey_patches/hash.rb +44 -0
- data/lib/gclouder/monkey_patches/ipaddr.rb +10 -0
- data/lib/gclouder/monkey_patches/string.rb +30 -0
- data/lib/gclouder/resource.rb +63 -0
- data/lib/gclouder/resource_cleaner.rb +58 -0
- data/lib/gclouder/resources/compute/addresses.rb +108 -0
- data/lib/gclouder/resources/compute/bgp-vpns.rb +220 -0
- data/lib/gclouder/resources/compute/disks.rb +99 -0
- data/lib/gclouder/resources/compute/firewall_rules.rb +82 -0
- data/lib/gclouder/resources/compute/instances.rb +147 -0
- data/lib/gclouder/resources/compute/networks/subnets.rb +104 -0
- data/lib/gclouder/resources/compute/networks.rb +110 -0
- data/lib/gclouder/resources/compute/project_info/ssh_keys.rb +171 -0
- data/lib/gclouder/resources/compute/routers.rb +83 -0
- data/lib/gclouder/resources/compute/vpns.rb +199 -0
- data/lib/gclouder/resources/container/clusters.rb +257 -0
- data/lib/gclouder/resources/container/node_pools.rb +193 -0
- data/lib/gclouder/resources/dns.rb +390 -0
- data/lib/gclouder/resources/logging/sinks.rb +98 -0
- data/lib/gclouder/resources/project/iam_policy_binding.rb +293 -0
- data/lib/gclouder/resources/project.rb +85 -0
- data/lib/gclouder/resources/project_id.rb +71 -0
- data/lib/gclouder/resources/pubsub/subscriptions.rb +100 -0
- data/lib/gclouder/resources/pubsub/topics.rb +95 -0
- data/lib/gclouder/resources/storagebuckets.rb +103 -0
- data/lib/gclouder/resources/validate/global.rb +27 -0
- data/lib/gclouder/resources/validate/local.rb +68 -0
- data/lib/gclouder/resources/validate/region.rb +28 -0
- data/lib/gclouder/resources/validate/remote.rb +78 -0
- data/lib/gclouder/resources.rb +148 -0
- data/lib/gclouder/shell.rb +71 -0
- data/lib/gclouder/version.rb +5 -0
- data/lib/gclouder.rb +278 -0
- metadata +102 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module GClouder
|
4
|
+
module Resources
|
5
|
+
module Compute
|
6
|
+
module Networks
|
7
|
+
include GClouder::Config::CLIArgs
|
8
|
+
include GClouder::Config::Project
|
9
|
+
include GClouder::Logging
|
10
|
+
include GClouder::Resource::Cleaner
|
11
|
+
|
12
|
+
def self.header(stage = :ensure)
|
13
|
+
info "[#{stage}] compute / network", indent: 1, title: true
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.ensure
|
17
|
+
return if Local.list.empty?
|
18
|
+
header
|
19
|
+
|
20
|
+
Local.list.each do |region, networks|
|
21
|
+
info region, indent: 2, heading: true
|
22
|
+
info
|
23
|
+
networks.each do |network|
|
24
|
+
Network.ensure(network["name"])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.validate
|
30
|
+
return if Local.list.empty?
|
31
|
+
header :validate
|
32
|
+
Local.validate
|
33
|
+
end
|
34
|
+
|
35
|
+
module Local
|
36
|
+
include GClouder::Config::CLIArgs
|
37
|
+
include GClouder::Config::Project
|
38
|
+
include GClouder::Logging
|
39
|
+
|
40
|
+
def self.list
|
41
|
+
{ "global" => resources }.delete_if { |_k, v| v.empty? }
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.resources
|
45
|
+
merged = networks.merge(subnet_networks)["global"]
|
46
|
+
return [] unless merged
|
47
|
+
merged.uniq { |network| network["name"] }
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.validate
|
51
|
+
return if list.empty?
|
52
|
+
|
53
|
+
failure = false
|
54
|
+
|
55
|
+
list.each do |region, networks|
|
56
|
+
info region, indent: 2, heading: true
|
57
|
+
networks.each do |network|
|
58
|
+
info network["name"], indent: 3, heading: true
|
59
|
+
if !network["name"].is_a?(String)
|
60
|
+
bad "#{network['name']} is incorrect type #{network['name'].class}, should be: String", indent: 4
|
61
|
+
failure = true
|
62
|
+
end
|
63
|
+
|
64
|
+
if cli_args[:debug] || !cli_args[:output_validation]
|
65
|
+
good "network is a String", indent: 4
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
fatal "\nerror: validation failure" if failure
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.networks
|
74
|
+
GClouder::Resources::Global.instances(path: ["networks"])
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.subnet_networks
|
78
|
+
GClouder::Resources::Compute::Networks::Subnets::Local.networks
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
module Remote
|
83
|
+
def self.list
|
84
|
+
{ "global" => instances.fetch("global", []).map { |network| { "name" => network["name"] } } }.delete_if { |_k, v| v.empty? }
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.instances
|
88
|
+
Resources::Remote.instances(
|
89
|
+
path: ["compute", "networks"],
|
90
|
+
ignore_keys: ["auto_create_subnetworks", "subnetworks", "x_gcloud_mode", "range"],
|
91
|
+
skip_instances: { "name" => /^default$/ },
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
module Network
|
97
|
+
include GClouder::GCloud
|
98
|
+
|
99
|
+
def self.ensure(network)
|
100
|
+
Resource.ensure :"compute networks", network, "--mode custom"
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.purge(network)
|
104
|
+
Resource.purge :"compute networks", network
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module GClouder
|
4
|
+
module Resources
|
5
|
+
module Compute
|
6
|
+
module ProjectInfo
|
7
|
+
module SSHKeys
|
8
|
+
include GClouder::Logging
|
9
|
+
include GClouder::Config::Project
|
10
|
+
include GClouder::Config::CLIArgs
|
11
|
+
|
12
|
+
def self.header(stage = :ensure)
|
13
|
+
info "[#{stage}] compute / metadata / ssh_keys", title: true
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.clean
|
17
|
+
return unless project.key?("users")
|
18
|
+
header :clean
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.check
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.validate
|
25
|
+
return if Local.data.empty?
|
26
|
+
header :validate
|
27
|
+
Local.validate
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.ensure
|
31
|
+
return unless project.key?("users")
|
32
|
+
header :ensure
|
33
|
+
|
34
|
+
info "global", heading: true, indent: 2
|
35
|
+
info
|
36
|
+
|
37
|
+
Local.data.each do |user_data|
|
38
|
+
description = user_data[:description]
|
39
|
+
|
40
|
+
user = Remote.data.find { |entry| entry[:description] == description }
|
41
|
+
|
42
|
+
# user doesn't exist, add it..
|
43
|
+
if user.nil?
|
44
|
+
add description
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
# user exists but has been modified
|
49
|
+
if user_data[:key] != user[:key]
|
50
|
+
change description
|
51
|
+
next
|
52
|
+
end
|
53
|
+
|
54
|
+
# user exists and is the same
|
55
|
+
good description
|
56
|
+
end
|
57
|
+
|
58
|
+
Remote.data.each do |user_data|
|
59
|
+
description = user_data[:description]
|
60
|
+
|
61
|
+
next if Local.data.find { |entry| entry[:description] == description }
|
62
|
+
|
63
|
+
# user isn't defined locally, remove it
|
64
|
+
remove description, indent: 3
|
65
|
+
end
|
66
|
+
|
67
|
+
return if Local.list == Remote.list
|
68
|
+
return if cli_args[:dry_run]
|
69
|
+
|
70
|
+
Key.ensure(Local.list)
|
71
|
+
end
|
72
|
+
|
73
|
+
module Local
|
74
|
+
include GClouder::Config::Project
|
75
|
+
include GClouder::Logging
|
76
|
+
|
77
|
+
def self.list
|
78
|
+
return [] unless project.key?("users")
|
79
|
+
|
80
|
+
project["users"].sort
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.data
|
84
|
+
list.map do |line|
|
85
|
+
components = line.split
|
86
|
+
user, type = components[0].split(":")
|
87
|
+
key = components[1]
|
88
|
+
description = components.length >= 2 ? components[2] : components[0]
|
89
|
+
|
90
|
+
{ key: key, type: type, user: user, description: description }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.validate
|
95
|
+
return if data.empty?
|
96
|
+
|
97
|
+
info "global", heading: true, indent: 2
|
98
|
+
|
99
|
+
data.each do |entry|
|
100
|
+
info
|
101
|
+
info entry[:description], indent: 3
|
102
|
+
|
103
|
+
if entry[:user].is_a?(String)
|
104
|
+
good "user is a String (#{entry[:user]})", indent: 4
|
105
|
+
else
|
106
|
+
bad "user is a String (#{entry[:user]})", indent: 4
|
107
|
+
end
|
108
|
+
|
109
|
+
if entry[:key].is_a?(String)
|
110
|
+
good "key is a String (#{entry[:key].reverse.truncate(20).reverse})", indent: 4
|
111
|
+
else
|
112
|
+
bad "key isn't a String (#{entry[:key]})", indent: 4
|
113
|
+
end
|
114
|
+
|
115
|
+
if entry[:type].is_a?(String)
|
116
|
+
good "type is a String (#{entry[:type]})", indent: 4
|
117
|
+
else
|
118
|
+
bad "type isn't a String (#{entry[:type]})", indent: 4
|
119
|
+
end
|
120
|
+
|
121
|
+
# check if description exists for key
|
122
|
+
# output useruser
|
123
|
+
# output key.truncate
|
124
|
+
# output description
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
module Remote
|
130
|
+
include GClouder::GCloud
|
131
|
+
|
132
|
+
def self.list
|
133
|
+
keys = metadata.dig("items")
|
134
|
+
|
135
|
+
return [] unless keys
|
136
|
+
return [] if keys.empty?
|
137
|
+
|
138
|
+
keys.delete_if { |h| h["key"] != "sshKeys" }
|
139
|
+
keys[0]["value"].split("\n").delete_if { |key| key =~ /^gke-/ }.sort
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.data
|
143
|
+
list.map do |line|
|
144
|
+
components = line.split
|
145
|
+
user, type = components[0].split(":")
|
146
|
+
key = components[1]
|
147
|
+
description = components.length >= 2 ? components[2] : components[0]
|
148
|
+
|
149
|
+
{ key: key, type: type, user: user, description: description }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.metadata
|
154
|
+
gcloud("compute project-info describe | jq -r '.commonInstanceMetadata'", force: true)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
module Key
|
160
|
+
include GClouder::Config::Project
|
161
|
+
include GClouder::GCloud
|
162
|
+
|
163
|
+
def self.ensure(list)
|
164
|
+
list = list.join("\n") if list.is_a?(Array)
|
165
|
+
gcloud("compute project-info add-metadata --metadata sshKeys=\"#{list}\"")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module GClouder
|
4
|
+
module Resources
|
5
|
+
module Compute
|
6
|
+
module Routers
|
7
|
+
include GClouder::Config::CLIArgs
|
8
|
+
include GClouder::Config::Project
|
9
|
+
include GClouder::Logging
|
10
|
+
include GClouder::Helpers
|
11
|
+
include GClouder::Config::Arguments
|
12
|
+
include GClouder::Resource::Cleaner
|
13
|
+
|
14
|
+
def self.header(stage = :ensure)
|
15
|
+
info "[#{stage}] compute / router", title: true
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.validate
|
19
|
+
return if Local.list.empty?
|
20
|
+
header :validate
|
21
|
+
Local.validate
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.ensure
|
25
|
+
return if Local.list.empty?
|
26
|
+
header
|
27
|
+
|
28
|
+
Local.list.each do |region, routers|
|
29
|
+
next if routers.empty?
|
30
|
+
info region, heading: true, indent: 2
|
31
|
+
|
32
|
+
routers.each do |router|
|
33
|
+
info
|
34
|
+
Router.ensure(region, router["name"], hash_to_args(router))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Local
|
40
|
+
include GClouder::Logging
|
41
|
+
|
42
|
+
def self.section
|
43
|
+
["compute", "routers"]
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.list
|
47
|
+
Resources::Region.instances(path: ["routers"])
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.validate
|
51
|
+
Resources::Validate::Region.instances(
|
52
|
+
list,
|
53
|
+
required_keys: GClouder::Config::Arguments.required(section),
|
54
|
+
permitted_keys: GClouder::Config::Arguments.permitted(section),
|
55
|
+
# ignore ASN until Fixnums are supported
|
56
|
+
ignore_keys: [ "asn" ],
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module Remote
|
62
|
+
def self.list
|
63
|
+
Resources::Remote.instances(
|
64
|
+
path: ["compute", "routers"],
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module Router
|
70
|
+
include GClouder::Resource
|
71
|
+
|
72
|
+
def self.ensure(region, router, args)
|
73
|
+
Resource.ensure :"compute routers", router, "--region #{region} #{args}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.purge(region, router)
|
77
|
+
Resource.purge :"compute routers", router, "--region #{region}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module GClouder
|
4
|
+
module Resources
|
5
|
+
module Compute
|
6
|
+
module VPNs
|
7
|
+
include GClouder::GCloud
|
8
|
+
include GClouder::Shell
|
9
|
+
include GClouder::Logging
|
10
|
+
include GClouder::Config::Project
|
11
|
+
include GClouder::Config::CLIArgs
|
12
|
+
include GClouder::Resource::Cleaner
|
13
|
+
|
14
|
+
def self.header(stage = :ensure)
|
15
|
+
info "[#{stage}] compute / vpns", indent: 1, title: true
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.validate
|
19
|
+
return if Local.list.empty?
|
20
|
+
header :validate
|
21
|
+
Local.validate
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.dir
|
25
|
+
cli_args[:keys_dir] || File.join(ENV["HOME"], "keys")
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.ensure
|
29
|
+
return if Local.list.empty?
|
30
|
+
|
31
|
+
header
|
32
|
+
|
33
|
+
Local.list.each do |region, instances|
|
34
|
+
info region, indent: 2, heading: true
|
35
|
+
info
|
36
|
+
|
37
|
+
instances.each do |vpn|
|
38
|
+
skip_vpn = false
|
39
|
+
|
40
|
+
# if 'shared_secret' key is set, use it
|
41
|
+
# if not, fall back to trying to read the secret from an environment variable, the name
|
42
|
+
# of which is provided by the 'shared_secret_env_var' key
|
43
|
+
unless vpn.key?("shared_secret") || vpn.key?("shared_secret_env_var") || vpn.key?("shared_secret_file")
|
44
|
+
if cli_args[:dry_run]
|
45
|
+
warning "skipping resource since no shared secret found for VPN and this is a dry run"
|
46
|
+
skip_vpn = true
|
47
|
+
else
|
48
|
+
fatal "shared_secret_env_var or shared_secret must be set for region/vpn: #{region}/#{vpn["name"]}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
vpn["shared_secret"] = if vpn.key?("shared_secret") && !vpn["shared_secret"].empty? && !vpn["shared_secret"].nil?
|
53
|
+
vpn["shared_secret"]
|
54
|
+
else
|
55
|
+
ENV[vpn["shared_secret_env_var"]] if vpn["shared_secret_env_var"]
|
56
|
+
end
|
57
|
+
|
58
|
+
# this overrides the above for now..
|
59
|
+
if vpn.key?("shared_secret_file")
|
60
|
+
config_file = File.join(dir, vpn["shared_secret_file"])
|
61
|
+
|
62
|
+
if !File.exists?(config_file)
|
63
|
+
fatal "shared_secret_file specified for vpn but no file found for region/vpn: #{region}/#{vpn["name"]}"
|
64
|
+
end
|
65
|
+
|
66
|
+
vpn["shared_secret"] = File.read(config_file)
|
67
|
+
end
|
68
|
+
|
69
|
+
vpn.delete("shared_secret_env_var") if vpn.key?("shared_secret_env_var")
|
70
|
+
vpn.delete("shared_secret_file") if vpn.key?("shared_secret_file")
|
71
|
+
|
72
|
+
required_params = %w(peer_address shared_secret ike_version remote_traffic_selector
|
73
|
+
local_traffic_selector target_vpn_gateway network)
|
74
|
+
|
75
|
+
required_params.each do |param|
|
76
|
+
fatal "no #{param} defined for region/vpn: #{region}/#{vpn}" unless vpn.key?(param)
|
77
|
+
|
78
|
+
# FIXME: change once hashie has been ripped out
|
79
|
+
if vpn[param].nil?
|
80
|
+
if cli_args[:dry_run]
|
81
|
+
warning "no #{param} defined for region/vpn: #{vpn["name"]} [#{region}]"
|
82
|
+
skip_vpn = true
|
83
|
+
else
|
84
|
+
fatal "no #{param} defined for region/vpn: #{vpn["name"]} [#{region}]"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
if vpn[param].is_a?(String)
|
89
|
+
if cli_args[:dry_run]
|
90
|
+
warning "no #{param} defined for region/vpn: #{vpn["name"]} [#{region}]" if vpn[param].empty?
|
91
|
+
skip_vpn = true
|
92
|
+
else
|
93
|
+
fatal "no #{param} defined for region/vpn: #{vpn["name"]} [#{region}]" if vpn[param].empty?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
next if skip_vpn && !cli_args[:dry_run]
|
99
|
+
|
100
|
+
VPN.create(region, vpn["name"], vpn)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
module Local
|
106
|
+
def self.section
|
107
|
+
["vpns"]
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.list
|
111
|
+
Resources::Region.instances(path: section).delete_if { |_k, v| v.empty? }
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.validate
|
115
|
+
Resources::Validate::Region.instances(
|
116
|
+
list,
|
117
|
+
required_keys: GClouder::Config::Arguments.required(["compute", "vpn-tunnels"]),
|
118
|
+
permitted_keys: GClouder::Config::Arguments.permitted(["compute", "vpn-tunnels"]),
|
119
|
+
ignore_keys: ["ike_version", "shared_secret_file", "network"]
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
module Remote
|
125
|
+
def self.list
|
126
|
+
Resources::Remote.instances(path: %w(compute vpn-tunnels))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
module VPN
|
131
|
+
include GClouder::GCloud
|
132
|
+
include GClouder::Shell
|
133
|
+
include GClouder::Logging
|
134
|
+
include GClouder::Helpers
|
135
|
+
include GClouder::Config::CLIArgs
|
136
|
+
|
137
|
+
def self.create(region, vpn, vpn_config)
|
138
|
+
network = vpn_config['network']
|
139
|
+
Resource.ensure :"compute target-vpn-gateways", vpn_config["target_vpn_gateway"],
|
140
|
+
"--network #{network} --region #{region}"
|
141
|
+
|
142
|
+
vpn_config.delete("network")
|
143
|
+
|
144
|
+
return if cli_args[:dry_run]
|
145
|
+
|
146
|
+
ip_data = gcloud("--format json compute addresses describe vpn-#{vpn} --region=#{region}", force: true)
|
147
|
+
|
148
|
+
unless ip_data.key?("address")
|
149
|
+
fatal "could not find address for static ip with key: vpn-#{vpn} (is key allocated in project config?)"
|
150
|
+
end
|
151
|
+
|
152
|
+
address = ip_data["address"]
|
153
|
+
|
154
|
+
Resource.ensure :"compute forwarding-rules",
|
155
|
+
"#{vpn}-esp",
|
156
|
+
"--region #{region} \
|
157
|
+
--ip-protocol ESP \
|
158
|
+
--address #{address} \
|
159
|
+
--target-vpn-gateway=#{vpn_config['target_vpn_gateway']}",
|
160
|
+
silent: true
|
161
|
+
|
162
|
+
Resource.ensure :"compute forwarding-rules",
|
163
|
+
"#{vpn}-udp500",
|
164
|
+
"--region #{region} \
|
165
|
+
--ip-protocol UDP \
|
166
|
+
--ports 500 \
|
167
|
+
--address #{address} \
|
168
|
+
--target-vpn-gateway=#{vpn_config['target_vpn_gateway']}",
|
169
|
+
silent: true
|
170
|
+
|
171
|
+
Resource.ensure :"compute forwarding-rules",
|
172
|
+
"#{vpn}-udp4500",
|
173
|
+
"--region #{region} --ip-protocol UDP --ports 4500 --address #{address} \
|
174
|
+
--target-vpn-gateway=#{vpn_config['target_vpn_gateway']}",
|
175
|
+
silent: true
|
176
|
+
|
177
|
+
Resource.ensure :"compute vpn-tunnels", vpn,
|
178
|
+
"--region=#{region} #{hash_to_args(vpn_config)}",
|
179
|
+
silent: true
|
180
|
+
|
181
|
+
vpn_config["remote_traffic_selector"].each_with_index do |range, index|
|
182
|
+
Resource.ensure :"compute routes",
|
183
|
+
"route-#{vpn}-#{index}",
|
184
|
+
"--network=#{network} --next-hop-vpn-tunnel=#{vpn} \
|
185
|
+
--next-hop-vpn-tunnel-region=#{region} --destination-range=#{range}",
|
186
|
+
silent: true
|
187
|
+
end
|
188
|
+
|
189
|
+
GClouder::Resources::Compute::FirewallRules::Rule.ensure("vpn-#{vpn}-icmp", {
|
190
|
+
"network" => network,
|
191
|
+
"source-ranges" => vpn_config["remote_traffic_selector"],
|
192
|
+
"allow" => "icmp"
|
193
|
+
}, silent: true)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|