kontena-cli 1.2.0.dev1 → 1.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/kontena-cli.gemspec +1 -1
- data/lib/kontena/cli/grids/common.rb +7 -0
- data/lib/kontena/cli/grids/update_command.rb +26 -0
- data/lib/kontena/cli/services/logs_command.rb +1 -1
- data/lib/kontena/cli/services/stats_command.rb +12 -2
- data/lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb +9 -3
- data/lib/kontena/cli/volume_command.rb +8 -0
- data/lib/kontena/cli/volumes/create_command.rb +38 -0
- data/lib/kontena/cli/volumes/list_command.rb +21 -0
- data/lib/kontena/cli/volumes/remove_command.rb +24 -0
- data/lib/kontena/command.rb +1 -1
- data/lib/kontena/main_command.rb +1 -0
- data/omnibus/wrappers/sh/kontena +1 -1
- data/spec/kontena/cli/grids/update_command_spec.rb +46 -0
- data/spec/kontena/cli/services/logs_command_spec.rb +41 -0
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +6 -0
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f03d83329e4ddcebc48f226b38df3d4eb9b6f96f
|
4
|
+
data.tar.gz: 451423d5bc02c8c01a18170cbb665a455d26a3d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24c1bd893acbaf99a21795710024e0673e79e0685f83f3478f6a708568c2f12f440f6caa463068406a22de4f232de2e6120017ca64334e8fc7dd7977932df3a1
|
7
|
+
data.tar.gz: c56ff810d3d4809d2c9d8c3c705389a0c801baf407290e89ec8ee718f3ef04b2d87112122eb379c498032da63994ee0b3f58cb609f24f45105ceeaca994819bf
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.0.
|
1
|
+
1.2.0.pre1
|
data/kontena-cli.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_runtime_dependency "launchy", "~> 2.4.3"
|
30
30
|
spec.add_runtime_dependency "hash_validator", "~> 0.7.0"
|
31
31
|
spec.add_runtime_dependency "retriable", "~> 2.1.0"
|
32
|
-
spec.add_runtime_dependency "opto", "1.8.
|
32
|
+
spec.add_runtime_dependency "opto", "1.8.4"
|
33
33
|
spec.add_runtime_dependency "semantic", "~> 1.5"
|
34
34
|
spec.add_runtime_dependency "safe_yaml", "~> 1.0"
|
35
35
|
spec.add_runtime_dependency "liquid", "~> 4.0.0"
|
@@ -41,6 +41,13 @@ module Kontena::Cli::Grids
|
|
41
41
|
puts " exports:"
|
42
42
|
puts " statsd: #{statsd['server']}:#{statsd['port']}"
|
43
43
|
end
|
44
|
+
if logs = grid.dig('logs')
|
45
|
+
puts "logs:"
|
46
|
+
puts " forwarder: #{logs['forwarder']}"
|
47
|
+
logs['opts'].each do |k,v|
|
48
|
+
puts " #{k}: #{v}"
|
49
|
+
end
|
50
|
+
end
|
44
51
|
end
|
45
52
|
|
46
53
|
def grids
|
@@ -8,10 +8,13 @@ module Kontena::Cli::Grids
|
|
8
8
|
parameter "NAME", "Grid name"
|
9
9
|
option "--statsd-server", "STATSD_SERVER", "Statsd server address (host:port)"
|
10
10
|
option "--default-affinity", "[AFFINITY]", "Default affinity rule for the grid", multivalued: true
|
11
|
+
option "--log-forwarder", "LOG_FORWARDER", "Set grid wide log forwarder"
|
12
|
+
option "--log-opt", "[LOG_OPT]", "Set log options (key=value)", multivalued: true
|
11
13
|
|
12
14
|
def execute
|
13
15
|
require_api_url
|
14
16
|
token = require_token
|
17
|
+
validate_log_opts
|
15
18
|
payload = {}
|
16
19
|
if statsd_server
|
17
20
|
server, port = statsd_server.split(':')
|
@@ -22,10 +25,33 @@ module Kontena::Cli::Grids
|
|
22
25
|
}
|
23
26
|
}
|
24
27
|
end
|
28
|
+
|
29
|
+
if log_forwarder
|
30
|
+
payload[:logs] = {
|
31
|
+
forwarder: log_forwarder,
|
32
|
+
opts: parse_log_opts
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
25
36
|
if default_affinity_list
|
26
37
|
payload[:default_affinity] = default_affinity_list
|
27
38
|
end
|
28
39
|
client(token).put("grids/#{name}", payload)
|
29
40
|
end
|
41
|
+
|
42
|
+
def validate_log_opts
|
43
|
+
if !log_opt_list.empty? && log_forwarder.nil?
|
44
|
+
raise Kontena::Errors::StandardError.new(1, "Need to specify --log-forwarder when using --log-opt")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_log_opts
|
49
|
+
opts = {}
|
50
|
+
log_opt_list.each do |opt|
|
51
|
+
key, value = opt.split('=')
|
52
|
+
opts[key.to_sym] = value
|
53
|
+
end
|
54
|
+
opts
|
55
|
+
end
|
30
56
|
end
|
31
57
|
end
|
@@ -15,7 +15,7 @@ module Kontena::Cli::Services
|
|
15
15
|
require_api_url
|
16
16
|
|
17
17
|
query_params = {}
|
18
|
-
query_params[:
|
18
|
+
query_params[:instance] = instance if instance
|
19
19
|
|
20
20
|
show_logs("services/#{parse_service_id(name)}/container_logs", query_params) do |log|
|
21
21
|
show_log(log)
|
@@ -53,8 +53,10 @@ module Kontena::Cli::Services
|
|
53
53
|
end
|
54
54
|
|
55
55
|
cpu = stat['cpu'].nil? ? 'N/A' : stat['cpu']['usage']
|
56
|
-
|
57
|
-
|
56
|
+
|
57
|
+
network_in = stat['network'].nil? ? 'N/A' : filesize_to_human(network_bytes(stat['network'], 'rx_bytes'))
|
58
|
+
network_out = stat['network'].nil? ? 'N/A' : filesize_to_human(network_bytes(stat['network'], 'tx_bytes'))
|
59
|
+
|
58
60
|
prefix = self.name.split('/')[0]
|
59
61
|
instance_name = stat['container_id'].gsub("#{prefix}-", "")
|
60
62
|
puts '%-30.30s %-15s %-20s %-15s %-15s' % [ instance_name, "#{cpu}%", "#{memory} / #{memory_limit}", "#{memory_pct}", "#{network_in}/#{network_out}"]
|
@@ -72,5 +74,13 @@ module Kontena::Cli::Services
|
|
72
74
|
rescue FloatDomainError
|
73
75
|
'N/A'
|
74
76
|
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# @param [Hash] network
|
80
|
+
# @param [String] key
|
81
|
+
# @return [Integer]
|
82
|
+
def network_bytes(network, key)
|
83
|
+
(network.dig('internal', key) || 0) + (network.dig('external', key) || 0)
|
84
|
+
end
|
75
85
|
end
|
76
86
|
end
|
@@ -6,10 +6,16 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
6
6
|
|
7
7
|
def validate(key, value, validations, errors)
|
8
8
|
unless value.is_a?(Hash)
|
9
|
-
errors[key] =
|
9
|
+
errors[key] = "must be a mapping, not #{value.class}"
|
10
10
|
return
|
11
11
|
end
|
12
12
|
|
13
|
+
value.keys.each do |hook|
|
14
|
+
unless %w(pre_build post_start).include?(hook)
|
15
|
+
errors[key] = "invalid hook #{hook}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
13
19
|
if value['pre_build']
|
14
20
|
validate_pre_build_hooks(key, value['pre_build'], errors)
|
15
21
|
end
|
@@ -21,7 +27,7 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
21
27
|
|
22
28
|
def validate_pre_build_hooks(key, pre_build_hooks, errors)
|
23
29
|
unless pre_build_hooks.is_a?(Array)
|
24
|
-
errors[key] = 'pre_build must be array
|
30
|
+
errors[key] = { 'pre_build' => "must be an array" }
|
25
31
|
return
|
26
32
|
end
|
27
33
|
pre_build_validation = {
|
@@ -36,7 +42,7 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
36
42
|
|
37
43
|
def validate_post_start_hooks(key, post_start_hooks, errors)
|
38
44
|
unless post_start_hooks.is_a?(Array)
|
39
|
-
errors[key] = 'post_start must be array'
|
45
|
+
errors[key] = { 'post_start' => 'must be an array' }
|
40
46
|
return
|
41
47
|
end
|
42
48
|
post_start_validation = {
|
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
class Kontena::Cli::VolumeCommand < Kontena::Command
|
3
|
+
|
4
|
+
subcommand "create", "Create a managed volume", load_subcommand('volumes/create_command')
|
5
|
+
subcommand ["remove", "rm"], "Remove a managed volume", load_subcommand('volumes/remove_command')
|
6
|
+
subcommand ["list", "ls"], "List managed volumes", load_subcommand('volumes/list_command')
|
7
|
+
|
8
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class CreateCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
|
8
|
+
banner "Creates a volume"
|
9
|
+
parameter 'NAME', 'Volume name'
|
10
|
+
|
11
|
+
option '--driver', 'DRIVER', 'Volume driver to be used'
|
12
|
+
option '--driver-opt', 'DRIVER_OPT', 'Volume driver options', multivalued: true
|
13
|
+
option '--scope', 'SCOPE', 'Volume scope'
|
14
|
+
|
15
|
+
requires_current_master
|
16
|
+
requires_current_master_token
|
17
|
+
|
18
|
+
def execute
|
19
|
+
volume = {
|
20
|
+
name: name,
|
21
|
+
scope: scope,
|
22
|
+
driver: driver,
|
23
|
+
driver_opts: parse_driver_opts
|
24
|
+
}
|
25
|
+
spinner "Creating volume #{pastel.cyan(name)} " do
|
26
|
+
create_volume(volume)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse_driver_opts
|
31
|
+
Hash[driver_opt_list.map{|opt| opt.split '='}]
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_volume(volume)
|
35
|
+
client.post("volumes/#{current_grid}", volume)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class ListCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
|
8
|
+
requires_current_master
|
9
|
+
requires_current_master_token
|
10
|
+
|
11
|
+
def execute
|
12
|
+
volumes = client.get("volumes/#{current_grid}")['volumes']
|
13
|
+
columns = '%-25.25s %-25.25s %-25.25s %-25.25s'
|
14
|
+
puts columns % ['NAME', 'SCOPE', 'DRIVER', 'CREATED AT']
|
15
|
+
volumes.each do |volume|
|
16
|
+
puts columns % [volume['name'], volume['scope'], volume['driver'], volume['created_at']]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class RemoveCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
|
8
|
+
banner "Removes a volume"
|
9
|
+
parameter 'VOLUME', 'Volume'
|
10
|
+
|
11
|
+
requires_current_master
|
12
|
+
requires_current_master_token
|
13
|
+
|
14
|
+
def execute
|
15
|
+
spinner "Removing volume #{pastel.cyan(volume)} " do
|
16
|
+
remove_volume(volume)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove_volume(volume)
|
21
|
+
client.delete("volumes/#{current_grid}/#{volume}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/kontena/command.rb
CHANGED
@@ -213,7 +213,7 @@ class Kontena::Command < Clamp::Command
|
|
213
213
|
end
|
214
214
|
rescue Kontena::Errors::StandardError => exc
|
215
215
|
raise exc if ENV['DEBUG']
|
216
|
-
puts " [#{Kontena.pastel.red('error')}] #{exc.message}"
|
216
|
+
$stderr.puts " [#{Kontena.pastel.red('error')}] #{exc.message}"
|
217
217
|
abort
|
218
218
|
rescue Errno::EPIPE
|
219
219
|
# If user is piping the command outputs to some other command that might exit before CLI has outputted everything
|
data/lib/kontena/main_command.rb
CHANGED
@@ -36,6 +36,7 @@ class Kontena::MainCommand < Kontena::Command
|
|
36
36
|
subcommand "whoami", "Shows current logged in user", load_subcommand('whoami_command')
|
37
37
|
subcommand "plugin", "Plugin related commands", load_subcommand('plugin_command')
|
38
38
|
subcommand "version", "Show CLI and current master version", load_subcommand('version_command')
|
39
|
+
subcommand "volume", "Volume specific commands", load_subcommand('volume_command')
|
39
40
|
|
40
41
|
def execute
|
41
42
|
end
|
data/omnibus/wrappers/sh/kontena
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
require_relative "../../../spec_helper"
|
3
|
+
require 'kontena/cli/grids/update_command'
|
4
|
+
|
5
|
+
describe Kontena::Cli::Grids::UpdateCommand do
|
6
|
+
|
7
|
+
include ClientHelpers
|
8
|
+
|
9
|
+
let(:client) do
|
10
|
+
Kontena::Client.new('https://foo', {access_token: 'abcd1234'})
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:subject) do
|
14
|
+
described_class.new(File.basename($0))
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:server) do
|
18
|
+
Kontena::Cli::Config::Server.new(url: 'https://localhost', token: 'abcd1234')
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#update" do
|
22
|
+
|
23
|
+
context 'log options' do
|
24
|
+
it 'should fail if no driver specified' do
|
25
|
+
expect {
|
26
|
+
subject.run(['--log-opt', 'foo=bar', 'test'])
|
27
|
+
}.to exit_with_error
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should send valid options to server' do
|
32
|
+
expect(client).to receive(:put).with(
|
33
|
+
'grids/test', hash_including({
|
34
|
+
logs: {
|
35
|
+
forwarder: 'fluentd',
|
36
|
+
opts: {
|
37
|
+
foo: 'bar'
|
38
|
+
}
|
39
|
+
}
|
40
|
+
})
|
41
|
+
)
|
42
|
+
subject.run(['--log-forwarder', 'fluentd', '--log-opt', 'foo=bar', 'test'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative "../../../spec_helper"
|
2
|
+
require "kontena/cli/services/logs_command"
|
3
|
+
|
4
|
+
describe Kontena::Cli::Services::LogsCommand do
|
5
|
+
|
6
|
+
include ClientHelpers
|
7
|
+
|
8
|
+
describe '#execute' do
|
9
|
+
before(:each) do
|
10
|
+
allow(client).to receive(:get).and_return({
|
11
|
+
'logs' => []
|
12
|
+
})
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'requires api url' do
|
16
|
+
expect(subject).to receive(:require_api_url).once
|
17
|
+
subject.run(['service-a'])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'requires token' do
|
21
|
+
expect(subject).to receive(:require_token).and_return(token)
|
22
|
+
subject.run(['service-a'])
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'requests logs from master' do
|
26
|
+
expect(client).to receive(:get).with(
|
27
|
+
'services/test-grid/null/service-a/container_logs', {limit: 100}
|
28
|
+
)
|
29
|
+
subject.run(['service-a'])
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when passing instance option ' do
|
33
|
+
it 'adds it to query params' do
|
34
|
+
expect(client).to receive(:get).with(
|
35
|
+
'services/test-grid/null/service-a/container_logs', {instance: '1', limit: 100}
|
36
|
+
)
|
37
|
+
subject.run(['-i', '1', 'service-a'])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -165,6 +165,12 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
165
165
|
end
|
166
166
|
|
167
167
|
context 'hooks' do
|
168
|
+
context 'validates hook name' do
|
169
|
+
it 'must be valid hook' do
|
170
|
+
result = subject.validate_options('hooks' => { 'pre-build' => {} })
|
171
|
+
expect(result.errors.key?('hooks')).to be_truthy
|
172
|
+
end
|
173
|
+
end
|
168
174
|
context 'validates pre_build' do
|
169
175
|
it 'must be array' do
|
170
176
|
result = subject.validate_options('hooks' => { 'pre_build' => {} })
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kontena-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.0.
|
4
|
+
version: 1.2.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kontena, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - '='
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 1.8.
|
145
|
+
version: 1.8.4
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - '='
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 1.8.
|
152
|
+
version: 1.8.4
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: semantic
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -456,6 +456,10 @@ files:
|
|
456
456
|
- lib/kontena/cli/vault_command.rb
|
457
457
|
- lib/kontena/cli/version.rb
|
458
458
|
- lib/kontena/cli/version_command.rb
|
459
|
+
- lib/kontena/cli/volume_command.rb
|
460
|
+
- lib/kontena/cli/volumes/create_command.rb
|
461
|
+
- lib/kontena/cli/volumes/list_command.rb
|
462
|
+
- lib/kontena/cli/volumes/remove_command.rb
|
459
463
|
- lib/kontena/cli/vpn/config_command.rb
|
460
464
|
- lib/kontena/cli/vpn/create_command.rb
|
461
465
|
- lib/kontena/cli/vpn/remove_command.rb
|
@@ -559,6 +563,7 @@ files:
|
|
559
563
|
- spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb
|
560
564
|
- spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb
|
561
565
|
- spec/kontena/cli/grids/trusted_subnets/remove_command_spec.rb
|
566
|
+
- spec/kontena/cli/grids/update_command_spec.rb
|
562
567
|
- spec/kontena/cli/grids/use_command_spec.rb
|
563
568
|
- spec/kontena/cli/helpers/log_helper_spec.rb
|
564
569
|
- spec/kontena/cli/main_command_spec.rb
|
@@ -576,6 +581,7 @@ files:
|
|
576
581
|
- spec/kontena/cli/services/containers_command_spec.rb
|
577
582
|
- spec/kontena/cli/services/exec_command_spec.rb
|
578
583
|
- spec/kontena/cli/services/link_command_spec.rb
|
584
|
+
- spec/kontena/cli/services/logs_command_spec.rb
|
579
585
|
- spec/kontena/cli/services/restart_command_spec.rb
|
580
586
|
- spec/kontena/cli/services/secrets/link_command_spec.rb
|
581
587
|
- spec/kontena/cli/services/secrets/unlink_command_spec.rb
|
@@ -695,6 +701,7 @@ test_files:
|
|
695
701
|
- spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb
|
696
702
|
- spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb
|
697
703
|
- spec/kontena/cli/grids/trusted_subnets/remove_command_spec.rb
|
704
|
+
- spec/kontena/cli/grids/update_command_spec.rb
|
698
705
|
- spec/kontena/cli/grids/use_command_spec.rb
|
699
706
|
- spec/kontena/cli/helpers/log_helper_spec.rb
|
700
707
|
- spec/kontena/cli/main_command_spec.rb
|
@@ -712,6 +719,7 @@ test_files:
|
|
712
719
|
- spec/kontena/cli/services/containers_command_spec.rb
|
713
720
|
- spec/kontena/cli/services/exec_command_spec.rb
|
714
721
|
- spec/kontena/cli/services/link_command_spec.rb
|
722
|
+
- spec/kontena/cli/services/logs_command_spec.rb
|
715
723
|
- spec/kontena/cli/services/restart_command_spec.rb
|
716
724
|
- spec/kontena/cli/services/secrets/link_command_spec.rb
|
717
725
|
- spec/kontena/cli/services/secrets/unlink_command_spec.rb
|