kontena-cli 1.5.0.pre1 → 1.5.0.pre2
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/.gitignore +2 -0
- data/VERSION +1 -1
- data/bin/kontena +4 -2
- data/lib/kontena/callback.rb +8 -5
- data/lib/kontena/cli/containers/exec_command.rb +2 -0
- data/lib/kontena/cli/grids/remove_command.rb +2 -2
- data/lib/kontena/cli/master/ssh_command.rb +8 -2
- data/lib/kontena/cli/nodes/ssh_command.rb +8 -1
- data/lib/kontena/cli/services/exec_command.rb +2 -0
- data/lib/kontena/cli/stacks/yaml/validator_v3.rb +9 -0
- data/lib/kontena/command.rb +2 -1
- data/omnibus/config/software/kontena-cli.rb +1 -1
- data/spec/kontena/cli/grids/remove_command_spec.rb +28 -0
- data/spec/kontena/cli/nodes/ssh_command_spec.rb +3 -3
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +49 -0
- data/spec/kontena/command_spec.rb +67 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74f6386b28ddbc26a54ac61391df25e03f771574faddad0d8ea24731bd8bd561
|
4
|
+
data.tar.gz: 7c2563acbae96b3e5658715395990677c8ccb06ca326df05badae5359a9803d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acc350ae3e7ee4c98925a6777fba1ed1f668b6b0107ed7ed3309a57bedd46f3aa9b650c757429697e6ce361e3553fc1dd25b1e313b93791ef5b76b6a8a1fbee5
|
7
|
+
data.tar.gz: 96aa693a16692716d4510ab1c3c265a696c8f087cb1f6f5f2fcf712507b4e1cf5b12b47040b80ded854ef500fe88248a221400b58108e7b1ec5b94f088cd0276
|
data/.gitignore
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.5.0.
|
1
|
+
1.5.0.pre2
|
data/bin/kontena
CHANGED
@@ -13,8 +13,10 @@ if ARGV[0] == 'complete'
|
|
13
13
|
$VERSION_WARNING_ADDED=true
|
14
14
|
require 'kontena/scripts/completer'
|
15
15
|
else
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
arg_end_idx = ARGV.index('--') || ARGV.size
|
18
|
+
ENV['DEBUG'] = "true" if ARGV[0..arg_end_idx].any? { |arg| arg == '-D' || arg == '--debug'}
|
19
|
+
ENV['DEBUG'] = "false" if ARGV[0..arg_end_idx].any? { |arg| arg == '--no-debug' }
|
18
20
|
require 'kontena_cli'
|
19
21
|
Kontena::PluginManager.init unless ENV['NO_PLUGINS']
|
20
22
|
Kontena::MainCommand.run
|
data/lib/kontena/callback.rb
CHANGED
@@ -22,14 +22,17 @@ class Kontena::Callback
|
|
22
22
|
else
|
23
23
|
cmd_type = cmd_type.to_sym
|
24
24
|
end
|
25
|
-
cmd_types[cmd_class.to_sym]
|
25
|
+
cmd_types[cmd_class.to_sym] ||= []
|
26
|
+
cmd_types[cmd_class.to_sym] << cmd_type
|
26
27
|
end
|
27
28
|
|
28
29
|
# Finally it should be normalized into a hash that looks like :cmd_class => :cmd_type, :app => :init, :grid => :all
|
29
|
-
cmd_types.each do |cmd_class,
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
cmd_types.each do |cmd_class, cmd_types|
|
31
|
+
cmd_types.each do |cmd_type|
|
32
|
+
Kontena::Callback.callbacks[cmd_class] ||= {}
|
33
|
+
Kontena::Callback.callbacks[cmd_class][cmd_type] ||= []
|
34
|
+
Kontena::Callback.callbacks[cmd_class][cmd_type] << self
|
35
|
+
end
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
@@ -5,13 +5,13 @@ module Kontena::Cli::Grids
|
|
5
5
|
include Kontena::Cli::Common
|
6
6
|
include Common
|
7
7
|
|
8
|
-
parameter "NAME ...", "Grid name"
|
8
|
+
parameter "NAME ...", "Grid name"
|
9
9
|
option "--force", :flag, "Force remove", default: false, attribute_name: :forced
|
10
10
|
|
11
11
|
def execute
|
12
12
|
require_api_url
|
13
13
|
token = require_token
|
14
|
-
|
14
|
+
name_list.each do |name|
|
15
15
|
confirm_command(name) unless forced?
|
16
16
|
grid = find_grid_by_name(name)
|
17
17
|
|
@@ -2,9 +2,10 @@ require 'kontena/plugin_manager'
|
|
2
2
|
|
3
3
|
module Kontena::Cli::Master
|
4
4
|
class SshCommand < Kontena::Command
|
5
|
-
|
6
5
|
include Kontena::Cli::Common
|
7
6
|
|
7
|
+
usage "[OPTIONS] -- [COMMANDS] ..."
|
8
|
+
|
8
9
|
parameter "[COMMANDS] ...", "Run command on host"
|
9
10
|
|
10
11
|
option ["-i", "--identity-file"], "IDENTITY_FILE", "Path to ssh private key"
|
@@ -56,7 +57,12 @@ module Kontena::Cli::Master
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def run_vagrant_ssh
|
59
|
-
|
60
|
+
cmd = %w(vagrant master ssh)
|
61
|
+
unless commands_list.empty?
|
62
|
+
cmd << '--'
|
63
|
+
cmd.concat commands_list
|
64
|
+
end
|
65
|
+
Kontena.run!(cmd)
|
60
66
|
end
|
61
67
|
|
62
68
|
def execute
|
@@ -5,6 +5,8 @@ module Kontena::Cli::Nodes
|
|
5
5
|
include Kontena::Cli::Common
|
6
6
|
include Kontena::Cli::GridOptions
|
7
7
|
|
8
|
+
usage "[OPTIONS] [NODE] -- [COMMANDS] ..."
|
9
|
+
|
8
10
|
parameter "[NODE]", "SSH to Grid node. Use --any to connect to the first available node"
|
9
11
|
parameter "[COMMANDS] ...", "Run command on host"
|
10
12
|
option ["-a", "--any"], :flag, "Connect to first available node"
|
@@ -35,7 +37,11 @@ module Kontena::Cli::Nodes
|
|
35
37
|
unless Kontena::PluginManager::Common.installed?('vagrant')
|
36
38
|
exit_with_error 'You need to install vagrant plugin to ssh into this node. Use kontena plugin install vagrant'
|
37
39
|
end
|
38
|
-
cmd = ['vagrant', 'node', 'ssh', node['name']]
|
40
|
+
cmd = ['vagrant', 'node', 'ssh', node['name']]
|
41
|
+
unless commands_list.empty?
|
42
|
+
cmd << '--'
|
43
|
+
cmd.concat(commands_list)
|
44
|
+
end
|
39
45
|
Kontena.run!(cmd)
|
40
46
|
else
|
41
47
|
cmd = ['ssh']
|
@@ -49,6 +55,7 @@ module Kontena::Cli::Nodes
|
|
49
55
|
end
|
50
56
|
cmd << "#{user}@#{ip}"
|
51
57
|
cmd += commands_list
|
58
|
+
logger.debug { "Running ssh command: #{cmd.inspect}" }
|
52
59
|
exec(*cmd)
|
53
60
|
end
|
54
61
|
end
|
@@ -66,9 +66,18 @@ module Kontena::Cli::Stacks
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
if yaml.key?('stack')
|
70
|
+
unless yaml['stack'] =~ /\A(?:.+?\/)?(?!-)[a-z0-9\-]+\z/
|
71
|
+
result[:notifications] << { 'stack' => 'A stack name should only include a-z, 0-9 and - characters and not start with the - character' }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
69
75
|
if yaml.key?('services')
|
70
76
|
if yaml['services'].kind_of?(Hash)
|
71
77
|
yaml['services'].each do |service, options|
|
78
|
+
unless service =~ /\A(?!-)[a-z0-9\-]+\z/
|
79
|
+
result[:notifications] << { 'services' => { service => { 'name' => 'A service name should only include a-z, 0-9 and - characters and not start with the - character' } } }
|
80
|
+
end
|
72
81
|
unless options.kind_of?(Hash)
|
73
82
|
result[:errors] << { 'services' => { service => { 'options' => "must be a mapping not a #{options.class}"} } }
|
74
83
|
next
|
data/lib/kontena/command.rb
CHANGED
@@ -5,8 +5,9 @@ require 'kontena/cli/bytes_helper'
|
|
5
5
|
require 'kontena/cli/grid_options'
|
6
6
|
require 'excon/error'
|
7
7
|
|
8
|
-
|
8
|
+
Clamp.allow_options_after_parameters = true
|
9
9
|
|
10
|
+
class Kontena::Command < Clamp::Command
|
10
11
|
option ['-D', '--[no-]debug'], :flag, "Enable debug", environment_variable: 'DEBUG', attribute_name: :debug_option do |debug|
|
11
12
|
unless debug.kind_of?(String)
|
12
13
|
ENV['DEBUG'] = debug.to_s
|
@@ -13,7 +13,7 @@ build do
|
|
13
13
|
gem "install rb-readline -v 0.5.4 -N", env: env
|
14
14
|
gem "install nokogiri -v 1.8.2 -N", env: env
|
15
15
|
gem "build kontena-cli.gemspec", env: env, cwd: File.expand_path('..', Omnibus::Config.project_root)
|
16
|
-
gem "install -N
|
16
|
+
gem "install -N kontena-cli-%s.gem" % default_version, env: env, cwd: File.expand_path('..', Omnibus::Config.project_root)
|
17
17
|
gem "install kontena-plugin-cloud -N", env: env
|
18
18
|
copy "sh/kontena", "#{install_dir}/bin/kontena"
|
19
19
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'kontena/cli/grids/remove_command'
|
2
|
+
|
3
|
+
describe Kontena::Cli::Grids::RemoveCommand do
|
4
|
+
include ClientHelpers
|
5
|
+
|
6
|
+
before do
|
7
|
+
# Kontena::Cli::Grids::Common#grids
|
8
|
+
allow(client).to receive(:get).with('grids').and_return('grids' => grids)
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'without any grids' do
|
12
|
+
let(:grids) { [] }
|
13
|
+
|
14
|
+
it 'errors out' do
|
15
|
+
expect{subject.run ['--force', 'test-grid']}.to exit_with_error.and output(/Could not resolve grid by name/).to_stderr
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with a grid' do
|
20
|
+
let(:grids) { [{'id' => 'test-grid', 'name' => 'test-grid'}] }
|
21
|
+
|
22
|
+
it 'deletes the grid' do
|
23
|
+
expect(client).to receive(:delete).with('grids/test-grid')
|
24
|
+
|
25
|
+
subject.run ['--force', 'test-grid']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -20,7 +20,7 @@ describe Kontena::Cli::Nodes::SshCommand do
|
|
20
20
|
context 'used together with a node name' do
|
21
21
|
it "fails and outputs an error message" do
|
22
22
|
expect(subject).to_not receive(:exec)
|
23
|
-
expect{subject.run(['--any', 'ls', '-l'])}.to exit_with_error.and output(/Cannot combine --any with a node name/).to_stderr
|
23
|
+
expect{subject.run(['--any', '--', 'ls', '-l'])}.to exit_with_error.and output(/Cannot combine --any with a node name/).to_stderr
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -53,11 +53,11 @@ describe Kontena::Cli::Nodes::SshCommand do
|
|
53
53
|
|
54
54
|
it "passes through the command to SSH" do
|
55
55
|
expect(subject).to receive(:exec).with('ssh', 'core@192.0.2.10', 'ls', '-l')
|
56
|
-
subject.run ['test-node', 'ls', '-l']
|
56
|
+
subject.run ['test-node', '--', 'ls', '-l']
|
57
57
|
end
|
58
58
|
|
59
59
|
it "passes through arguments to SSH" do
|
60
60
|
expect(subject).to receive(:exec).with('ssh', 'core@192.0.2.10', '-F', 'ssh/config' 'ls', '-l')
|
61
|
-
subject.run ['test-node', '-F', 'ssh/config' 'ls', '-l']
|
61
|
+
subject.run ['test-node', '--', '-F', 'ssh/config' 'ls', '-l']
|
62
62
|
end
|
63
63
|
end
|
@@ -374,6 +374,55 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
374
374
|
end
|
375
375
|
|
376
376
|
describe '#validate' do
|
377
|
+
context 'stack' do
|
378
|
+
context 'stack name' do
|
379
|
+
let(:stack) do
|
380
|
+
{
|
381
|
+
'stack' => 'user/a_stack',
|
382
|
+
'services' => {
|
383
|
+
'app' => {
|
384
|
+
'image' => 'redis:latest'
|
385
|
+
}
|
386
|
+
}
|
387
|
+
}
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'should warn about invalid stack names' do
|
391
|
+
result = subject.validate(stack)
|
392
|
+
expect(result[:notifications]).to match array_including(
|
393
|
+
hash_including('stack' => /stack name should/)
|
394
|
+
)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
context 'services' do
|
400
|
+
context 'service name' do
|
401
|
+
let(:stack) do
|
402
|
+
{
|
403
|
+
'stack' => 'user/a-stack',
|
404
|
+
'services' => {
|
405
|
+
'invalid_service_name' => {
|
406
|
+
'image' => 'redis:latest'
|
407
|
+
}
|
408
|
+
}
|
409
|
+
}
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'should warn about invalid service names' do
|
413
|
+
result = subject.validate(stack)
|
414
|
+
expect(result[:notifications]).to match array_including(
|
415
|
+
hash_including(
|
416
|
+
'services' => hash_including(
|
417
|
+
'invalid_service_name' => hash_including(
|
418
|
+
'name' => /service name should/
|
419
|
+
)
|
420
|
+
)
|
421
|
+
)
|
422
|
+
)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
377
426
|
|
378
427
|
context 'volumes' do
|
379
428
|
let(:stack) do
|
@@ -51,4 +51,71 @@ describe Kontena::Command do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
context 'option placement handling' do
|
56
|
+
subject do
|
57
|
+
Class.new(Kontena::Command) do
|
58
|
+
parameter 'TESTPARAM', 'Test parameter'
|
59
|
+
option '--long-only', 'LONGONLY', 'Option with long only'
|
60
|
+
option ['--long-and-short', '-l'], :flag, 'Flag with short and long', default: false
|
61
|
+
|
62
|
+
def execute
|
63
|
+
{ param: testparam, longopt: long_only, shortflag: long_and_short? }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'allows using options before parameters' do
|
70
|
+
expect(subject.new('kontena').run(%w(-l --long-only longopt test))).to match hash_including(
|
71
|
+
param: 'test', longopt: 'longopt', shortflag: true
|
72
|
+
)
|
73
|
+
expect(subject.new('kontena').run(%w(--long-only longopt test))).to match hash_including(
|
74
|
+
param: 'test', longopt: 'longopt', shortflag: false
|
75
|
+
)
|
76
|
+
expect(subject.new('kontena').run(%w(--long-and-short test))).to match hash_including(
|
77
|
+
param: 'test', longopt: nil, shortflag: true
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'allows using options after parameters' do
|
82
|
+
expect(subject.new('kontena').run(%w(test -l --long-only longopt))).to match hash_including(
|
83
|
+
param: 'test', longopt: 'longopt', shortflag: true
|
84
|
+
)
|
85
|
+
expect(subject.new('kontena').run(%w(test --long-only longopt))).to match hash_including(
|
86
|
+
param: 'test', longopt: 'longopt', shortflag: false
|
87
|
+
)
|
88
|
+
expect(subject.new('kontena').run(%w(test --long-and-short))).to match hash_including(
|
89
|
+
param: 'test', longopt: nil, shortflag: true
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'allows using options mixed with parameters' do
|
94
|
+
expect(subject.new('kontena').run(%w(-l test --long-only longopt))).to match hash_including(
|
95
|
+
param: 'test', longopt: 'longopt', shortflag: true
|
96
|
+
)
|
97
|
+
expect(subject.new('kontena').run(%w(--long-and-short test --long-only longopt))).to match hash_including(
|
98
|
+
param: 'test', longopt: 'longopt', shortflag: true
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with double dash' do
|
103
|
+
subject do
|
104
|
+
Class.new(Kontena::Command) do
|
105
|
+
parameter 'TESTPARAM ...', 'Test parameter'
|
106
|
+
option '--opt', 'OPT', 'Option'
|
107
|
+
|
108
|
+
def execute
|
109
|
+
{ param_list: testparam_list, opt: opt }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'does not parse options after -- double dash' do
|
115
|
+
expect(subject.new('kontena').run(%w(--opt hello foo -- --bar hello))).to match hash_including(
|
116
|
+
param_list: %w(foo --bar hello), opt: 'hello'
|
117
|
+
)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
54
121
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kontena-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.0.
|
4
|
+
version: 1.5.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kontena, Inc
|
@@ -570,6 +570,7 @@ files:
|
|
570
570
|
- spec/kontena/cli/etcd/health_command_spec.rb
|
571
571
|
- spec/kontena/cli/grids/events_command_spec.rb
|
572
572
|
- spec/kontena/cli/grids/health_command_spec.rb
|
573
|
+
- spec/kontena/cli/grids/remove_command_spec.rb
|
573
574
|
- spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb
|
574
575
|
- spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb
|
575
576
|
- spec/kontena/cli/grids/trusted_subnets/remove_command_spec.rb
|
@@ -752,6 +753,7 @@ test_files:
|
|
752
753
|
- spec/kontena/cli/etcd/health_command_spec.rb
|
753
754
|
- spec/kontena/cli/grids/events_command_spec.rb
|
754
755
|
- spec/kontena/cli/grids/health_command_spec.rb
|
756
|
+
- spec/kontena/cli/grids/remove_command_spec.rb
|
755
757
|
- spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb
|
756
758
|
- spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb
|
757
759
|
- spec/kontena/cli/grids/trusted_subnets/remove_command_spec.rb
|