kontena-cli 1.1.0.rc1 → 1.1.0.rc2
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/VERSION +1 -1
- data/lib/kontena/cli/apps/deploy_command.rb +1 -5
- data/lib/kontena/cli/cloud/login_command.rb +9 -1
- data/lib/kontena/cli/common.rb +2 -2
- data/lib/kontena/cli/etcd/health_command.rb +58 -0
- data/lib/kontena/cli/etcd_command.rb +2 -0
- data/lib/kontena/cli/external_registry_command.rb +0 -2
- data/lib/kontena/cli/master/login_command.rb +5 -7
- data/lib/kontena/cli/service_command.rb +2 -2
- data/lib/kontena/cli/services/deploy_command.rb +1 -5
- data/lib/kontena/cli/services/exec_command.rb +84 -0
- data/lib/kontena/cli/services/services_helper.rb +4 -1
- data/lib/kontena/cli/stacks/common.rb +6 -17
- data/lib/kontena/cli/stacks/install_command.rb +2 -10
- data/lib/kontena/cli/stacks/show_command.rb +30 -4
- data/lib/kontena/cli/stacks/upgrade_command.rb +20 -7
- data/lib/kontena/cli/stacks/validate_command.rb +1 -9
- data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +45 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +15 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/reader.rb +36 -26
- data/lib/kontena/command.rb +5 -0
- data/lib/kontena/main_command.rb +5 -4
- data/lib/kontena_cli.rb +4 -0
- data/spec/fixtures/stack-with-prompted-variables.yml +5 -1
- data/spec/fixtures/stack-with-variables.yml +5 -1
- data/spec/kontena/cli/cloud/login_command_spec.rb +1 -0
- data/spec/kontena/cli/etcd/health_command_spec.rb +87 -0
- data/spec/kontena/cli/master/login_command_spec.rb +8 -17
- data/spec/kontena/cli/services/exec_command_spec.rb +137 -0
- data/spec/kontena/cli/stacks/install_command_spec.rb +5 -5
- data/spec/kontena/cli/stacks/upgrade_command_spec.rb +39 -32
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +22 -0
- data/spec/support/client_helpers.rb +6 -2
- data/spec/support/output_helpers.rb +23 -0
- metadata +11 -7
- data/lib/kontena/cli/external_registries/delete_command.rb +0 -15
- data/lib/kontena/cli/login_command.rb +0 -12
- data/lib/kontena/cli/register_command.rb +0 -9
- data/lib/kontena/cli/services/delete_command.rb +0 -19
|
@@ -13,22 +13,35 @@ module Kontena::Cli::Stacks
|
|
|
13
13
|
include Common::StackFileOrNameParam
|
|
14
14
|
include Common::StackValuesFromOption
|
|
15
15
|
|
|
16
|
-
option '--deploy', :flag, '
|
|
16
|
+
option '--[no-]deploy', :flag, 'Trigger deploy after upgrade', default: true
|
|
17
17
|
|
|
18
18
|
requires_current_master
|
|
19
19
|
requires_current_master_token
|
|
20
20
|
|
|
21
21
|
def execute
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
spinner "Upgrading stack #{pastel.cyan(name)} " do
|
|
25
|
-
update_stack(stack)
|
|
22
|
+
master_data = spinner "Reading stack #{pastel.cyan(name)} metadata from Kontena Master" do |spin|
|
|
23
|
+
read_stack || spin.fail!
|
|
26
24
|
end
|
|
27
|
-
|
|
25
|
+
|
|
26
|
+
stack = stack_from_yaml(filename, name: name, values: values, defaults: master_data['variables'])
|
|
27
|
+
|
|
28
|
+
spinner "Upgrading stack #{pastel.cyan(name)}" do |spin|
|
|
29
|
+
update_stack(stack) || spin.fail!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Kontena.run(['stack', 'deploy', name]) if deploy?
|
|
28
33
|
end
|
|
29
34
|
|
|
30
35
|
def update_stack(stack)
|
|
31
|
-
client.put(
|
|
36
|
+
client.put(stack_url, stack)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def stack_url
|
|
40
|
+
@stack_url ||= "stacks/#{current_grid}/#{name}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def read_stack
|
|
44
|
+
client.get(stack_url)
|
|
32
45
|
end
|
|
33
46
|
end
|
|
34
47
|
end
|
|
@@ -19,15 +19,7 @@ module Kontena::Cli::Stacks
|
|
|
19
19
|
requires_current_master_token
|
|
20
20
|
|
|
21
21
|
def execute
|
|
22
|
-
|
|
23
|
-
if !File.exist?(filename) && filename =~ /\A[a-zA-Z0-9\_\.\-]+\/[a-zA-Z0-9\_\.\-]+(?::.*)?\z/
|
|
24
|
-
from_registry = true
|
|
25
|
-
else
|
|
26
|
-
from_registry = false
|
|
27
|
-
require_config_file(filename)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
reader = reader_from_yaml(filename, from_registry: from_registry, name: name, values: values)
|
|
22
|
+
reader = reader_from_yaml(filename, name: name, values: values)
|
|
31
23
|
outcome = reader.execute
|
|
32
24
|
hint_on_validation_notifications(outcome[:notifications]) if outcome[:notifications].size > 0
|
|
33
25
|
abort_on_validation_errors(outcome[:errors]) if outcome[:errors].size > 0
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Kontena::Cli::Stacks
|
|
2
|
+
module YAML
|
|
3
|
+
class Opto::Resolvers::ServiceLink < Opto::Resolver
|
|
4
|
+
include Kontena::Cli::Common
|
|
5
|
+
|
|
6
|
+
def resolve
|
|
7
|
+
message = hint['prompt']
|
|
8
|
+
name_filter = hint['name']
|
|
9
|
+
image_filter = hint['image']
|
|
10
|
+
raise "prompt missing" unless message
|
|
11
|
+
|
|
12
|
+
services = client.get("grids/#{current_grid}/services")['services']
|
|
13
|
+
services = filter_by_image(services, image_filter) if image_filter
|
|
14
|
+
services = filter_by_name(services, name_filter) if name_filter
|
|
15
|
+
prompt.select(message) do |menu|
|
|
16
|
+
menu.choice "<none>", nil unless option.required?
|
|
17
|
+
services.each do |s|
|
|
18
|
+
if s.dig('stack', 'name') == 'null'
|
|
19
|
+
name = s['name']
|
|
20
|
+
else
|
|
21
|
+
name = "#{s.dig('stack', 'name')}/#{s['name']}"
|
|
22
|
+
end
|
|
23
|
+
menu.choice name, "#{s.dig('stack', 'name')}/#{s['name']}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def filter_by_image(services, image)
|
|
29
|
+
services.select { |s|
|
|
30
|
+
s['image'].include?(image)
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def filter_by_name(services, name)
|
|
35
|
+
services.select { |s|
|
|
36
|
+
s['name'].include?(name)
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def stack
|
|
41
|
+
ENV['STACK']
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Kontena::Cli::Stacks
|
|
2
|
+
module YAML
|
|
3
|
+
class Opto::Resolvers::VaultCertPrompt < Opto::Resolver
|
|
4
|
+
include Kontena::Cli::Common
|
|
5
|
+
|
|
6
|
+
def resolve
|
|
7
|
+
message = hint || 'Select SSL certs'
|
|
8
|
+
secrets = client.get("grids/#{current_grid}/secrets")['secrets'].select{ |s|
|
|
9
|
+
s['name'].match(/(ssl|cert)/i)
|
|
10
|
+
}
|
|
11
|
+
prompt.multi_select(hint, secrets.map{ |s| s['name'] })
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -2,6 +2,7 @@ module Kontena::Cli::Stacks
|
|
|
2
2
|
module YAML
|
|
3
3
|
class Opto::Resolvers::Vault < Opto::Resolver
|
|
4
4
|
def resolve
|
|
5
|
+
raise RuntimeError, "Missing or empty vault secret name" if hint.to_s.empty?
|
|
5
6
|
require 'shellwords'
|
|
6
7
|
Kontena.run("vault read --return #{hint.shellescape}", returning: :result)
|
|
7
8
|
end
|
|
@@ -6,9 +6,9 @@ module Kontena::Cli::Stacks
|
|
|
6
6
|
include Kontena::Util
|
|
7
7
|
include Kontena::Cli::Common
|
|
8
8
|
|
|
9
|
-
attr_reader :file, :raw_content, :errors, :notifications
|
|
9
|
+
attr_reader :file, :raw_content, :errors, :notifications, :defaults, :values
|
|
10
10
|
|
|
11
|
-
def initialize(file, skip_validation: false, skip_variables: false,
|
|
11
|
+
def initialize(file, skip_validation: false, skip_variables: false, variables: nil, values: nil, defaults: nil)
|
|
12
12
|
require 'yaml'
|
|
13
13
|
require_relative 'service_extender'
|
|
14
14
|
require_relative 'validator_v3'
|
|
@@ -17,15 +17,20 @@ module Kontena::Cli::Stacks
|
|
|
17
17
|
require_relative 'opto/vault_resolver'
|
|
18
18
|
require_relative 'opto/prompt_resolver'
|
|
19
19
|
require_relative 'opto/service_instances_resolver'
|
|
20
|
+
require_relative 'opto/vault_cert_prompt_resolver'
|
|
21
|
+
require_relative 'opto/service_link_resolver'
|
|
20
22
|
require 'liquid'
|
|
21
23
|
|
|
22
24
|
@file = file
|
|
23
|
-
@from_registry = from_registry
|
|
24
25
|
|
|
25
26
|
if from_registry?
|
|
26
27
|
require 'shellwords'
|
|
27
28
|
@raw_content = Kontena::StacksCache.pull(file)
|
|
28
29
|
@registry = Kontena::StacksCache.registry_url
|
|
30
|
+
elsif from_url?
|
|
31
|
+
require 'open-uri'
|
|
32
|
+
stream = open(file)
|
|
33
|
+
@raw_content = stream.read
|
|
29
34
|
else
|
|
30
35
|
@raw_content = File.read(File.expand_path(file))
|
|
31
36
|
end
|
|
@@ -36,6 +41,7 @@ module Kontena::Cli::Stacks
|
|
|
36
41
|
@skip_variables = skip_variables
|
|
37
42
|
@variables = variables
|
|
38
43
|
@values = values
|
|
44
|
+
@defaults = defaults
|
|
39
45
|
end
|
|
40
46
|
|
|
41
47
|
def internals_interpolated_yaml
|
|
@@ -89,8 +95,15 @@ module Kontena::Cli::Stacks
|
|
|
89
95
|
to: :env
|
|
90
96
|
}
|
|
91
97
|
)
|
|
92
|
-
if
|
|
93
|
-
|
|
98
|
+
if defaults
|
|
99
|
+
defaults.each do |key, val|
|
|
100
|
+
var = variables.option(key)
|
|
101
|
+
var.default = val if var
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if values
|
|
106
|
+
values.each do |key, val|
|
|
94
107
|
var = @variables.option(key)
|
|
95
108
|
var.set(val) if var
|
|
96
109
|
end
|
|
@@ -105,7 +118,7 @@ module Kontena::Cli::Stacks
|
|
|
105
118
|
validate unless skip_validation?
|
|
106
119
|
|
|
107
120
|
result = {}
|
|
108
|
-
Dir.chdir(
|
|
121
|
+
Dir.chdir(from_file? ? File.dirname(File.expand_path(file)) : Dir.pwd) do
|
|
109
122
|
result[:stack] = raw_yaml['stack']
|
|
110
123
|
result[:version] = self.stack_version
|
|
111
124
|
result[:name] = self.stack_name
|
|
@@ -119,7 +132,6 @@ module Kontena::Cli::Stacks
|
|
|
119
132
|
k == 'GRID' || k == 'STACK' || variables.option(k).to.has_key?(:vault) || variables.option(k).from.has_key?(:vault)
|
|
120
133
|
end
|
|
121
134
|
end
|
|
122
|
-
result[:vault_keys] = extract_vault_keys(result[:services])
|
|
123
135
|
end
|
|
124
136
|
result
|
|
125
137
|
end
|
|
@@ -160,7 +172,15 @@ module Kontena::Cli::Stacks
|
|
|
160
172
|
end
|
|
161
173
|
|
|
162
174
|
def from_registry?
|
|
163
|
-
|
|
175
|
+
file =~ /\A[a-zA-Z0-9\_\.\-]+\/[a-zA-Z0-9\_\.\-]+(?::.*)?\z/ && !File.exist?(file)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def from_url?
|
|
179
|
+
file =~ /\A(?:http|https|ftp):\/\//
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def from_file?
|
|
183
|
+
!from_registry? && !from_url?
|
|
164
184
|
end
|
|
165
185
|
|
|
166
186
|
# @return [Kontena::Cli::Stacks::YAML::ValidatorV3]
|
|
@@ -229,8 +249,8 @@ module Kontena::Cli::Stacks
|
|
|
229
249
|
@services ||= fully_interpolated_yaml['services']
|
|
230
250
|
end
|
|
231
251
|
|
|
232
|
-
def from_external_file(filename, service_name
|
|
233
|
-
outcome = Reader.new(filename, skip_validation: skip_validation?, skip_variables: true,
|
|
252
|
+
def from_external_file(filename, service_name)
|
|
253
|
+
outcome = Reader.new(filename, skip_validation: skip_validation?, skip_variables: true, variables: variables, defaults: defaults, values: values).execute(service_name)
|
|
234
254
|
errors.concat outcome[:errors] unless errors.any? { |item| item.has_key?(filename) }
|
|
235
255
|
notifications.concat outcome[:notifications] unless notifications.any? { |item| item.has_key?(filename) }
|
|
236
256
|
outcome[:services]
|
|
@@ -252,8 +272,11 @@ module Kontena::Cli::Stacks
|
|
|
252
272
|
if use_opto
|
|
253
273
|
opt = variables.option(var)
|
|
254
274
|
if opt.nil?
|
|
255
|
-
|
|
256
|
-
|
|
275
|
+
if variables.find { |opt| opt.to[:env][var] }
|
|
276
|
+
val = env[var]
|
|
277
|
+
else
|
|
278
|
+
raise RuntimeError, "Undeclared variable '#{var}' in #{file}:#{line_num} -- #{row}" if raise_on_unknown
|
|
279
|
+
end
|
|
257
280
|
else
|
|
258
281
|
val = opt.value
|
|
259
282
|
end
|
|
@@ -315,7 +338,7 @@ module Kontena::Cli::Stacks
|
|
|
315
338
|
if filename
|
|
316
339
|
parent_config = from_external_file(filename, extended_service)
|
|
317
340
|
elsif stackname
|
|
318
|
-
parent_config = from_external_file(stackname, extended_service
|
|
341
|
+
parent_config = from_external_file(stackname, extended_service)
|
|
319
342
|
else
|
|
320
343
|
raise ("Service '#{extended_service}' not found in #{file}") unless services.has_key?(extended_service)
|
|
321
344
|
parent_config = process_config(services[extended_service])
|
|
@@ -384,19 +407,6 @@ module Kontena::Cli::Stacks
|
|
|
384
407
|
end
|
|
385
408
|
end
|
|
386
409
|
|
|
387
|
-
# Goes through an array of service hashes and extracts vault secret key names
|
|
388
|
-
# @param [Hash] services_array
|
|
389
|
-
# @return [Array] keys
|
|
390
|
-
def extract_vault_keys(services)
|
|
391
|
-
keys = []
|
|
392
|
-
services.each do |_, data|
|
|
393
|
-
Array(services['secrets']).each do |secret|
|
|
394
|
-
keys << secret['secret']
|
|
395
|
-
end
|
|
396
|
-
end
|
|
397
|
-
keys.uniq.compact
|
|
398
|
-
end
|
|
399
|
-
|
|
400
410
|
# Takes a stack name such as user/foo:1.0.0 and breaks it into components
|
|
401
411
|
# @param [String] stack_name
|
|
402
412
|
# @return [Hash] a hash with :user, :stack and :version
|
data/lib/kontena/command.rb
CHANGED
|
@@ -2,6 +2,10 @@ require 'clamp'
|
|
|
2
2
|
|
|
3
3
|
class Kontena::Command < Clamp::Command
|
|
4
4
|
|
|
5
|
+
option ['-D', '--debug'], :flag, "Enable debug", environment_variable: 'DEBUG' do
|
|
6
|
+
ENV['DEBUG'] = 'true'
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
attr_accessor :arguments
|
|
6
10
|
attr_reader :result
|
|
7
11
|
attr_reader :exit_code
|
|
@@ -194,6 +198,7 @@ class Kontena::Command < Clamp::Command
|
|
|
194
198
|
exit(@exit_code) if @exit_code.to_i > 0
|
|
195
199
|
@result
|
|
196
200
|
end
|
|
201
|
+
|
|
197
202
|
end
|
|
198
203
|
|
|
199
204
|
require_relative 'callback'
|
data/lib/kontena/main_command.rb
CHANGED
|
@@ -6,7 +6,6 @@ require_relative 'callback'
|
|
|
6
6
|
require_relative 'cli/bytes_helper'
|
|
7
7
|
require_relative 'cli/grid_options'
|
|
8
8
|
require_relative 'cli/app_command'
|
|
9
|
-
require_relative 'cli/login_command'
|
|
10
9
|
require_relative 'cli/logout_command'
|
|
11
10
|
require_relative 'cli/whoami_command'
|
|
12
11
|
require_relative 'cli/container_command'
|
|
@@ -25,12 +24,16 @@ require_relative 'cli/version_command'
|
|
|
25
24
|
require_relative 'cli/stack_command'
|
|
26
25
|
require_relative 'cli/certificate_command'
|
|
27
26
|
require_relative 'cli/cloud_command'
|
|
28
|
-
require_relative 'cli/register_command'
|
|
29
27
|
|
|
30
28
|
class Kontena::MainCommand < Kontena::Command
|
|
31
29
|
include Kontena::Util
|
|
32
30
|
include Kontena::Cli::Common
|
|
33
31
|
|
|
32
|
+
option ['-v', '--version'], :flag, "Output Kontena CLI version #{Kontena::Cli::VERSION}" do
|
|
33
|
+
puts ['kontena-cli', Kontena::Cli::VERSION, '[ruby' + RUBY_VERSION + '+' + RUBY_PLATFORM + ']'].join(' ')
|
|
34
|
+
exit 0
|
|
35
|
+
end
|
|
36
|
+
|
|
34
37
|
subcommand "cloud", "Kontena Cloud specific commands", Kontena::Cli::CloudCommand
|
|
35
38
|
subcommand "logout", "Logout from Kontena Masters or Kontena Cloud accounts", Kontena::Cli::LogoutCommand
|
|
36
39
|
subcommand "grid", "Grid specific commands", Kontena::Cli::GridCommand
|
|
@@ -49,8 +52,6 @@ class Kontena::MainCommand < Kontena::Command
|
|
|
49
52
|
subcommand "whoami", "Shows current logged in user", Kontena::Cli::WhoamiCommand
|
|
50
53
|
subcommand "plugin", "Plugin related commands", Kontena::Cli::PluginCommand
|
|
51
54
|
subcommand "version", "Show version", Kontena::Cli::VersionCommand
|
|
52
|
-
subcommand "login", "[DEPRECATED] Login to Kontena Master", Kontena::Cli::LoginCommand
|
|
53
|
-
subcommand "register", "[DEPRECATED] Register a Kontena Cloud account", Kontena::Cli::RegisterCommand
|
|
54
55
|
|
|
55
56
|
def execute
|
|
56
57
|
end
|
data/lib/kontena_cli.rb
CHANGED
|
@@ -36,6 +36,10 @@ module Kontena
|
|
|
36
36
|
ENV['OS'] == 'Windows_NT' && RUBY_PLATFORM !~ /cygwin/
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
def self.browserless?
|
|
40
|
+
!!(RUBY_PLATFORM =~ /linux|(?:free|net|open)bsd|solaris|aix|hpux/ && ENV['DISPLAY'].to_s.empty?)
|
|
41
|
+
end
|
|
42
|
+
|
|
39
43
|
def self.simple_terminal?
|
|
40
44
|
ENV['KONTENA_SIMPLE_TERM'] || !$stdout.tty?
|
|
41
45
|
end
|
|
@@ -31,8 +31,12 @@ variables:
|
|
|
31
31
|
env: test_var
|
|
32
32
|
TEST_ENV_VAR: # the default from/to is to set/read env of the option name
|
|
33
33
|
type: :string
|
|
34
|
-
|
|
34
|
+
tag:
|
|
35
35
|
type: string
|
|
36
|
+
from:
|
|
37
|
+
env: TAG
|
|
38
|
+
to:
|
|
39
|
+
env: TAG
|
|
36
40
|
MYSQL_IMAGE:
|
|
37
41
|
type: string
|
|
38
42
|
empty_is_nil: false
|
|
@@ -17,6 +17,7 @@ describe Kontena::Cli::Cloud::LoginCommand do
|
|
|
17
17
|
before(:each) do
|
|
18
18
|
allow(subject).to receive(:config).and_return(config)
|
|
19
19
|
allow(Kontena::Client).to receive(:new).and_return(client)
|
|
20
|
+
allow(Kontena).to receive(:browserless?).and_return(false)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
it 'should give error if trying to use --code and --force' do
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
describe Kontena::Cli::Etcd::HealthCommand do
|
|
2
|
+
include ClientHelpers
|
|
3
|
+
include OutputHelpers
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
allow(subject).to receive(:health_icon) {|health| health.inspect }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '#show_node_health' do
|
|
10
|
+
context "For an offline node" do
|
|
11
|
+
let :node_health do
|
|
12
|
+
{
|
|
13
|
+
"connected" => false,
|
|
14
|
+
"name" => "node-1",
|
|
15
|
+
'etcd_health' => {
|
|
16
|
+
'health' => nil,
|
|
17
|
+
'error' => nil,
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "shows offline and returns false" do
|
|
23
|
+
expect{subject.show_node_health(node_health)}.to return_and_output false, [
|
|
24
|
+
":offline Node node-1 is offline",
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "For a node with health errors" do
|
|
30
|
+
let :node_health do
|
|
31
|
+
{
|
|
32
|
+
"name" => "node-1",
|
|
33
|
+
"connected" => true,
|
|
34
|
+
'etcd_health' => {
|
|
35
|
+
'health' => nil,
|
|
36
|
+
'error' => "timeout",
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "shows errored and returns false" do
|
|
42
|
+
expect{subject.show_node_health(node_health)}.to return_and_output false, [
|
|
43
|
+
":error Node node-1 is unhealthy: timeout",
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "For a node that returns health=false" do
|
|
49
|
+
let :node_health do
|
|
50
|
+
{
|
|
51
|
+
"name" => "node-1",
|
|
52
|
+
"connected" => true,
|
|
53
|
+
'etcd_health' => {
|
|
54
|
+
'health' => false,
|
|
55
|
+
'error' => nil,
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "shows unhealthy and returns false" do
|
|
61
|
+
expect{subject.show_node_health(node_health)}.to return_and_output false, [
|
|
62
|
+
":error Node node-1 is unhealthy",
|
|
63
|
+
]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "For a healthy node" do
|
|
68
|
+
let :node_health do
|
|
69
|
+
{
|
|
70
|
+
"name" => "node-1",
|
|
71
|
+
"connected" => true,
|
|
72
|
+
'etcd_health' => {
|
|
73
|
+
'health' => true,
|
|
74
|
+
'error' => nil,
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
it "shows healthy and returns true" do
|
|
81
|
+
expect{subject.show_node_health(node_health)}.to return_and_output true, [
|
|
82
|
+
":ok Node node-1 is healthy",
|
|
83
|
+
]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|