aptible-cli 0.26.5 → 0.26.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/aptible/cli/helpers/vhost/option_set_builder.rb +154 -1
- data/lib/aptible/cli/helpers/vhost.rb +5 -2
- data/lib/aptible/cli/renderer/text.rb +3 -1
- data/lib/aptible/cli/resource_formatter.rb +6 -0
- data/lib/aptible/cli/subcommands/endpoints.rb +27 -9
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/helpers/vhost/option_set_builder_spec.rb +94 -0
- data/spec/aptible/cli/resource_formatter_spec.rb +3 -0
- data/spec/aptible/cli/subcommands/endpoints_spec.rb +178 -4
- data/spec/fabricators/setting_fabricator.rb +8 -0
- data/spec/fabricators/vhost_fabricator.rb +2 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96e4d08173fd6d471b8a0a4f625d5bc1b3cf22af4c6cf2bb71fb3da109bc27af
|
|
4
|
+
data.tar.gz: 53ff531ac50e1a925a7c6ddc01bf5cdc7c972333e4f7ef72e5af83b0001c5ae0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dec6c2d62bbe07eb89627dad9c1984133e7768f4b87316ac3029a1fd94f71d22418ca6b3ad73efa445425e60cd620d75d9653b23e4da10c7f28a62b6fc460d69
|
|
7
|
+
data.tar.gz: fd1b7ab666de7e4e13300ba4057d265edf919f40abaddcac96a90f9437b8ad23144775f4fc49124bae2af06f668aea57bdf976eeffa1fab60a7e01abb5ffd241
|
data/Gemfile.lock
CHANGED
|
@@ -14,6 +14,35 @@ module Aptible
|
|
|
14
14
|
alb
|
|
15
15
|
).freeze
|
|
16
16
|
|
|
17
|
+
SSL_PROTOCOL_VALUES = [
|
|
18
|
+
'TLSv1 TLSv1.1 TLSv1.2',
|
|
19
|
+
'TLSv1 TLSv1.1 TLSv1.2 PFS',
|
|
20
|
+
'TLSv1.1 TLSv1.2',
|
|
21
|
+
'TLSv1.1 TLSv1.2 PFS',
|
|
22
|
+
'TLSv1.2',
|
|
23
|
+
'TLSv1.2 PFS',
|
|
24
|
+
'TLSv1.2 PFS TLSv1.3',
|
|
25
|
+
'TLSv1.3'
|
|
26
|
+
].freeze
|
|
27
|
+
|
|
28
|
+
ALB_PROTOCOL_VALUES = SSL_PROTOCOL_VALUES
|
|
29
|
+
|
|
30
|
+
ELB_PROTOCOL_VALUES =
|
|
31
|
+
SSL_PROTOCOL_VALUES.reject { |v| v.include?(' PFS') }.freeze
|
|
32
|
+
|
|
33
|
+
SSL_PROTOCOL_ALB_DESC = (
|
|
34
|
+
'Specify the allowed SSL protocols. Valid options: ' +
|
|
35
|
+
ALB_PROTOCOL_VALUES.map { |v| "\"#{v}\"" }.join(', ') +
|
|
36
|
+
'. PFS options require an HTTPS (ALB) endpoint. ' \
|
|
37
|
+
'Use "default" to reset to the platform default'
|
|
38
|
+
).freeze
|
|
39
|
+
|
|
40
|
+
SSL_PROTOCOL_ELB_DESC = (
|
|
41
|
+
'Specify the allowed SSL protocols. Valid options: ' +
|
|
42
|
+
ELB_PROTOCOL_VALUES.map { |v| "\"#{v}\"" }.join(', ') +
|
|
43
|
+
'. Use "default" to reset to the platform default'
|
|
44
|
+
).freeze
|
|
45
|
+
|
|
17
46
|
def initialize(&block)
|
|
18
47
|
FLAGS.each { |f| instance_variable_set("@#{f}", false) }
|
|
19
48
|
instance_exec(&block) if block
|
|
@@ -53,6 +82,14 @@ module Aptible
|
|
|
53
82
|
)
|
|
54
83
|
end
|
|
55
84
|
|
|
85
|
+
option(
|
|
86
|
+
:idle_timeout,
|
|
87
|
+
type: :string,
|
|
88
|
+
desc: 'Timeout (seconds) to enforce idle timeouts while ' \
|
|
89
|
+
'sending and receiving responses. Use "default" to ' \
|
|
90
|
+
'reset to the platform default'
|
|
91
|
+
)
|
|
92
|
+
|
|
56
93
|
if builder.alb?
|
|
57
94
|
option(
|
|
58
95
|
:load_balancing_algorithm_type,
|
|
@@ -69,6 +106,50 @@ module Aptible
|
|
|
69
106
|
desc: "Share this Endpoint's load balancer with other " \
|
|
70
107
|
'Endpoints'
|
|
71
108
|
)
|
|
109
|
+
|
|
110
|
+
option(
|
|
111
|
+
:force_ssl,
|
|
112
|
+
type: :boolean,
|
|
113
|
+
desc: 'Redirect all HTTP requests to HTTPS, and ' \
|
|
114
|
+
'enable the Strict-Transport-Security header (HSTS)'
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
option(
|
|
118
|
+
:maintenance_page_url,
|
|
119
|
+
type: :string,
|
|
120
|
+
desc: 'The URL of a maintenance page to cache and serve ' \
|
|
121
|
+
'when requests time out, or your app is unhealthy. ' \
|
|
122
|
+
'Use "default" to reset to the platform default'
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
option(
|
|
126
|
+
:release_healthcheck_timeout,
|
|
127
|
+
type: :string,
|
|
128
|
+
desc: 'Timeout (seconds) to wait for your app to ' \
|
|
129
|
+
'respond to a release health check. Use "default" ' \
|
|
130
|
+
'to reset to the platform default'
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
option(
|
|
134
|
+
:show_elb_healthchecks,
|
|
135
|
+
type: :boolean,
|
|
136
|
+
desc: 'Show all runtime health check requets in the ' \
|
|
137
|
+
"endpoint's logs"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
option(
|
|
141
|
+
:ssl_protocols_override,
|
|
142
|
+
type: :string,
|
|
143
|
+
desc: SSL_PROTOCOL_ALB_DESC
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
option(
|
|
147
|
+
:strict_health_checks,
|
|
148
|
+
type: :boolean,
|
|
149
|
+
desc: 'Require containers to respond to health checks ' \
|
|
150
|
+
'with a 200 OK HTTP response.'
|
|
151
|
+
)
|
|
152
|
+
|
|
72
153
|
end
|
|
73
154
|
end
|
|
74
155
|
|
|
@@ -128,6 +209,27 @@ module Aptible
|
|
|
128
209
|
desc: 'The fingerprint of an existing Certificate to use ' \
|
|
129
210
|
'on this Endpoint'
|
|
130
211
|
)
|
|
212
|
+
|
|
213
|
+
unless builder.alb?
|
|
214
|
+
option(
|
|
215
|
+
:ssl_protocols_override,
|
|
216
|
+
type: :string,
|
|
217
|
+
desc: SSL_PROTOCOL_ELB_DESC
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
option(
|
|
221
|
+
:ssl_ciphers_override,
|
|
222
|
+
type: :string,
|
|
223
|
+
desc: 'Specify the allowed SSL ciphers. ' \
|
|
224
|
+
'Use "default" to reset to the platform default'
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
option(
|
|
228
|
+
:disable_weak_cipher_suites,
|
|
229
|
+
type: :boolean,
|
|
230
|
+
desc: 'Block the SSLv3 protocol and RC4 ciphers'
|
|
231
|
+
)
|
|
232
|
+
end
|
|
131
233
|
end
|
|
132
234
|
end
|
|
133
235
|
end
|
|
@@ -137,6 +239,7 @@ module Aptible
|
|
|
137
239
|
verify_option_conflicts(options)
|
|
138
240
|
|
|
139
241
|
params = {}
|
|
242
|
+
settings = {}
|
|
140
243
|
|
|
141
244
|
params[:ip_whitelist] = options.delete(:ip_whitelist) do
|
|
142
245
|
create? ? [] : nil
|
|
@@ -203,6 +306,56 @@ module Aptible
|
|
|
203
306
|
params[:shared] = options.delete(:shared)
|
|
204
307
|
end
|
|
205
308
|
|
|
309
|
+
if (proto = options[:ssl_protocols_override]) &&
|
|
310
|
+
proto != 'default'
|
|
311
|
+
unless ALB_PROTOCOL_VALUES.include?(proto)
|
|
312
|
+
raise Thor::Error,
|
|
313
|
+
"Invalid --ssl-protocols-override: \"#{proto}\". " \
|
|
314
|
+
"Valid options are: #{ALB_PROTOCOL_VALUES.join(', ')}"
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
if !ELB_PROTOCOL_VALUES.include?(proto) && !alb?
|
|
318
|
+
raise Thor::Error,
|
|
319
|
+
"Invalid --ssl-protocols-override: \"#{proto}\". " \
|
|
320
|
+
'PFS options are only valid for an HTTPS (ALB) endpoint. ' \
|
|
321
|
+
"Valid options are: #{ELB_PROTOCOL_VALUES.join(', ')}"
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
vhost_settings = %i(
|
|
326
|
+
idle_timeout
|
|
327
|
+
maintenance_page_url
|
|
328
|
+
release_healthcheck_timeout
|
|
329
|
+
ssl_protocols_override
|
|
330
|
+
ssl_ciphers_override
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
vhost_settings.each do |key|
|
|
334
|
+
val = options.delete(key)
|
|
335
|
+
next if val.nil?
|
|
336
|
+
|
|
337
|
+
settings[key.to_s.upcase] = case val
|
|
338
|
+
when 'default'
|
|
339
|
+
''
|
|
340
|
+
else
|
|
341
|
+
val
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
boolean_vhost_settings = %i(
|
|
346
|
+
force_ssl
|
|
347
|
+
show_elb_healthchecks
|
|
348
|
+
strict_health_checks
|
|
349
|
+
disable_weak_cipher_suites
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
boolean_vhost_settings.each do |key|
|
|
353
|
+
value = options.delete(key)
|
|
354
|
+
next if value.nil?
|
|
355
|
+
|
|
356
|
+
settings[key.to_s.upcase] = value.to_s
|
|
357
|
+
end
|
|
358
|
+
|
|
206
359
|
options.delete(:environment)
|
|
207
360
|
|
|
208
361
|
# NOTE: This is here to ensure that specs don't test for options
|
|
@@ -210,7 +363,7 @@ module Aptible
|
|
|
210
363
|
# this.
|
|
211
364
|
raise "Unexpected options: #{options}" if options.any?
|
|
212
365
|
|
|
213
|
-
params.delete_if { |_, v| v.nil? }
|
|
366
|
+
[params.delete_if { |_, v| v.nil? }, settings]
|
|
214
367
|
end
|
|
215
368
|
|
|
216
369
|
FLAGS.each do |f|
|
|
@@ -2,8 +2,11 @@ module Aptible
|
|
|
2
2
|
module CLI
|
|
3
3
|
module Helpers
|
|
4
4
|
module Vhost
|
|
5
|
-
def provision_vhost_and_explain(service, vhost)
|
|
6
|
-
op = vhost.create_operation!(
|
|
5
|
+
def provision_vhost_and_explain(service, vhost, settings)
|
|
6
|
+
op = vhost.create_operation!(
|
|
7
|
+
type: 'provision',
|
|
8
|
+
**(settings.empty? ? {} : { settings: settings })
|
|
9
|
+
)
|
|
7
10
|
attach_to_operation_logs(op)
|
|
8
11
|
|
|
9
12
|
Formatter.render(Renderer.current) do |root|
|
|
@@ -213,6 +213,12 @@ module Aptible
|
|
|
213
213
|
|
|
214
214
|
node.value('internal', vhost.internal)
|
|
215
215
|
|
|
216
|
+
unless vhost.current_setting.nil?
|
|
217
|
+
vhost.current_setting.settings.each do |k, v|
|
|
218
|
+
node.value(k.downcase, v)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
216
222
|
ip_whitelist = if vhost.ip_whitelist.any?
|
|
217
223
|
vhost.ip_whitelist.join(' ')
|
|
218
224
|
else
|
|
@@ -27,13 +27,18 @@ module Aptible
|
|
|
27
27
|
service = database.service
|
|
28
28
|
raise Thor::Error, 'Database is not provisioned' if service.nil?
|
|
29
29
|
|
|
30
|
+
prepared_params, settings = database_create_flags.prepare(
|
|
31
|
+
database.account,
|
|
32
|
+
options
|
|
33
|
+
)
|
|
34
|
+
|
|
30
35
|
vhost = service.create_vhost!(
|
|
31
36
|
type: 'tcp',
|
|
32
37
|
platform: 'elb',
|
|
33
|
-
**
|
|
38
|
+
**prepared_params
|
|
34
39
|
)
|
|
35
40
|
|
|
36
|
-
provision_vhost_and_explain(service, vhost)
|
|
41
|
+
provision_vhost_and_explain(service, vhost, settings)
|
|
37
42
|
end
|
|
38
43
|
|
|
39
44
|
database_modify_flags = Helpers::Vhost::OptionSetBuilder.new do
|
|
@@ -49,9 +54,14 @@ module Aptible
|
|
|
49
54
|
|
|
50
55
|
database = ensure_database(options.merge(db: options[:database]))
|
|
51
56
|
vhost = find_vhost(each_service(database), hostname)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
|
|
58
|
+
prepared_params, settings = database_modify_flags.prepare(
|
|
59
|
+
database.account,
|
|
60
|
+
options
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
vhost.update!(**prepared_params)
|
|
64
|
+
provision_vhost_and_explain(vhost.service, vhost, settings)
|
|
55
65
|
end
|
|
56
66
|
|
|
57
67
|
tcp_create_flags = Helpers::Vhost::OptionSetBuilder.new do
|
|
@@ -246,18 +256,26 @@ module Aptible
|
|
|
246
256
|
no_commands do
|
|
247
257
|
def create_app_vhost(flags, options, process_type, **attrs)
|
|
248
258
|
service = ensure_service(options, process_type)
|
|
259
|
+
|
|
260
|
+
prepared_params, settings =
|
|
261
|
+
flags.prepare(service.account, options)
|
|
262
|
+
|
|
249
263
|
vhost = service.create_vhost!(
|
|
250
|
-
**
|
|
264
|
+
**prepared_params,
|
|
251
265
|
**attrs
|
|
252
266
|
)
|
|
253
|
-
provision_vhost_and_explain(service, vhost)
|
|
267
|
+
provision_vhost_and_explain(service, vhost, settings)
|
|
254
268
|
end
|
|
255
269
|
|
|
256
270
|
def modify_app_vhost(flags, options, hostname)
|
|
257
271
|
app = ensure_app(options)
|
|
258
272
|
vhost = find_vhost(each_service(app), hostname)
|
|
259
|
-
|
|
260
|
-
|
|
273
|
+
|
|
274
|
+
prepared_params, settings =
|
|
275
|
+
flags.prepare(vhost.service.account, options)
|
|
276
|
+
|
|
277
|
+
vhost.update!(**prepared_params)
|
|
278
|
+
provision_vhost_and_explain(vhost.service, vhost, settings)
|
|
261
279
|
end
|
|
262
280
|
end
|
|
263
281
|
end
|
data/lib/aptible/cli/version.rb
CHANGED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Aptible::CLI::Helpers::Vhost::OptionSetBuilder do
|
|
4
|
+
def register_options(builder)
|
|
5
|
+
klass = Class.new(Thor) { include Aptible::CLI::Helpers::App }
|
|
6
|
+
builder.declare_options(klass)
|
|
7
|
+
klass.instance_variable_get(:@method_options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '--ssl-protocols-override option description' do
|
|
11
|
+
context 'HTTPS endpoints (ALB, alb! flag set)' do
|
|
12
|
+
let(:builder) do
|
|
13
|
+
described_class.new do
|
|
14
|
+
app!
|
|
15
|
+
tls!
|
|
16
|
+
alb!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'includes PFS values' do
|
|
21
|
+
desc = register_options(builder)[:ssl_protocols_override].description
|
|
22
|
+
expect(desc).to include('PFS')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context 'TLS endpoints (ELB, tls! without alb!)' do
|
|
27
|
+
let(:builder) do
|
|
28
|
+
described_class.new do
|
|
29
|
+
app!
|
|
30
|
+
tls!
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'does not include PFS values' do
|
|
35
|
+
desc = register_options(builder)[:ssl_protocols_override].description
|
|
36
|
+
expect(desc).not_to include('PFS')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'is still present' do
|
|
40
|
+
expect(register_options(builder)).to have_key(:ssl_protocols_override)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'gRPC endpoints (ELB, tls! without alb!)' do
|
|
45
|
+
let(:builder) do
|
|
46
|
+
described_class.new do
|
|
47
|
+
app!
|
|
48
|
+
port!
|
|
49
|
+
tls!
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'does not include PFS values' do
|
|
54
|
+
desc = register_options(builder)[:ssl_protocols_override].description
|
|
55
|
+
expect(desc).not_to include('PFS')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context 'TCP endpoints (no tls! flag)' do
|
|
60
|
+
let(:builder) do
|
|
61
|
+
described_class.new do
|
|
62
|
+
app!
|
|
63
|
+
ports!
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'is absent' do
|
|
68
|
+
expect(register_options(builder)).not_to have_key(:ssl_protocols_override)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe 'SSL_PROTOCOL_ALB_DESC' do
|
|
74
|
+
subject { described_class::SSL_PROTOCOL_ALB_DESC }
|
|
75
|
+
|
|
76
|
+
it 'lists all PFS protocol values' do
|
|
77
|
+
pfs_values = described_class::SSL_PROTOCOL_VALUES.select { |v| v.include?('PFS') }
|
|
78
|
+
pfs_values.each { |v| is_expected.to include(v) }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe 'SSL_PROTOCOL_ELB_DESC' do
|
|
83
|
+
subject { described_class::SSL_PROTOCOL_ELB_DESC }
|
|
84
|
+
|
|
85
|
+
it 'contains no PFS values' do
|
|
86
|
+
is_expected.not_to include('PFS')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'lists all non-PFS protocol values' do
|
|
90
|
+
non_pfs_values = described_class::SSL_PROTOCOL_VALUES.reject { |v| v.include?('PFS') }
|
|
91
|
+
non_pfs_values.each { |v| is_expected.to include(v) }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -25,12 +25,12 @@ describe Aptible::CLI::Agent do
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def expect_create_vhost(service, options)
|
|
28
|
+
def expect_create_vhost(service, options, settings: nil)
|
|
29
29
|
expect(service).to receive(:create_vhost!).with(
|
|
30
30
|
hash_including(options)
|
|
31
31
|
) do |args|
|
|
32
32
|
Fabricate(:vhost, service: service, **args).tap do |v|
|
|
33
|
-
expect_operation(v, 'provision')
|
|
33
|
+
expect_operation(v, 'provision', settings: settings)
|
|
34
34
|
expect(v).to receive(:reload).and_return(v)
|
|
35
35
|
expect(Aptible::CLI::ResourceFormatter).to receive(:inject_vhost)
|
|
36
36
|
.with(an_instance_of(Aptible::CLI::Formatter::Object), v, service)
|
|
@@ -49,8 +49,16 @@ describe Aptible::CLI::Agent do
|
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
def expect_operation(vhost, type)
|
|
53
|
-
expect(vhost).to receive(:create_operation!)
|
|
52
|
+
def expect_operation(vhost, type, settings: nil)
|
|
53
|
+
expect(vhost).to receive(:create_operation!) do |args|
|
|
54
|
+
expect(args[:type]).to eq(type)
|
|
55
|
+
|
|
56
|
+
if settings.nil?
|
|
57
|
+
expect(args).not_to have_key(:settings)
|
|
58
|
+
else
|
|
59
|
+
expect(args[:settings]).to eq(settings)
|
|
60
|
+
end
|
|
61
|
+
|
|
54
62
|
Fabricate(:operation).tap do |o|
|
|
55
63
|
expect(subject).to receive(:attach_to_operation_logs).with(o)
|
|
56
64
|
end
|
|
@@ -170,7 +178,13 @@ describe Aptible::CLI::Agent do
|
|
|
170
178
|
it 'lists Endpoints' do
|
|
171
179
|
s = Fabricate(:service, database: db)
|
|
172
180
|
v1 = Fabricate(:vhost, service: s)
|
|
181
|
+
v1.current_setting = Fabricate(:setting,
|
|
182
|
+
settings: { 'IDLE_TIMEOUT' => '123' },
|
|
183
|
+
vhost: v1)
|
|
173
184
|
v2 = Fabricate(:vhost, service: s)
|
|
185
|
+
v2.current_setting = Fabricate(:setting,
|
|
186
|
+
settings: { 'FORCE_SSL' => 'true' },
|
|
187
|
+
vhost: v2)
|
|
174
188
|
|
|
175
189
|
stub_options(database: db.handle)
|
|
176
190
|
subject.send('endpoints:list')
|
|
@@ -179,6 +193,8 @@ describe Aptible::CLI::Agent do
|
|
|
179
193
|
|
|
180
194
|
expect(lines).to include("Hostname: #{v1.external_host}")
|
|
181
195
|
expect(lines).to include("Hostname: #{v2.external_host}")
|
|
196
|
+
expect(lines).to include('Idle Timeout: 123')
|
|
197
|
+
expect(lines).to include('Force SSL: true')
|
|
182
198
|
|
|
183
199
|
expect(lines[0]).not_to eq("\n")
|
|
184
200
|
expect(lines[-1]).not_to eq("\n")
|
|
@@ -243,6 +259,105 @@ describe Aptible::CLI::Agent do
|
|
|
243
259
|
stub_options
|
|
244
260
|
end
|
|
245
261
|
|
|
262
|
+
shared_examples 'shared create and modify ALB settings examples' do |method|
|
|
263
|
+
context 'App Vhost Settings (string)' do
|
|
264
|
+
string_options = %i(
|
|
265
|
+
idle_timeout
|
|
266
|
+
maintenance_page_url
|
|
267
|
+
release_healthcheck_timeout
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
let(:value) { 'some value' }
|
|
271
|
+
|
|
272
|
+
string_options.each do |option|
|
|
273
|
+
context "--#{option.to_s.tr('_', '-')}" do
|
|
274
|
+
it 'passes a value if provided' do
|
|
275
|
+
wanted = { option.to_s.upcase => value }
|
|
276
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
277
|
+
stub_options(option => value)
|
|
278
|
+
subject.send(method, 'web')
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it 'passes nothing if not provided' do
|
|
282
|
+
expect_create_vhost(service, {})
|
|
283
|
+
subject.send(method, 'web')
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
context 'reverting to default' do
|
|
287
|
+
it 'sends an empty string if passed an empty string' do
|
|
288
|
+
wanted = { option.to_s.upcase => '' }
|
|
289
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
290
|
+
stub_options(option => '')
|
|
291
|
+
subject.send(method, 'web')
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it 'sends an empty string if passed the string "default"' do
|
|
295
|
+
wanted = { option.to_s.upcase => '' }
|
|
296
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
297
|
+
stub_options(option => 'default')
|
|
298
|
+
subject.send(method, 'web')
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
context '--ssl-protocols-override' do
|
|
306
|
+
it 'passes a valid non-PFS value' do
|
|
307
|
+
wanted = { 'SSL_PROTOCOLS_OVERRIDE' => 'TLSv1.2' }
|
|
308
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
309
|
+
stub_options(ssl_protocols_override: 'TLSv1.2')
|
|
310
|
+
subject.send(method, 'web')
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it 'passes a valid PFS value' do
|
|
314
|
+
wanted = { 'SSL_PROTOCOLS_OVERRIDE' => 'TLSv1.2 PFS' }
|
|
315
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
316
|
+
stub_options(ssl_protocols_override: 'TLSv1.2 PFS')
|
|
317
|
+
subject.send(method, 'web')
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
it 'raises an error for an invalid value' do
|
|
321
|
+
stub_options(ssl_protocols_override: 'TLSv1.0')
|
|
322
|
+
expect { subject.send(method, 'web') }
|
|
323
|
+
.to raise_error(/invalid --ssl-protocols-override/im)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it 'passes nothing if not provided' do
|
|
327
|
+
expect_create_vhost(service, {})
|
|
328
|
+
subject.send(method, 'web')
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it 'sends an empty string if passed the string "default"' do
|
|
332
|
+
wanted = { 'SSL_PROTOCOLS_OVERRIDE' => '' }
|
|
333
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
334
|
+
stub_options(ssl_protocols_override: 'default')
|
|
335
|
+
subject.send(method, 'web')
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
context 'App Vhost Settings (boolean)' do
|
|
340
|
+
boolean_options = %i(
|
|
341
|
+
force_ssl
|
|
342
|
+
show_elb_healthchecks
|
|
343
|
+
strict_health_checks
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
boolean_options.each do |option|
|
|
347
|
+
[true, false].each do |value|
|
|
348
|
+
context "--#{value ? '' : 'no-'}#{option.to_s.tr('_', '-')}" do
|
|
349
|
+
it "sets the value to the string '#{value}'" do
|
|
350
|
+
wanted = { option.to_s.upcase => value.to_s }
|
|
351
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
352
|
+
stub_options(option => value)
|
|
353
|
+
subject.send(method, 'web')
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
246
361
|
shared_examples 'shared create app vhost examples' do |method|
|
|
247
362
|
context 'App Vhost Options' do
|
|
248
363
|
it 'fails if the app does not exist' do
|
|
@@ -440,10 +555,64 @@ describe Aptible::CLI::Agent do
|
|
|
440
555
|
end
|
|
441
556
|
end
|
|
442
557
|
|
|
558
|
+
shared_examples 'shared create idle timeout examples' do |method|
|
|
559
|
+
context 'IDLE_TIMEOUT' do
|
|
560
|
+
it 'passes idle_timeout if provided' do
|
|
561
|
+
expect_create_vhost(service, {}, { settings: { 'IDLE_TIMEOUT' => '30' } })
|
|
562
|
+
stub_options(idle_timeout: '30')
|
|
563
|
+
subject.send(method, 'web')
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
shared_examples 'shared create non-alb tls settings examples' do |method|
|
|
569
|
+
context '--ssl-protocols-override' do
|
|
570
|
+
it 'passes a valid non-PFS value' do
|
|
571
|
+
wanted = { 'SSL_PROTOCOLS_OVERRIDE' => 'TLSv1.2' }
|
|
572
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
573
|
+
stub_options(ssl_protocols_override: 'TLSv1.2')
|
|
574
|
+
subject.send(method, 'web')
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
it 'raises an error for a PFS value' do
|
|
578
|
+
stub_options(ssl_protocols_override: 'TLSv1.2 PFS')
|
|
579
|
+
expect { subject.send(method, 'web') }
|
|
580
|
+
.to raise_error(/pfs.*only.*alb/im)
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
it 'raises an error for an invalid value' do
|
|
584
|
+
stub_options(ssl_protocols_override: 'TLSv1.0')
|
|
585
|
+
expect { subject.send(method, 'web') }
|
|
586
|
+
.to raise_error(/invalid --ssl-protocols-override/im)
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
context 'SSL_CIPHERS_OVERRIDE' do
|
|
591
|
+
it 'passes ssl_ciphers_override if provided' do
|
|
592
|
+
wanted = { 'SSL_CIPHERS_OVERRIDE' => 'HIGH:!aNULL' }
|
|
593
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
594
|
+
stub_options(ssl_ciphers_override: 'HIGH:!aNULL')
|
|
595
|
+
subject.send(method, 'web')
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
context 'DISABLE_WEAK_CIPHER_SUITES' do
|
|
600
|
+
[true, false].each do |value|
|
|
601
|
+
it "sets disable_weak_cipher_suites to '#{value}'" do
|
|
602
|
+
wanted = { 'DISABLE_WEAK_CIPHER_SUITES' => value.to_s }
|
|
603
|
+
expect_create_vhost(service, {}, { settings: wanted })
|
|
604
|
+
stub_options(disable_weak_cipher_suites: value)
|
|
605
|
+
subject.send(method, 'web')
|
|
606
|
+
end
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
|
|
443
611
|
describe 'endpoints:tcp:create' do
|
|
444
612
|
m = 'endpoints:tcp:create'
|
|
445
613
|
include_examples 'shared create app vhost examples', m
|
|
446
614
|
include_examples 'shared create tcp vhost examples', m
|
|
615
|
+
include_examples 'shared create idle timeout examples', m
|
|
447
616
|
|
|
448
617
|
it 'creates a TCP Endpoint' do
|
|
449
618
|
expect_create_vhost(
|
|
@@ -465,6 +634,8 @@ describe Aptible::CLI::Agent do
|
|
|
465
634
|
include_examples 'shared create app vhost examples', m
|
|
466
635
|
include_examples 'shared create tcp vhost examples', m
|
|
467
636
|
include_examples 'shared create tls vhost examples', m
|
|
637
|
+
include_examples 'shared create idle timeout examples', m
|
|
638
|
+
include_examples 'shared create non-alb tls settings examples', m
|
|
468
639
|
|
|
469
640
|
it 'creates a TLS Endpoint' do
|
|
470
641
|
expect_create_vhost(
|
|
@@ -484,6 +655,7 @@ describe Aptible::CLI::Agent do
|
|
|
484
655
|
m = 'endpoints:https:create'
|
|
485
656
|
include_examples 'shared create app vhost examples', m
|
|
486
657
|
include_examples 'shared create tls vhost examples', m
|
|
658
|
+
include_examples 'shared create and modify ALB settings examples', m
|
|
487
659
|
|
|
488
660
|
it 'creates a HTTP Endpoint' do
|
|
489
661
|
expect_create_vhost(
|
|
@@ -516,6 +688,8 @@ describe Aptible::CLI::Agent do
|
|
|
516
688
|
m = 'endpoints:grpc:create'
|
|
517
689
|
include_examples 'shared create app vhost examples', m
|
|
518
690
|
include_examples 'shared create tls vhost examples', m
|
|
691
|
+
include_examples 'shared create idle timeout examples', m
|
|
692
|
+
include_examples 'shared create non-alb tls settings examples', m
|
|
519
693
|
|
|
520
694
|
it 'creates a gRPC Endpoint' do
|
|
521
695
|
expect_create_vhost(
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aptible-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.26.
|
|
4
|
+
version: 0.26.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Frank Macreery
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -563,6 +563,7 @@ files:
|
|
|
563
563
|
- spec/aptible/cli/helpers/ssh_spec.rb
|
|
564
564
|
- spec/aptible/cli/helpers/token_spec.rb
|
|
565
565
|
- spec/aptible/cli/helpers/tunnel_spec.rb
|
|
566
|
+
- spec/aptible/cli/helpers/vhost/option_set_builder_spec.rb
|
|
566
567
|
- spec/aptible/cli/renderer/json_spec.rb
|
|
567
568
|
- spec/aptible/cli/renderer/text_spec.rb
|
|
568
569
|
- spec/aptible/cli/resource_formatter_spec.rb
|
|
@@ -608,6 +609,7 @@ files:
|
|
|
608
609
|
- spec/fabricators/operation_fabricator.rb
|
|
609
610
|
- spec/fabricators/service_fabricator.rb
|
|
610
611
|
- spec/fabricators/service_sizing_policy_fabricator.rb
|
|
612
|
+
- spec/fabricators/setting_fabricator.rb
|
|
611
613
|
- spec/fabricators/stack_fabricator.rb
|
|
612
614
|
- spec/fabricators/vhost_fabricator.rb
|
|
613
615
|
- spec/mock/git
|
|
@@ -657,6 +659,7 @@ test_files:
|
|
|
657
659
|
- spec/aptible/cli/helpers/ssh_spec.rb
|
|
658
660
|
- spec/aptible/cli/helpers/token_spec.rb
|
|
659
661
|
- spec/aptible/cli/helpers/tunnel_spec.rb
|
|
662
|
+
- spec/aptible/cli/helpers/vhost/option_set_builder_spec.rb
|
|
660
663
|
- spec/aptible/cli/renderer/json_spec.rb
|
|
661
664
|
- spec/aptible/cli/renderer/text_spec.rb
|
|
662
665
|
- spec/aptible/cli/resource_formatter_spec.rb
|
|
@@ -702,6 +705,7 @@ test_files:
|
|
|
702
705
|
- spec/fabricators/operation_fabricator.rb
|
|
703
706
|
- spec/fabricators/service_fabricator.rb
|
|
704
707
|
- spec/fabricators/service_sizing_policy_fabricator.rb
|
|
708
|
+
- spec/fabricators/setting_fabricator.rb
|
|
705
709
|
- spec/fabricators/stack_fabricator.rb
|
|
706
710
|
- spec/fabricators/vhost_fabricator.rb
|
|
707
711
|
- spec/mock/git
|