glb 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/.gitignore +17 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +6 -0
- data/Guardfile +19 -0
- data/LICENSE.txt +1 -0
- data/README.md +51 -0
- data/Rakefile +6 -0
- data/docs/external.md +19 -0
- data/docs/internal.md +65 -0
- data/docs/ssl.md +33 -0
- data/docs/static-ip-address.md +30 -0
- data/exe/glb +14 -0
- data/glb.gemspec +33 -0
- data/lib/glb/autoloader.rb +21 -0
- data/lib/glb/cli/base.rb +15 -0
- data/lib/glb/cli/help/completion.md +20 -0
- data/lib/glb/cli/help/completion_script.md +3 -0
- data/lib/glb/cli/help.rb +11 -0
- data/lib/glb/cli.rb +48 -0
- data/lib/glb/command.rb +91 -0
- data/lib/glb/completer/script.rb +8 -0
- data/lib/glb/completer/script.sh +10 -0
- data/lib/glb/completer.rb +159 -0
- data/lib/glb/config.rb +147 -0
- data/lib/glb/core.rb +27 -0
- data/lib/glb/lb/args.rb +66 -0
- data/lib/glb/lb/backend_service/backend.rb +94 -0
- data/lib/glb/lb/backend_service.rb +19 -0
- data/lib/glb/lb/firewall_rule.rb +9 -0
- data/lib/glb/lb/forwarding_rule.rb +16 -0
- data/lib/glb/lb/forwarding_rule_https.rb +24 -0
- data/lib/glb/lb/health_check.rb +13 -0
- data/lib/glb/lb/names.rb +50 -0
- data/lib/glb/lb/resource.rb +119 -0
- data/lib/glb/lb/target_http_proxy.rb +9 -0
- data/lib/glb/lb/target_https_proxy.rb +4 -0
- data/lib/glb/lb/url_map.rb +9 -0
- data/lib/glb/lb.rb +110 -0
- data/lib/glb/util/sh.rb +37 -0
- data/lib/glb/util/sure.rb +18 -0
- data/lib/glb/version.rb +3 -0
- data/lib/glb.rb +22 -0
- data/spec/cli_spec.rb +26 -0
- data/spec/spec_helper.rb +29 -0
- metadata +245 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
=begin
|
2
|
+
Code Explanation:
|
3
|
+
|
4
|
+
There are 3 types of things to auto-complete:
|
5
|
+
|
6
|
+
1. command: the command itself
|
7
|
+
2. parameters: command parameters.
|
8
|
+
3. options: command options
|
9
|
+
|
10
|
+
Here's an example:
|
11
|
+
|
12
|
+
mycli hello name --from me
|
13
|
+
|
14
|
+
* command: hello
|
15
|
+
* parameters: name
|
16
|
+
* option: --from
|
17
|
+
|
18
|
+
When command parameters are done processing, the remaining completion words will be options. We can tell that the command params are completed based on the method arity.
|
19
|
+
|
20
|
+
## Arity
|
21
|
+
|
22
|
+
For example, say you had a method for a CLI command with the following form:
|
23
|
+
|
24
|
+
ufo scale service count --cluster development
|
25
|
+
|
26
|
+
It's equivalent ruby method:
|
27
|
+
|
28
|
+
scale(service, count) = has an arity of 2
|
29
|
+
|
30
|
+
So typing:
|
31
|
+
|
32
|
+
ufo scale service count [TAB] # there are 3 parameters including the "scale" command according to Thor's CLI processing.
|
33
|
+
|
34
|
+
So the completion should only show options, something like this:
|
35
|
+
|
36
|
+
--noop --verbose --cluster
|
37
|
+
|
38
|
+
## Splat Arguments
|
39
|
+
|
40
|
+
When the ruby method has a splat argument, it's arity is negative. Here are some example methods and their arities.
|
41
|
+
|
42
|
+
ship(service) = 1
|
43
|
+
scale(service, count) = 2
|
44
|
+
ships(*services) = -1
|
45
|
+
foo(example, *rest) = -2
|
46
|
+
|
47
|
+
Fortunately, negative and positive arity values are processed the same way. So we take simply take the absolute value of the arity and process it the same.
|
48
|
+
|
49
|
+
Here are some test cases, hit TAB after typing the command:
|
50
|
+
|
51
|
+
glb completion
|
52
|
+
glb completion hello
|
53
|
+
glb completion hello name
|
54
|
+
glb completion hello name --
|
55
|
+
glb completion hello name --noop
|
56
|
+
|
57
|
+
glb completion
|
58
|
+
glb completion sub:goodbye
|
59
|
+
glb completion sub:goodbye name
|
60
|
+
|
61
|
+
## Subcommands and Thor::Group Registered Commands
|
62
|
+
|
63
|
+
Sometimes the commands are not simple thor commands but are subcommands or Thor::Group commands. A good specific example is the ufo tool.
|
64
|
+
|
65
|
+
* regular command: ufo ship
|
66
|
+
* subcommand: ufo docker
|
67
|
+
* Thor::Group command: ufo init
|
68
|
+
|
69
|
+
Auto-completion accounts for each of these type of commands.
|
70
|
+
=end
|
71
|
+
module Glb
|
72
|
+
class Completer
|
73
|
+
def initialize(command_class, *params)
|
74
|
+
@params = params
|
75
|
+
@current_command = @params[0]
|
76
|
+
@command_class = command_class # CLI initiall
|
77
|
+
end
|
78
|
+
|
79
|
+
def run
|
80
|
+
if subcommand?(@current_command)
|
81
|
+
subcommand_class = @command_class.subcommand_classes[@current_command]
|
82
|
+
@params.shift # destructive
|
83
|
+
Completer.new(subcommand_class, *@params).run # recursively use subcommand
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
# full command has been found!
|
88
|
+
unless found?(@current_command)
|
89
|
+
puts all_commands
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
# will only get to here if command aws found (above)
|
94
|
+
arity = @command_class.instance_method(@current_command).arity.abs
|
95
|
+
if @params.size > arity or thor_group_command?
|
96
|
+
puts options_completion
|
97
|
+
else
|
98
|
+
puts params_completion
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def subcommand?(command)
|
103
|
+
@command_class.subcommands.include?(command)
|
104
|
+
end
|
105
|
+
|
106
|
+
# hacky way to detect that command is a registered Thor::Group command
|
107
|
+
def thor_group_command?
|
108
|
+
command_params(raw=true) == [[:rest, :args]]
|
109
|
+
end
|
110
|
+
|
111
|
+
def found?(command)
|
112
|
+
public_methods = @command_class.public_instance_methods(false)
|
113
|
+
command && public_methods.include?(command.to_sym)
|
114
|
+
end
|
115
|
+
|
116
|
+
# all top-level commands
|
117
|
+
def all_commands
|
118
|
+
commands = @command_class.all_commands.reject do |k,v|
|
119
|
+
v.is_a?(Thor::HiddenCommand)
|
120
|
+
end
|
121
|
+
commands.keys
|
122
|
+
end
|
123
|
+
|
124
|
+
def command_params(raw=false)
|
125
|
+
params = @command_class.instance_method(@current_command).parameters
|
126
|
+
# Example:
|
127
|
+
# >> Sub.instance_method(:goodbye).parameters
|
128
|
+
# => [[:req, :name]]
|
129
|
+
# >>
|
130
|
+
raw ? params : params.map!(&:last)
|
131
|
+
end
|
132
|
+
|
133
|
+
def params_completion
|
134
|
+
offset = @params.size - 1
|
135
|
+
offset_params = command_params[offset..-1]
|
136
|
+
command_params[offset..-1].first
|
137
|
+
end
|
138
|
+
|
139
|
+
def options_completion
|
140
|
+
used = ARGV.select { |a| a.include?('--') } # so we can remove used options
|
141
|
+
|
142
|
+
method_options = @command_class.all_commands[@current_command].options.keys
|
143
|
+
class_options = @command_class.class_options.keys
|
144
|
+
|
145
|
+
all_options = method_options + class_options + ['help']
|
146
|
+
|
147
|
+
all_options.map! { |o| "--#{o.to_s.gsub('_','-')}" }
|
148
|
+
filtered_options = all_options - used
|
149
|
+
filtered_options.uniq
|
150
|
+
end
|
151
|
+
|
152
|
+
# Useful for debugging. Using puts messes up completion.
|
153
|
+
def log(msg)
|
154
|
+
File.open("/tmp/complete.log", "a") do |file|
|
155
|
+
file.puts(msg)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
data/lib/glb/config.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require "singleton"
|
2
|
+
|
3
|
+
module Glb
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
include DslEvaluator
|
7
|
+
|
8
|
+
attr_reader :config
|
9
|
+
def initialize
|
10
|
+
@config = defaults
|
11
|
+
end
|
12
|
+
|
13
|
+
def defaults
|
14
|
+
config = ActiveSupport::OrderedOptions.new
|
15
|
+
|
16
|
+
config.lb = ActiveSupport::OrderedOptions.new
|
17
|
+
# config.lb.region = "us-central1"
|
18
|
+
# config.lb.load_balancing_scheme = "INTERNAL_MANAGED"
|
19
|
+
# config.lb.network = "dev"
|
20
|
+
# config.lb.subnet = "dev-app"
|
21
|
+
|
22
|
+
config.firewall_rule = ActiveSupport::OrderedOptions.new
|
23
|
+
config.firewall_rule.action = "allow"
|
24
|
+
config.firewall_rule.direction = "ingress"
|
25
|
+
config.firewall_rule.network = nil # default in set_from_lb_config
|
26
|
+
config.firewall_rule.rules = "tcp:80"
|
27
|
+
config.firewall_rule.source_ranges = "130.211.0.0/22,35.191.0.0/16" # load balancer
|
28
|
+
# config.firewall_rule.target_tags = @name # @name is not available here
|
29
|
+
|
30
|
+
config.health_check = ActiveSupport::OrderedOptions.new
|
31
|
+
config.health_check.port = 80
|
32
|
+
config.health_check.request_path = "/"
|
33
|
+
config.health_check.region = nil
|
34
|
+
|
35
|
+
config.backend_service = ActiveSupport::OrderedOptions.new
|
36
|
+
config.backend_service.load_balancing_scheme = nil # default in set_from_lb_config
|
37
|
+
config.backend_service.protocol = "HTTP"
|
38
|
+
config.backend_service.port_name = "http"
|
39
|
+
config.backend_service.region = nil
|
40
|
+
# config.backend_service.health_checks = health_check_name # health_check_name is not available here
|
41
|
+
|
42
|
+
config.backend_service.add_backend = ActiveSupport::OrderedOptions.new
|
43
|
+
config.backend_service.add_backend.balancing_mode = "RATE"
|
44
|
+
config.backend_service.add_backend.max_rate_per_endpoint = "1.0"
|
45
|
+
config.backend_service.add_backend.region = nil
|
46
|
+
config.backend_service.health_checks_region = nil
|
47
|
+
# config.backend_service.add_backend.network_endpoint_group_zone = google_zone, # google_zone is not available here
|
48
|
+
# config.backend_service.add_backend.network_endpoint_group = network_endpoint_group # network_endpoint_group is not available here
|
49
|
+
|
50
|
+
config.url_map = ActiveSupport::OrderedOptions.new
|
51
|
+
config.url_map.region = nil
|
52
|
+
# config.url_map.default_service = backend_service_name # backend_service_name is not available here
|
53
|
+
|
54
|
+
config.target_http_proxy = ActiveSupport::OrderedOptions.new
|
55
|
+
config.target_http_proxy.region = nil
|
56
|
+
# config.target_http_proxy.url_map = url_map_name # url_map_name is not available here
|
57
|
+
|
58
|
+
config.target_https_proxy = ActiveSupport::OrderedOptions.new
|
59
|
+
config.target_https_proxy.region = nil
|
60
|
+
config.target_https_proxy.ssl_certificates = nil # must be assigned by user
|
61
|
+
# config.target_https_proxy.url_map = url_map_name # url_map_name is not available here
|
62
|
+
|
63
|
+
config.forwarding_rule = ActiveSupport::OrderedOptions.new
|
64
|
+
config.forwarding_rule.load_balancing_scheme = nil # default in set_from_lb_config
|
65
|
+
config.forwarding_rule.ports = 80
|
66
|
+
config.forwarding_rule.region = nil
|
67
|
+
# config.forwarding_rule.target_http_proxy = target_http_proxy_name # target_http_proxy_name is not available here
|
68
|
+
|
69
|
+
config.forwarding_rule_https = ActiveSupport::OrderedOptions.new
|
70
|
+
config.forwarding_rule_https.load_balancing_scheme = nil # default in set_from_lb_config
|
71
|
+
config.forwarding_rule_https.ports = 443
|
72
|
+
config.forwarding_rule_https.region = nil
|
73
|
+
# config.forwarding_rule_https.target_http_proxy = target_http_proxy_name # target_http_proxy_name is not available here
|
74
|
+
|
75
|
+
config.show = ActiveSupport::OrderedOptions.new
|
76
|
+
config.show.format = nil
|
77
|
+
|
78
|
+
config.naming = ActiveSupport::OrderedOptions.new
|
79
|
+
config.naming.include_type = false
|
80
|
+
|
81
|
+
config
|
82
|
+
end
|
83
|
+
|
84
|
+
def configure
|
85
|
+
yield(@config)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Load configs example:
|
89
|
+
#
|
90
|
+
# .glb/config.rb
|
91
|
+
# .glb/config/env/dev.rb
|
92
|
+
#
|
93
|
+
def load_configs
|
94
|
+
evaluate_file(".glb/config.rb")
|
95
|
+
evaluate_file(".glb/config/env/#{Glb.env}.rb")
|
96
|
+
if Glb.app
|
97
|
+
evaluate_file(".glb/config/app/#{Glb.app}.rb")
|
98
|
+
evaluate_file(".glb/config/app/#{Glb.app}/#{Glb.env}.rb")
|
99
|
+
end
|
100
|
+
set_from_lb_config
|
101
|
+
end
|
102
|
+
|
103
|
+
# Simpiflies the required config values to be set for an internal load balancer
|
104
|
+
# by providing shorthand config.lb options. Example:
|
105
|
+
#
|
106
|
+
# config.lb.region = "us-central1"
|
107
|
+
# config.lb.load_balancing_scheme = "INTERNAL_MANAGED"
|
108
|
+
# config.lb.network = "dev"
|
109
|
+
# config.lb.subnet = "dev-app"
|
110
|
+
#
|
111
|
+
# Called in initialize so that config values are set before any methods are called.
|
112
|
+
# IE: region_option or args
|
113
|
+
def set_from_lb_config
|
114
|
+
config.firewall_rule.network ||= config.lb.network || "default"
|
115
|
+
|
116
|
+
config.health_check.region ||= config.lb.region
|
117
|
+
|
118
|
+
config.backend_service.load_balancing_scheme ||= config.lb.load_balancing_scheme || "EXTERNAL_MANAGED"
|
119
|
+
config.backend_service.region ||= config.lb.region
|
120
|
+
config.backend_service.health_checks_region ||= config.lb.region
|
121
|
+
config.backend_service.add_backend.region ||= config.lb.region
|
122
|
+
|
123
|
+
config.url_map.region ||= config.lb.region
|
124
|
+
|
125
|
+
config.target_http_proxy.region ||= config.lb.region
|
126
|
+
|
127
|
+
config.target_https_proxy.region ||= config.lb.region
|
128
|
+
config.target_https_proxy.ssl_certificates ||= config.lb.ssl_certificates
|
129
|
+
|
130
|
+
config.forwarding_rule.region ||= config.lb.region
|
131
|
+
config.forwarding_rule.network ||= config.lb.network
|
132
|
+
config.forwarding_rule.subnet ||= config.lb.subnet
|
133
|
+
config.forwarding_rule.load_balancing_scheme ||= config.lb.load_balancing_scheme || "EXTERNAL_MANAGED"
|
134
|
+
config.forwarding_rule.target_http_proxy_region ||= config.lb.region
|
135
|
+
|
136
|
+
config.forwarding_rule_https.region ||= config.lb.region
|
137
|
+
config.forwarding_rule_https.network ||= config.lb.network
|
138
|
+
config.forwarding_rule_https.subnet ||= config.lb.subnet
|
139
|
+
config.forwarding_rule_https.load_balancing_scheme ||= config.lb.load_balancing_scheme || "EXTERNAL_MANAGED"
|
140
|
+
config.forwarding_rule_https.target_https_proxy_region ||= config.lb.region
|
141
|
+
|
142
|
+
# Set to true to create target_https_proxy and additional forwarding_rule which uses https settings
|
143
|
+
config.lb.enabled = false
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
data/lib/glb/core.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Glb
|
2
|
+
module Core
|
3
|
+
extend Memoist
|
4
|
+
|
5
|
+
def app
|
6
|
+
ENV['GLB_APP'] unless ENV['GLB_APP'].blank?
|
7
|
+
end
|
8
|
+
|
9
|
+
def env
|
10
|
+
ENV['GLB_ENV'].blank? ? "dev" : ENV['GLB_ENV']
|
11
|
+
end
|
12
|
+
|
13
|
+
def extra
|
14
|
+
ENV['GLB_EXTRA'] unless ENV['GLB_EXTRA'].blank?
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure(&block)
|
18
|
+
Config.instance.configure(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def config
|
22
|
+
Config.instance.load_configs
|
23
|
+
Config.instance.config
|
24
|
+
end
|
25
|
+
memoize :config
|
26
|
+
end
|
27
|
+
end
|
data/lib/glb/lb/args.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
class Glb::Lb
|
2
|
+
class Args
|
3
|
+
extend Memoist
|
4
|
+
include Glb::Util::Sh
|
5
|
+
|
6
|
+
# command: "firewall-rule create"
|
7
|
+
def initialize(command, opts)
|
8
|
+
@command, @opts = command, opts
|
9
|
+
end
|
10
|
+
|
11
|
+
# Converts a hash of options to a string of gcloud arguments
|
12
|
+
def transform
|
13
|
+
return "" if invalid_command?
|
14
|
+
options = @opts.dup
|
15
|
+
options.compact!
|
16
|
+
options[:global] = true unless options[:region]
|
17
|
+
allowed = allowed_options(@command)
|
18
|
+
allowed.map! { |o| o.gsub("-", "_") }
|
19
|
+
options = options.select { |k,v| allowed.include?(k.to_s) }
|
20
|
+
|
21
|
+
options.map do |k,v|
|
22
|
+
k = k.to_s.gsub("_", "-")
|
23
|
+
k = "--#{k}"
|
24
|
+
if v == true
|
25
|
+
k # IE: --global
|
26
|
+
elsif v == false
|
27
|
+
""
|
28
|
+
else
|
29
|
+
"#{k}=#{v}"
|
30
|
+
end
|
31
|
+
end.sort.join(" ").squish
|
32
|
+
end
|
33
|
+
|
34
|
+
def invalid_command?
|
35
|
+
@command == "url-maps update"
|
36
|
+
end
|
37
|
+
|
38
|
+
def allowed_options(command)
|
39
|
+
lines = capture("gcloud help compute #{command}", show_command: false).split("\n")
|
40
|
+
lines = lines.grep(/--/)
|
41
|
+
lines = filter_special_cases(lines)
|
42
|
+
lines.map do |line|
|
43
|
+
md = line.match(/--([\w-]+)/)
|
44
|
+
md[1] if md
|
45
|
+
end.compact.sort.uniq
|
46
|
+
end
|
47
|
+
memoize :allowed_options
|
48
|
+
|
49
|
+
# Note: Tried filtering out lines with bold text, but it didn't work. It introduced too many bugs.
|
50
|
+
#
|
51
|
+
# " \e[1m--priority\e[m=\e[4mPRIORITY\e[m",
|
52
|
+
# " \e[1m--rules\e[m=[\e[4mPROTOCOL\e[m[:\e[4mPORT\e[m[-\e[4mPORT\e[m]],...]",
|
53
|
+
# " \e[1m--source-ranges\e[m=[\e[4mCIDR_RANGE\e[m,...]",
|
54
|
+
#
|
55
|
+
# regexp to match bold text: /^\s+.?\[1m--/ (attempt)
|
56
|
+
# line.match(/^\s+.?\[1m--/)
|
57
|
+
#
|
58
|
+
def filter_special_cases(lines)
|
59
|
+
case @command
|
60
|
+
when "backend-services update"
|
61
|
+
lines = lines.reject { |line| line.include?("--load-balancing-scheme") }
|
62
|
+
end
|
63
|
+
lines
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class Glb::Lb::BackendService
|
2
|
+
class Backend < Glb::Lb::Resource
|
3
|
+
# override so resource_name, resource_config, and region_option are correct
|
4
|
+
def resource_type
|
5
|
+
"backend_service"
|
6
|
+
end
|
7
|
+
|
8
|
+
def resource_name
|
9
|
+
backend_service_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def add
|
13
|
+
return unless network_endpoint_group
|
14
|
+
validate_neg_exists!
|
15
|
+
|
16
|
+
google_zones.each do |zone|
|
17
|
+
if backend_added?(zone)
|
18
|
+
puts "Backend already added. network_endpoint_group: #{network_endpoint_group} backend_service: #{resource_name} zone: #{zone}"
|
19
|
+
else
|
20
|
+
sh add_command(zone)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_commands
|
26
|
+
google_zones.map do |zone|
|
27
|
+
add_command(zone)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_command(zone)
|
32
|
+
"gcloud compute backend-services add-backend #{resource_name} #{add_args(zone)}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_args(zone)
|
36
|
+
defaults = {
|
37
|
+
network_endpoint_group_zone: zone, # us-central1-a
|
38
|
+
network_endpoint_group: network_endpoint_group,
|
39
|
+
}
|
40
|
+
opts = defaults.merge(config.backend_service.add_backend)
|
41
|
+
Glb::Lb::Args.new("backend-services add-backend", opts).transform
|
42
|
+
end
|
43
|
+
|
44
|
+
def backend_added?(zone)
|
45
|
+
@describe_cache ||= capture "gcloud compute backend-services describe #{resource_name} #{region_option} --format json"
|
46
|
+
return false if @describe_cache.blank?
|
47
|
+
|
48
|
+
data = JSON.load(@describe_cache)
|
49
|
+
backends = data["backends"]
|
50
|
+
return false unless backends
|
51
|
+
|
52
|
+
# "backends": [
|
53
|
+
# {
|
54
|
+
# "balancingMode": "RATE",
|
55
|
+
# "capacityScaler": 1,
|
56
|
+
# "group": "https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/networkEndpointGroups/NEG",
|
57
|
+
# "maxRatePerEndpoint": 1
|
58
|
+
# }
|
59
|
+
backends.any? do |b|
|
60
|
+
# https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/networkEndpointGroups/NEG
|
61
|
+
parts = b["group"].split("/")
|
62
|
+
parts.last == network_endpoint_group && parts[-3] == zone
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
# Validate by checking if the network_endpoint_group exists in any google zone
|
68
|
+
def validate_neg_exists!
|
69
|
+
if google_zones.empty?
|
70
|
+
puts <<~EOL.color(:red)
|
71
|
+
ERROR: Could not find network_endpoint_group: #{network_endpoint_group}
|
72
|
+
in any google zones.
|
73
|
+
|
74
|
+
Please check that the network_endpoint_group exists and try again.
|
75
|
+
|
76
|
+
gcloud compute network-endpoint-groups list --filter='name=#{network_endpoint_group}'
|
77
|
+
|
78
|
+
EOL
|
79
|
+
exit 1
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def google_zones
|
84
|
+
out = capture "gcloud compute network-endpoint-groups list --filter='name=#{network_endpoint_group}' --format json", show_command: false
|
85
|
+
groups = JSON.load(out)
|
86
|
+
groups = groups.map { |g| g["zone"].split("/").last }
|
87
|
+
end
|
88
|
+
memoize :google_zones
|
89
|
+
|
90
|
+
def network_endpoint_group
|
91
|
+
Glb.config.backend_service.add_backend.network_endpoint_group
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Glb::Lb
|
2
|
+
class BackendService < Resource
|
3
|
+
def default_options
|
4
|
+
{
|
5
|
+
health_checks: health_check_name,
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
def up
|
10
|
+
super
|
11
|
+
backend.add
|
12
|
+
end
|
13
|
+
|
14
|
+
def backend
|
15
|
+
Backend.new(@options)
|
16
|
+
end
|
17
|
+
memoize :backend
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Glb::Lb
|
2
|
+
class ForwardingRule < Resource
|
3
|
+
def default_options
|
4
|
+
{
|
5
|
+
target_http_proxy: target_http_proxy_name,
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
def show_ip
|
10
|
+
out = capture "gcloud compute forwarding-rules describe #{resource_name} #{region_option} --format json", show_command: false
|
11
|
+
ip = JSON.parse(out)["IPAddress"]
|
12
|
+
name = self.class.name.split('::').last.underscore.humanize
|
13
|
+
puts "#{name} ip: #{ip}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Glb::Lb
|
2
|
+
class ForwardingRuleHttps < ForwardingRule
|
3
|
+
# override so resource_name is correct
|
4
|
+
def resource_type
|
5
|
+
"forwarding_rule"
|
6
|
+
end
|
7
|
+
|
8
|
+
# override so resource_name is correct
|
9
|
+
def resource_name
|
10
|
+
forwarding_rule_https_name
|
11
|
+
end
|
12
|
+
|
13
|
+
# override so resource_config and region_option are correct
|
14
|
+
def resource_config
|
15
|
+
config.forwarding_rule_https
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_options
|
19
|
+
{
|
20
|
+
target_https_proxy: target_https_proxy_name,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Glb::Lb
|
2
|
+
class HealthCheck < Resource
|
3
|
+
# Override to add http to the command
|
4
|
+
def up_command
|
5
|
+
"gcloud compute health-checks #{action} http #{resource_name} #{args}" if valid?
|
6
|
+
end
|
7
|
+
|
8
|
+
# Override to add http to the command
|
9
|
+
def args
|
10
|
+
Args.new("health-checks #{action} http", config.health_check).transform
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/glb/lb/names.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
class Glb::Lb
|
2
|
+
module Names
|
3
|
+
def firewall_rule_name
|
4
|
+
build_name("#{network}-#{@name}", 'firewall-rule') # IE: dev-demo-dev
|
5
|
+
end
|
6
|
+
|
7
|
+
# firewall_rule_name network method to be defined in the class
|
8
|
+
# defined here to make easier to follow
|
9
|
+
def network
|
10
|
+
Glb.config.firewall_rule.network
|
11
|
+
end
|
12
|
+
|
13
|
+
def health_check_name
|
14
|
+
build_name(@name, 'health-check') # IE: demo-health-check-dev
|
15
|
+
end
|
16
|
+
|
17
|
+
def backend_service_name
|
18
|
+
build_name(@name, 'backend-service') # IE: demo-backend-service-dev
|
19
|
+
end
|
20
|
+
|
21
|
+
def url_map_name
|
22
|
+
build_name(@name, 'url-map') # IE: demo-url-map-dev
|
23
|
+
end
|
24
|
+
|
25
|
+
def target_http_proxy_name
|
26
|
+
build_name(@name, 'target-http-proxy') # IE: demo-target-http-proxy-dev
|
27
|
+
end
|
28
|
+
|
29
|
+
def forwarding_rule_name
|
30
|
+
build_name(@name, 'forwarding-rule')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Note: target_https_proxy name can be the same as target_http_proxy name
|
34
|
+
# Google considers them different types of resources.
|
35
|
+
def target_https_proxy_name
|
36
|
+
build_name(@name, 'target-https-proxy') # IE: demo-target-https-proxy-dev
|
37
|
+
end
|
38
|
+
|
39
|
+
# Note: forwarding rules for https must be differently named from the http one
|
40
|
+
# Google considers them the type of resources.
|
41
|
+
def forwarding_rule_https_name
|
42
|
+
build_name(@name, 'forwarding-rule', 'https') # IE: demo-forwarding-rule-https-dev
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_name(name, type, infix=nil)
|
46
|
+
type = nil unless config.naming.include_type
|
47
|
+
[name, type, infix, Glb.env, Glb.extra].compact.join('-') # IE: demo-health-check-dev
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|