kontena-cli 1.5.0.pre1 → 1.5.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|