kontena-cli 1.3.5 → 1.4.0.pre1
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 +5 -5
- data/VERSION +1 -1
- data/lib/kontena/cli/etcd/health_command.rb +1 -1
- data/lib/kontena/cli/grids/common.rb +51 -0
- data/lib/kontena/cli/grids/create_command.rb +13 -9
- data/lib/kontena/cli/grids/update_command.rb +11 -44
- data/lib/kontena/cli/node_command.rb +3 -0
- data/lib/kontena/cli/nodes/create_command.rb +25 -0
- data/lib/kontena/cli/nodes/env_command.rb +32 -0
- data/lib/kontena/cli/nodes/health_command.rb +2 -2
- data/lib/kontena/cli/nodes/labels/add_command.rb +3 -3
- data/lib/kontena/cli/nodes/labels/list_command.rb +2 -2
- data/lib/kontena/cli/nodes/labels/remove_command.rb +3 -3
- data/lib/kontena/cli/nodes/remove_command.rb +9 -7
- data/lib/kontena/cli/nodes/reset_token_command.rb +31 -0
- data/lib/kontena/cli/nodes/show_command.rb +4 -4
- data/lib/kontena/cli/nodes/ssh_command.rb +4 -4
- data/lib/kontena/cli/nodes/update_command.rb +13 -8
- data/lib/kontena/cli/services/create_command.rb +4 -0
- data/lib/kontena/cli/services/services_helper.rb +2 -0
- data/lib/kontena/cli/services/update_command.rb +2 -0
- data/lib/kontena/cli/stacks/service_generator.rb +2 -0
- data/lib/kontena/cli/stacks/show_command.rb +1 -0
- data/lib/kontena/cli/stacks/stacks_helper.rb +2 -3
- data/lib/kontena/cli/stacks/yaml/validations.rb +3 -1
- data/lib/kontena/machine/cloud_config/cloudinit.yml +17 -4
- data/omnibus/package-scripts/kontena/postinst +0 -4
- data/omnibus/package-scripts/kontena/postrm +1 -1
- data/omnibus/package-scripts/kontena/preinst +0 -2
- data/spec/fixtures/api/node.json +93 -0
- data/spec/kontena/cli/containers/logs_command_spec.rb +0 -4
- data/spec/kontena/cli/etcd/health_command_spec.rb +128 -63
- data/spec/kontena/cli/nodes/create_command_spec.rb +24 -0
- data/spec/kontena/cli/nodes/env_command_spec.rb +49 -0
- data/spec/kontena/cli/nodes/health_command_spec.rb +15 -173
- data/spec/kontena/cli/nodes/labels/add_command_spec.rb +56 -0
- data/spec/kontena/cli/nodes/labels/list_command_spec.rb +43 -0
- data/spec/kontena/cli/nodes/labels/remove_command_spec.rb +57 -0
- data/spec/kontena/cli/nodes/list_command_spec.rb +0 -2
- data/spec/kontena/cli/nodes/remove_command_spec.rb +76 -0
- data/spec/kontena/cli/nodes/reset_token_command_spec.rb +38 -0
- data/spec/kontena/cli/nodes/show_command_spec.rb +46 -0
- data/spec/kontena/cli/nodes/ssh_command_spec.rb +5 -0
- data/spec/kontena/cli/nodes/update_command_spec.rb +24 -0
- data/spec/kontena/cli/stacks/deploy_command_spec.rb +21 -0
- data/spec/kontena/cli/stacks/logs_command_spec.rb +0 -4
- data/spec/kontena/cli/table_generator_spec.rb +0 -4
- data/spec/spec_helper.rb +5 -0
- data/spec/support/output_helpers.rb +3 -14
- data/tasks/release.rake +2 -2
- metadata +28 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 69a344212c91c304c80efd5073e2b3d3e9003b66
|
4
|
+
data.tar.gz: 04ba668d77961f031b6bdd1bad7cbeacab5dfac9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fb80753ebfd53b27841cedaa60b2de9af188b6448691b7cc5e9f02410e644d44115b8f873295c7cf2eef823fa929911069d7032ebe5334ffbadd46b52d18b35
|
7
|
+
data.tar.gz: 32129fc7dd6d6ba258238a47799d085d639d5ae0168ee64a90de78756c8984dbfc88885324ce06f5cb4ffe8a76286cb97f119479c3c41e7e4430b6fa6241befc
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0.pre1
|
@@ -26,7 +26,7 @@ module Kontena::Cli::Etcd
|
|
26
26
|
nodes = client.get("grids/#{current_grid}/nodes")['nodes']
|
27
27
|
|
28
28
|
nodes.each do |node|
|
29
|
-
node_health = client.get("nodes/#{
|
29
|
+
node_health = client.get("nodes/#{node['id']}/health")
|
30
30
|
|
31
31
|
if !show_node_health(node_health)
|
32
32
|
health = false
|
@@ -117,5 +117,56 @@ module Kontena::Cli::Grids
|
|
117
117
|
exit_with_error "No grid given or selected"
|
118
118
|
end
|
119
119
|
end
|
120
|
+
|
121
|
+
module Parameters
|
122
|
+
def self.included(base)
|
123
|
+
base.option "--default-affinity", "[AFFINITY]", "Default affinity rule for the grid", multivalued: true
|
124
|
+
base.option "--statsd-server", "STATSD_SERVER", "Statsd server address (host:port)"
|
125
|
+
base.option "--log-forwarder", "LOG_FORWARDER", "Set grid wide log forwarder (set to 'none' to disable)"
|
126
|
+
base.option "--log-opt", "[LOG_OPT]", "Set log options (key=value)", multivalued: true
|
127
|
+
end
|
128
|
+
|
129
|
+
def validate_log_opts
|
130
|
+
if !log_opt_list.empty? && log_forwarder.nil?
|
131
|
+
raise Kontena::Errors::StandardError.new(1, "Need to specify --log-forwarder when using --log-opt")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def parse_log_opts
|
136
|
+
opts = {}
|
137
|
+
log_opt_list.each do |opt|
|
138
|
+
key, value = opt.split('=')
|
139
|
+
opts[key.to_sym] = value
|
140
|
+
end
|
141
|
+
opts
|
142
|
+
end
|
143
|
+
|
144
|
+
def validate_grid_parameters
|
145
|
+
validate_log_opts
|
146
|
+
end
|
147
|
+
|
148
|
+
def build_grid_parameters(payload)
|
149
|
+
if statsd_server
|
150
|
+
server, port = statsd_server.split(':')
|
151
|
+
payload[:stats] = {
|
152
|
+
statsd: {
|
153
|
+
server: server,
|
154
|
+
port: port || 8125
|
155
|
+
}
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
if log_forwarder
|
160
|
+
payload[:logs] = {
|
161
|
+
forwarder: log_forwarder,
|
162
|
+
opts: parse_log_opts
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
unless default_affinity_list.empty?
|
167
|
+
payload[:default_affinity] = default_affinity_list
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
120
171
|
end
|
121
172
|
end
|
@@ -10,28 +10,32 @@ module Kontena::Cli::Grids
|
|
10
10
|
option "--initial-size", "INITIAL_SIZE", "Initial grid size (number of nodes)", default: 1
|
11
11
|
option "--silent", :flag, "Reduce output verbosity"
|
12
12
|
option "--token", "[TOKEN]", "Set grid token"
|
13
|
-
option "--default-affinity", "[AFFINITY]", "Default affinity rule for the grid", multivalued: true
|
14
13
|
option "--subnet", "[CIDR]", "Configure grid overlay subnet"
|
15
14
|
option "--supernet", "[CIDR]", "Configure grid IPAM supernet"
|
16
15
|
|
16
|
+
include Common::Parameters
|
17
|
+
|
17
18
|
requires_current_master_token
|
18
19
|
|
19
20
|
def execute
|
21
|
+
validate_grid_parameters
|
22
|
+
|
23
|
+
if initial_size == 1
|
24
|
+
warning "Option --initial-size=1 is only recommended for test/dev usage" unless running_silent?
|
25
|
+
end
|
26
|
+
|
20
27
|
payload = {
|
21
28
|
name: name
|
22
29
|
}
|
23
30
|
payload[:token] = self.token if self.token
|
24
31
|
payload[:initial_size] = self.initial_size if self.initial_size
|
25
|
-
payload[:default_affinity] = self.default_affinity_list unless self.default_affinity_list.empty?
|
26
32
|
payload[:subnet] = subnet if subnet
|
27
33
|
payload[:supernet] = supernet if supernet
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
spinner "Creating #{pastel.cyan(name)} grid " do
|
34
|
-
grid = client.post('grids', payload)
|
34
|
+
|
35
|
+
build_grid_parameters(payload)
|
36
|
+
|
37
|
+
grid = spinner "Creating #{pastel.cyan(name)} grid " do
|
38
|
+
client.post('grids', payload)
|
35
39
|
end
|
36
40
|
if grid
|
37
41
|
spinner "Switching scope to #{pastel.cyan(name)} grid " do
|
@@ -6,63 +6,30 @@ module Kontena::Cli::Grids
|
|
6
6
|
include Common
|
7
7
|
|
8
8
|
parameter "NAME", "Grid name"
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
include Common::Parameters
|
11
|
+
|
12
12
|
option "--no-default-affinity", :flag, "Unset grid default affinity"
|
13
|
-
option "--
|
14
|
-
|
13
|
+
option "--no-statsd-server", :flag, "Unset statsd server setting"
|
14
|
+
|
15
|
+
requires_current_master_token
|
15
16
|
|
16
17
|
def execute
|
17
|
-
|
18
|
-
|
19
|
-
validate_log_opts
|
18
|
+
validate_grid_parameters
|
19
|
+
|
20
20
|
payload = {}
|
21
|
-
|
22
|
-
|
23
|
-
payload[:stats] = {
|
24
|
-
statsd: {
|
25
|
-
server: server,
|
26
|
-
port: port || 8125
|
27
|
-
}
|
28
|
-
}
|
29
|
-
end
|
21
|
+
|
22
|
+
build_grid_parameters(payload)
|
30
23
|
|
31
24
|
if no_statsd_server?
|
32
25
|
payload[:stats] = { statsd: nil }
|
33
26
|
end
|
34
27
|
|
35
|
-
if log_forwarder
|
36
|
-
payload[:logs] = {
|
37
|
-
forwarder: log_forwarder,
|
38
|
-
opts: parse_log_opts
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
unless default_affinity_list.empty?
|
43
|
-
payload[:default_affinity] = default_affinity_list
|
44
|
-
end
|
45
|
-
|
46
28
|
if no_default_affinity?
|
47
29
|
payload[:default_affinity] = []
|
48
30
|
end
|
49
31
|
|
50
|
-
client
|
51
|
-
end
|
52
|
-
|
53
|
-
def validate_log_opts
|
54
|
-
if !log_opt_list.empty? && log_forwarder.nil?
|
55
|
-
raise Kontena::Errors::StandardError.new(1, "Need to specify --log-forwarder when using --log-opt")
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def parse_log_opts
|
60
|
-
opts = {}
|
61
|
-
log_opt_list.each do |opt|
|
62
|
-
key, value = opt.split('=')
|
63
|
-
opts[key.to_sym] = value
|
64
|
-
end
|
65
|
-
opts
|
32
|
+
client.put("grids/#{name}", payload)
|
66
33
|
end
|
67
34
|
end
|
68
35
|
end
|
@@ -3,10 +3,13 @@ class Kontena::Cli::NodeCommand < Kontena::Command
|
|
3
3
|
subcommand ["list","ls"], "List grid nodes", load_subcommand('nodes/list_command')
|
4
4
|
subcommand "show", "Show node", load_subcommand('nodes/show_command')
|
5
5
|
subcommand "ssh", "Ssh into node", load_subcommand('nodes/ssh_command')
|
6
|
+
subcommand "create", "Create node", load_subcommand('nodes/create_command')
|
6
7
|
subcommand "update", "Update node", load_subcommand('nodes/update_command')
|
8
|
+
subcommand "reset-token", "Reset node token for agent websocket connection", load_subcommand('nodes/reset_token_command')
|
7
9
|
subcommand ["remove","rm"], "Remove node", load_subcommand('nodes/remove_command')
|
8
10
|
subcommand "label", "Node label specific commands", load_subcommand('nodes/label_command')
|
9
11
|
subcommand "health", "Check node health", load_subcommand('nodes/health_command')
|
12
|
+
subcommand "env", "Generate kontena-agent.env configuration", load_subcommand('nodes/env_command')
|
10
13
|
|
11
14
|
def execute
|
12
15
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Kontena::Cli::Nodes
|
2
|
+
class CreateCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
requires_current_master
|
7
|
+
requires_current_master_token
|
8
|
+
requires_current_grid
|
9
|
+
|
10
|
+
parameter "NAME", "Node name"
|
11
|
+
option ["--token"], "TOKEN", "Node token"
|
12
|
+
option ["-l", "--label"], "LABEL", "Node label", multivalued: true
|
13
|
+
|
14
|
+
def execute
|
15
|
+
data = { name: name }
|
16
|
+
|
17
|
+
data[:token] = token if token
|
18
|
+
data[:labels] = label_list
|
19
|
+
|
20
|
+
spinner "Creating #{name.colorize(:cyan)} node " do
|
21
|
+
client.post("grids/#{current_grid}/nodes", data)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Kontena::Cli::Nodes
|
2
|
+
class EnvCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
requires_current_master
|
7
|
+
requires_current_master_token
|
8
|
+
requires_current_grid
|
9
|
+
|
10
|
+
parameter "NAME", "Node name"
|
11
|
+
option ['--token'], :flag, 'Only show token', default: false
|
12
|
+
|
13
|
+
def grid_uri
|
14
|
+
grid_uri = self.current_master['url'].sub('http', 'ws')
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute
|
18
|
+
token_node = client.get("nodes/#{current_grid}/#{name}/token")
|
19
|
+
|
20
|
+
unless token_node['token']
|
21
|
+
exit_with_error "Node #{name} was not created with a node token. Use `kontena grid env` instead"
|
22
|
+
end
|
23
|
+
|
24
|
+
if self.token?
|
25
|
+
puts token_node['token']
|
26
|
+
else
|
27
|
+
puts "KONTENA_URI=#{grid_uri}"
|
28
|
+
puts "KONTENA_NODE_TOKEN=#{token_node['token']}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -6,14 +6,14 @@ module Kontena::Cli::Nodes
|
|
6
6
|
include Kontena::Cli::GridOptions
|
7
7
|
include Kontena::Cli::Helpers::HealthHelper
|
8
8
|
|
9
|
-
parameter "
|
9
|
+
parameter "NODE", "Node name"
|
10
10
|
|
11
11
|
def execute
|
12
12
|
require_api_url
|
13
13
|
require_current_grid
|
14
14
|
token = require_token
|
15
15
|
|
16
|
-
node = client(token).get("nodes/#{current_grid}/#{
|
16
|
+
node = client(token).get("nodes/#{current_grid}/#{self.node}")
|
17
17
|
|
18
18
|
return show_node_health(node)
|
19
19
|
end
|
@@ -2,7 +2,7 @@ module Kontena::Cli::Nodes::Labels
|
|
2
2
|
class AddCommand < Kontena::Command
|
3
3
|
include Kontena::Cli::Common
|
4
4
|
|
5
|
-
parameter "
|
5
|
+
parameter "NODE", "Node name"
|
6
6
|
parameter "LABEL ...", "Labels"
|
7
7
|
|
8
8
|
requires_current_master
|
@@ -10,9 +10,9 @@ module Kontena::Cli::Nodes::Labels
|
|
10
10
|
requires_current_grid
|
11
11
|
|
12
12
|
def execute
|
13
|
-
node = client.get("nodes/#{current_grid}/#{
|
13
|
+
node = client.get("nodes/#{current_grid}/#{self.node}")
|
14
14
|
data = { labels: (Array(node['labels']) + label_list).uniq }
|
15
|
-
client.put("nodes/#{
|
15
|
+
client.put("nodes/#{node['id']}", data)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -2,7 +2,7 @@ module Kontena::Cli::Nodes::Labels
|
|
2
2
|
class ListCommand < Kontena::Command
|
3
3
|
include Kontena::Cli::Common
|
4
4
|
|
5
|
-
parameter "
|
5
|
+
parameter "NODE", "Node name"
|
6
6
|
|
7
7
|
# the command outputs id info only anyway, this is here strictly for ignoring purposes
|
8
8
|
option ['-q', '--quiet'], :flag, "Output the identifying column only", hidden: true
|
@@ -12,7 +12,7 @@ module Kontena::Cli::Nodes::Labels
|
|
12
12
|
requires_current_grid
|
13
13
|
|
14
14
|
def execute
|
15
|
-
node = client.get("nodes/#{current_grid}/#{
|
15
|
+
node = client.get("nodes/#{current_grid}/#{self.node}")
|
16
16
|
puts Array(node['labels']).join("\n")
|
17
17
|
end
|
18
18
|
end
|
@@ -2,7 +2,7 @@ module Kontena::Cli::Nodes::Labels
|
|
2
2
|
class RemoveCommand < Kontena::Command
|
3
3
|
include Kontena::Cli::Common
|
4
4
|
|
5
|
-
parameter "
|
5
|
+
parameter "NODE", "Node name"
|
6
6
|
parameter "LABEL ...", "Labels"
|
7
7
|
|
8
8
|
requires_current_master
|
@@ -10,9 +10,9 @@ module Kontena::Cli::Nodes::Labels
|
|
10
10
|
requires_current_grid
|
11
11
|
|
12
12
|
def execute
|
13
|
-
node = client.get("nodes/#{current_grid}/#{
|
13
|
+
node = client.get("nodes/#{current_grid}/#{self.node}")
|
14
14
|
data = { labels: Array(node['labels']).reject {|label| label_list.include?(label) } }
|
15
|
-
client.put("nodes/#{
|
15
|
+
client.put("nodes/#{node['id']}", data)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -3,7 +3,7 @@ module Kontena::Cli::Nodes
|
|
3
3
|
include Kontena::Cli::Common
|
4
4
|
include Kontena::Cli::GridOptions
|
5
5
|
|
6
|
-
parameter "
|
6
|
+
parameter "NODE", "Node name"
|
7
7
|
option "--force", :flag, "Force remove", default: false, attribute_name: :forced
|
8
8
|
|
9
9
|
def execute
|
@@ -11,16 +11,18 @@ module Kontena::Cli::Nodes
|
|
11
11
|
require_current_grid
|
12
12
|
token = require_token
|
13
13
|
|
14
|
-
node = client(token).get("nodes/#{current_grid}/#{
|
14
|
+
node = client(token).get("nodes/#{current_grid}/#{self.node}")
|
15
15
|
|
16
|
-
if node['connected']
|
17
|
-
|
16
|
+
if node['has_token'] && node['connected']
|
17
|
+
warning "Node #{node['name']} is still connected using a node token, but will be force-disconnected"
|
18
|
+
elsif node['connected']
|
19
|
+
exit_with_error "Node #{node['name']} is still connected using a grid token. You must terminate the node before removing it."
|
18
20
|
end
|
19
21
|
|
20
|
-
confirm_command(
|
22
|
+
confirm_command(self.node) unless forced?
|
21
23
|
|
22
|
-
spinner "Removing #{
|
23
|
-
client(token).delete("nodes/#{
|
24
|
+
spinner "Removing #{self.node.colorize(:cyan)} node from #{current_grid.colorize(:cyan)} grid " do
|
25
|
+
client(token).delete("nodes/#{node['id']}")
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Kontena::Cli::Nodes
|
2
|
+
class ResetTokenCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
requires_current_master
|
7
|
+
requires_current_master_token
|
8
|
+
requires_current_grid
|
9
|
+
|
10
|
+
parameter "NODE", "Node name"
|
11
|
+
|
12
|
+
option ["--token"], "TOKEN", "Use given node token instead of generating a random token"
|
13
|
+
option ["--clear-token"], :flag, "Clear node token, reverting to grid token"
|
14
|
+
option "--[no-]reset-connection", :flag, "Reset agent websocket connection", default: true
|
15
|
+
option "--force", :flag, "Force token update"
|
16
|
+
|
17
|
+
def execute
|
18
|
+
confirm("Resetting the node token will disconnect the agent (unless using --no-reset-connection), and require you to reconfigure the kontena-agent using the new `kontena node env` values before it will be able to reconnect. Are you sure?")
|
19
|
+
|
20
|
+
data = {}
|
21
|
+
|
22
|
+
data[:token] = self.token
|
23
|
+
data[:token] = '' if self.clear_token?
|
24
|
+
data[:reset_connection] = self.reset_connection?
|
25
|
+
|
26
|
+
spinner "Resetting node #{self.node.colorize(:cyan)} websocket connection token" do
|
27
|
+
client.put("nodes/#{current_grid}/#{self.node}/token", data)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -4,16 +4,16 @@ module Kontena::Cli::Nodes
|
|
4
4
|
include Kontena::Cli::GridOptions
|
5
5
|
include Kontena::Cli::BytesHelper
|
6
6
|
|
7
|
-
parameter "
|
7
|
+
parameter "NODE", "Node name"
|
8
8
|
|
9
9
|
def execute
|
10
10
|
require_api_url
|
11
11
|
require_current_grid
|
12
12
|
token = require_token
|
13
13
|
|
14
|
-
node = client(token).get("nodes/#{current_grid}/#{
|
15
|
-
puts "#{node['
|
16
|
-
puts " id: #{node['
|
14
|
+
node = client(token).get("nodes/#{current_grid}/#{self.node}")
|
15
|
+
puts "#{node['id']}:"
|
16
|
+
puts " id: #{node['node_id']}"
|
17
17
|
puts " agent version: #{node['agent_version']}"
|
18
18
|
puts " docker version: #{node['docker_version']}"
|
19
19
|
puts " connected: #{node['connected'] ? 'yes': 'no'}"
|