kontena-cli 0.6.1 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd8dd1a2fac72b1e4ff7a2673d263d519bc757b0
4
- data.tar.gz: ad06dce5bdb05a6f050710fe90d861d6978cc271
3
+ metadata.gz: 95a8ffbdbff5aee91629d12bc4f3b39e01e242cf
4
+ data.tar.gz: 730864d95afd58a14b8d1e0477c292af652b34da
5
5
  SHA512:
6
- metadata.gz: 69982d2741ba6644c9fc26e697937ffc1fca9e832ea5d8181ed40cfc3c5c79c05d68613035c8e1acdfe59b79089e04a3c51b9872cea1b3f80be9ad38a1e1ee14
7
- data.tar.gz: c425be0997e31e8d84c2523ead66fbde8ba732d8155b3ea3147292051204df9182a65e6211aa80602f20c34f69333070a2a5940dd1ef274f671f890e73ebac82
6
+ metadata.gz: f0882dd73e058658b63f65066e31f188aced37c8b98bf07203a10ab92587f02dc6a1e6574c83f5b69f3b47542134b8aa7473d3ef814fa3cb5054ba7c39ec6809
7
+ data.tar.gz: 7f278890e746d3f59a2f1c262ba534ef118327a31dd75b8a22089c2aa4d566f45858428a588fab78ded50b9e25dce70cf3793357d687ff675b244c12ddbb793c
data/README.md CHANGED
@@ -10,19 +10,21 @@ Install it yourself as:
10
10
 
11
11
  $ gem install kontena-cli
12
12
 
13
- ## Usage
13
+ To enable tab-completion for bash, add this to your `.bashrc` scripts:
14
14
 
15
- First you need to connect to a Kontena server:
15
+ ```
16
+ which kontena > /dev/null && . "$( kontena whoami --bash-completion-path )"
17
+ ```
16
18
 
17
- $ kontena connect
19
+ ## Usage
18
20
 
19
- To register a new user:
21
+ First you need to register as a user:
20
22
 
21
23
  $ kontena register
22
24
 
23
- Then you can login with:
25
+ Then you can login to master server:
24
26
 
25
- $ kontena login
27
+ $ kontena login https://<master>:8080
26
28
 
27
29
  To get list of all commands:
28
30
 
@@ -17,4 +17,4 @@ require_relative 'containers/commands'
17
17
  require_relative 'grids/commands'
18
18
  require_relative 'nodes/commands'
19
19
  require_relative 'services/commands'
20
- require_relative 'stacks/commands'
20
+ require_relative 'stacks/commands'
@@ -50,7 +50,7 @@ module Kontena
50
50
  def api_url
51
51
  url = settings['server']['url']
52
52
  unless url
53
- raise ArgumentError.new("Please init service first using: kontena connect")
53
+ raise ArgumentError.new("It seem's that you are not logged into Kontena master, please login with: kontena login")
54
54
  end
55
55
  url
56
56
  end
@@ -10,7 +10,7 @@ module Kontena::Cli::Containers
10
10
  token = require_token
11
11
 
12
12
  payload = {cmd: ['sh', '-c', cmd]}
13
- result = client(token).post("containers/#{container_id}/exec", payload)
13
+ result = client(token).post("containers/#{current_grid}/#{container_id}/exec", payload)
14
14
  puts result[0].join(" ") unless result[0].size == 0
15
15
  STDERR.puts result[1].join(" ") unless result[1].size == 0
16
16
  exit result[2]
@@ -4,7 +4,8 @@ require_relative 'grids'
4
4
  require_relative 'users'
5
5
  require_relative 'audit_log'
6
6
  require_relative 'vpn'
7
-
7
+ require_relative 'registry'
8
+ require_relative 'external_registries'
8
9
 
9
10
  command 'grid list' do |c|
10
11
  c.syntax = 'kontena grid list'
@@ -52,8 +53,9 @@ end
52
53
  command 'grid create' do |c|
53
54
  c.syntax = 'kontena grid create <name>'
54
55
  c.description = 'Create a new grid'
56
+ c.option '--initial-size INTEGER', Integer, 'Initial number of nodes'
55
57
  c.action do |args, options|
56
- Kontena::Cli::Grids::Grids.new.create(args[0])
58
+ Kontena::Cli::Grids::Grids.new.create(args[0], options)
57
59
  end
58
60
  end
59
61
 
@@ -61,7 +63,7 @@ command 'grid remove' do |c|
61
63
  c.syntax = 'kontena grid remove <name>'
62
64
  c.description = 'Removes grid'
63
65
  c.action do |args, options|
64
- Kontena::Cli::Platform::Grids.new.destroy(args[0])
66
+ Kontena::Cli::Grids::Grids.new.destroy(args[0])
65
67
  end
66
68
  end
67
69
 
@@ -115,3 +117,53 @@ command 'vpn config' do |c|
115
117
  Kontena::Cli::Grids::Vpn.new.config
116
118
  end
117
119
  end
120
+
121
+ command 'registry create' do |c|
122
+ c.syntax = 'kontena registry create'
123
+ c.description = 'Create Docker Registry service'
124
+ c.option '--node STRING', String, 'Node name'
125
+ c.option '--s3-access-key STRING', String, 'S3 access key'
126
+ c.option '--s3-secret-key STRING', String, 'S3 secret key'
127
+ c.option '--s3-bucket STRING', String, 'S3 bucket'
128
+ c.option '--s3-region STRING', String, 'S3 region'
129
+ c.option '--s3-encrypt', 'S3 encrypt data'
130
+ c.option '--s3-secure', 'S3 use secure connection'
131
+ c.option '--azure-account-name STRING', String, 'Azure account name'
132
+ c.option '--azure-account-key STRING', String, 'Azure account key'
133
+ c.option '--azure-container-name STRING', String, 'Azure container name'
134
+ c.action do |args, options|
135
+ Kontena::Cli::Grids::Registry.new.create(options)
136
+ end
137
+ end
138
+
139
+ command 'registry delete' do |c|
140
+ c.syntax = 'kontena registry delete'
141
+ c.description = 'Delete Docker Registry service'
142
+ c.action do |args, options|
143
+ Kontena::Cli::Grids::Registry.new.delete
144
+ end
145
+ end
146
+
147
+ command 'external-registry add' do |c|
148
+ c.syntax = 'kontena external-registry add'
149
+ c.description = 'Add external private registry credentials'
150
+ c.action do |args, options|
151
+ Kontena::Cli::Grids::ExternalRegistries.new.add
152
+ end
153
+ end
154
+
155
+ command 'external-registry list' do |c|
156
+ c.syntax = 'kontena external-registry list'
157
+ c.description = 'List external private registries'
158
+ c.action do |args, options|
159
+ Kontena::Cli::Grids::ExternalRegistries.new.list
160
+ end
161
+ end
162
+
163
+ command 'external-registry delete' do |c|
164
+ c.syntax = 'kontena external-registry delete'
165
+ c.description = 'Delete external private registry'
166
+ c.action do |args, options|
167
+ Kontena::Cli::Grids::ExternalRegistries.new.destroy(args[0])
168
+ end
169
+ end
@@ -0,0 +1,40 @@
1
+ require 'kontena/client'
2
+ require_relative '../common'
3
+
4
+ module Kontena::Cli::Grids
5
+ class ExternalRegistries
6
+ include Kontena::Cli::Common
7
+
8
+ def add
9
+ default_url = 'https://index.docker.io/v1/'
10
+ require_api_url
11
+ require_current_grid
12
+ token = require_token
13
+
14
+ username = ask("Username: ")
15
+ password = password("Password: ")
16
+ email = ask("Email: ")
17
+ url = ask("URL [#{default_url}]: ")
18
+ url = default_url if url.strip == ''
19
+ data = { username: username, password: password, email: email, url: url }
20
+ client(token).post("grids/#{current_grid}/external_registries", data)
21
+ end
22
+
23
+ def destroy(name)
24
+ require_api_url
25
+ token = require_token
26
+ client(token).delete("external_registries/#{current_grid}/#{name}")
27
+ end
28
+
29
+ def list
30
+ require_api_url
31
+ require_current_grid
32
+ token = require_token
33
+ result = client(token).get("grids/#{current_grid}/external_registries")
34
+ puts "%-30s %-20s %-30s" % ['Name', 'Username', 'Email']
35
+ result['external_registries'].each { |r|
36
+ puts "%-30.30s %-20.20s %-30.30s" % [r['name'], r['username'], r['email']]
37
+ }
38
+ end
39
+ end
40
+ end
@@ -12,14 +12,14 @@ module Kontena::Cli::Grids
12
12
  print color("You don't have any grids yet. Create first one with 'kontena grids create' command", :yellow)
13
13
  end
14
14
 
15
- puts '%-30.30s %-10s %-10s %-10s' % ['Name', 'Nodes', 'Containers', 'Users']
15
+ puts '%-30.30s %-8s %-12s %-10s' % ['Name', 'Nodes', 'Services', 'Users']
16
16
  grids['grids'].each do |grid|
17
17
  if grid['id'] == current_grid
18
18
  name = "#{grid['name']} *"
19
19
  else
20
20
  name = grid['name']
21
21
  end
22
- puts '%-30.30s %-10s %-10s %-10s' % [name, grid['nodeCount'], grid['containerCount'], grid['userCount']]
22
+ puts '%-30.30s %-8s %-12s %-10s' % [name, grid['node_count'], grid['service_count'], grid['user_count']]
23
23
  end
24
24
  end
25
25
 
@@ -29,7 +29,7 @@ module Kontena::Cli::Grids
29
29
  grid = find_grid_by_name(name)
30
30
  if !grid.nil?
31
31
  self.current_grid = grid
32
- print color("Using #{grid['name']}", :green)
32
+ puts "Using grid: #{grid['name'].cyan}"
33
33
  else
34
34
  print color('Could not resolve grid by name. For a list of existing grids please run: kontena grid list', :red)
35
35
  end
@@ -41,41 +41,43 @@ module Kontena::Cli::Grids
41
41
 
42
42
  grid = find_grid_by_name(name)
43
43
  print_grid(grid)
44
-
45
44
  end
46
45
 
47
46
  def current
48
47
  require_api_url
49
48
  if current_grid.nil?
50
- puts 'No grid selected. To select grid, please run: kontena use <grid name>'
51
-
49
+ puts 'No grid selected. To select grid, please run: kontena grid use <grid name>'
52
50
  else
53
51
  grid = client(require_token).get("grids/#{current_grid}")
54
52
  print_grid(grid)
55
53
  end
56
54
  end
57
55
 
58
- def create(name=nil)
56
+ def create(name = nil, opts)
59
57
  require_api_url
60
58
 
61
59
  token = require_token
62
60
  payload = {
63
61
  name: name
64
62
  }
63
+ payload[:initial_size] = opts.initial_size if opts.initial_size
65
64
  grid = client(token).post('grids', payload)
66
- puts "created #{grid['name']} (#{grid['id']})" if grid
65
+ if grid
66
+ self.current_grid = grid
67
+ puts "Using grid: #{grid['name'].cyan}"
68
+ end
67
69
  end
68
70
 
69
71
  def destroy(name)
70
72
  require_api_url
71
-
73
+ token = require_token
72
74
  grid = find_grid_by_name(name)
73
75
 
74
76
  if !grid.nil?
75
77
  response = client(token).delete("grids/#{grid['id']}")
76
78
  if response
77
79
  clear_current_grid if grid['id'] == current_grid
78
- puts "removed #{grid['name']} (#{grid['id']})"
80
+ puts "removed #{grid['name'].cyan}"
79
81
  end
80
82
  else
81
83
  print color('Could not resolve grid by name. For a list of existing grids please run: kontena grid list', :red)
@@ -89,9 +91,10 @@ module Kontena::Cli::Grids
89
91
  def print_grid(grid)
90
92
  puts "#{grid['name']}:"
91
93
  puts " token: #{grid['token']}"
92
- puts " users: #{grid['userCount']}"
93
- puts " nodes: #{grid['nodeCount']}"
94
- puts " containers: #{grid['containerCount']}"
94
+ puts " users: #{grid['user_count']}"
95
+ puts " nodes: #{grid['node_count']}"
96
+ puts " services: #{grid['service_count']}"
97
+ puts " containers: #{grid['container_count']}"
95
98
  end
96
99
 
97
100
  def grids
@@ -0,0 +1,90 @@
1
+ require 'kontena/client'
2
+ require_relative '../common'
3
+
4
+ module Kontena::Cli::Grids
5
+ class Registry
6
+ include Kontena::Cli::Common
7
+
8
+ def create(opts)
9
+ require_api_url
10
+ token = require_token
11
+ preferred_node = opts.node
12
+
13
+ registry = client(token).get("services/#{current_grid}/registry") rescue nil
14
+ raise ArgumentError.new('Registry already exists') if registry
15
+
16
+ nodes = client(token).get("grids/#{current_grid}/nodes")
17
+ if preferred_node.nil?
18
+ node = nodes['nodes'].find{|n| n['connected']}
19
+ raise ArgumentError.new('Cannot find any online nodes') if node.nil?
20
+ else
21
+ node = nodes['nodes'].find{|n| n['connected'] && n['name'] == preferred_node }
22
+ raise ArgumentError.new('Node not found') if node.nil?
23
+ end
24
+
25
+ if opts.s3_access_key || opts.s3_secret_key
26
+ raise ArgumentError.new('--s3-access-key is missing') if opts.s3_access_key.nil?
27
+ raise ArgumentError.new('--s3-secret-key is missing') if opts.s3_secret_key.nil?
28
+ raise ArgumentError.new('--s3-bucket is missing') if opts.s3_bucket.nil?
29
+ s3_region = opts.s3_region || 'eu-west-1'
30
+ s3_encrypt = opts.s3_encrypt || false
31
+ s3_secure = opts.s3_secure || true
32
+ env = [
33
+ "REGISTRY_STORAGE=s3",
34
+ "REGISTRY_STORAGE_S3_ACCESSKEY=#{opts.s3_access_key}",
35
+ "REGISTRY_STORAGE_S3_SECRETKEY=#{opts.s3_secret_key}",
36
+ "REGISTRY_STORAGE_S3_REGION=#{s3_region}",
37
+ "REGISTRY_STORAGE_S3_BUCKET=#{opts.s3_bucket}",
38
+ "REGISTRY_STORAGE_S3_ENCRYPT=#{s3_encrypt}",
39
+ "REGISTRY_STORAGE_S3_SECURE=#{s3_secure}",
40
+ ]
41
+ elsif opts.azure_account_name || opts.azure_account_key
42
+ raise ArgumentError.new('--azure-account-name is missing') if opts.azure_account_name.nil?
43
+ raise ArgumentError.new('--azure-account-key is missing') if opts.azure_account_key.nil?
44
+ raise ArgumentError.new('--azure-container-name is missing') if opts.azure_container_name.nil?
45
+ env = [
46
+ "REGISTRY_STORAGE=azure",
47
+ "REGISTRY_STORAGE_AZURE_ACCOUNTNAME=#{opts.azure_account_name}",
48
+ "REGISTRY_STORAGE_AZURE_ACCOUNTKEY=#{opts.azure_account_key}",
49
+ "REGISTRY_STORAGE_AZURE_CONTAINERNAME=#{opts.azure_container_name}"
50
+ ]
51
+ else
52
+ env = [
53
+ "REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/registry"
54
+ ]
55
+ end
56
+
57
+ env << "REGISTRY_HTTP_ADDR=0.0.0.0:80"
58
+
59
+ data = {
60
+ name: 'registry',
61
+ stateful: true,
62
+ image: 'registry:2.0',
63
+ volumes: ['/registry'],
64
+ env: env,
65
+ affinity: ["node==#{node['name']}"]
66
+ }
67
+ client(token).post("grids/#{current_grid}/services", data)
68
+ result = client(token).post("services/#{current_grid}/registry/deploy", {})
69
+ print 'deploying registry service '
70
+ until client(token).get("services/#{current_grid}/registry")['state'] != 'deploying' do
71
+ print '.'
72
+ sleep 1
73
+ end
74
+ puts ' done'
75
+ puts "Docker Registry 2.0 is now running at registry.kontena.local."
76
+ puts "Note: OpenVPN connection is needed to establish connection to this registry."
77
+ puts 'Note 2: you must set "--insecure-registry 10.81.0.0/16" to your client docker daemon before you are able to push to this registry.'
78
+ end
79
+
80
+ def delete
81
+ require_api_url
82
+ token = require_token
83
+
84
+ registry = client(token).get("services/#{current_grid}/registry") rescue nil
85
+ raise ArgumentError.new("Docker Registry service does not exist") if registry.nil?
86
+
87
+ client(token).delete("services/#{current_grid}/registry")
88
+ end
89
+ end
90
+ end
@@ -10,7 +10,7 @@ module Kontena::Cli::Grids
10
10
  token = require_token
11
11
  preferred_node = opts.node
12
12
 
13
- vpn = client(token).get("services/vpn") rescue nil
13
+ vpn = client(token).get("services/#{current_grid}/vpn") rescue nil
14
14
  raise ArgumentError.new('Vpn already exists') if vpn
15
15
 
16
16
  nodes = client(token).get("grids/#{current_grid}/nodes")
@@ -40,9 +40,9 @@ module Kontena::Cli::Grids
40
40
  affinity: ["node==#{node['name']}"]
41
41
  }
42
42
  client(token).post("grids/#{current_grid}/services", data)
43
- result = client(token).post("services/vpn/deploy", {})
43
+ result = client(token).post("services/#{current_grid}/vpn/deploy", {})
44
44
  print 'deploying '
45
- until client(token).get("services/vpn")['state'] != 'deploying' do
45
+ until client(token).get("services/#{current_grid}/vpn")['state'] != 'deploying' do
46
46
  print '.'
47
47
  sleep 1
48
48
  end
@@ -55,16 +55,16 @@ module Kontena::Cli::Grids
55
55
  require_api_url
56
56
  token = require_token
57
57
 
58
- vpn = client(token).get("services/vpn") rescue nil
58
+ vpn = client(token).get("services/#{current_grid}/vpn") rescue nil
59
59
  raise ArgumentError.new("VPN service does not exist") if vpn.nil?
60
60
 
61
- client(token).delete("services/vpn")
61
+ client(token).delete("services/#{current_grid}/vpn")
62
62
  end
63
63
 
64
64
  def config
65
65
  require_api_url
66
66
  payload = {cmd: ['/usr/local/bin/ovpn_getclient', 'KONTENA_VPN_CLIENT']}
67
- stdout, stderr = client(require_token).post("containers/vpn-1/exec", payload)
67
+ stdout, stderr = client(require_token).post("containers/#{current_grid}/vpn/vpn-1/exec", payload)
68
68
  puts stdout
69
69
  end
70
70
  end
@@ -11,16 +11,16 @@ module Kontena::Cli::Nodes
11
11
  token = require_token
12
12
 
13
13
  grids = client(token).get("grids/#{current_grid}/nodes")
14
- puts "%-30s %-20s %-15s %-30s %-10s" % ['Name', 'OS', 'Driver', 'Labels', 'Status']
14
+ puts "%-30s %-40s %-15s %-30s %-10s" % ['Name', 'OS', 'Driver', 'Labels', 'Status']
15
15
  grids['nodes'].each do |node|
16
16
  if node['connected']
17
17
  status = 'online'
18
18
  else
19
19
  status = 'offline'
20
20
  end
21
- puts "%-30.30s %-20.20s %-15s %-30.30s %-10s" % [
21
+ puts "%-30.30s %-40.40s %-15s %-30.30s %-10s" % [
22
22
  node['name'],
23
- node['os'],
23
+ "#{node['os']} (#{node['kernel_version']})",
24
24
  node['driver'],
25
25
  (node['labels'] || ['-']).join(","),
26
26
  status
@@ -39,6 +39,8 @@ module Kontena::Cli::Nodes
39
39
  puts " connected: #{node['connected'] ? 'yes': 'no'}"
40
40
  puts " last connect: #{node['updated_at']}"
41
41
  puts " public ip: #{node['public_ip']}"
42
+ puts " private ip: #{node['private_ip']}"
43
+ puts " overlay network: 10.81.#{node['node_number']}.0/24"
42
44
  puts " os: #{node['os']}"
43
45
  puts " driver: #{node['driver']}"
44
46
  puts " kernel: #{node['kernel_version']}"
@@ -3,27 +3,11 @@ module Kontena::Cli::Server; end;
3
3
  require_relative 'server'
4
4
  require_relative 'user'
5
5
 
6
- command 'connect' do |c|
7
- c.syntax = 'kontena connect <url>'
8
- c.description = 'Connect to Kontena server'
9
- c.action do |args, options|
10
- Kontena::Cli::Server::Server.new.connect(args[0], options)
11
- end
12
- end
13
-
14
- command 'disconnect' do |c|
15
- c.syntax = 'kontena disconnect'
16
- c.description = 'Disconnect from Kontena server'
17
- c.action do |args, options|
18
- Kontena::Cli::Server::Server.new.disconnect
19
- end
20
- end
21
-
22
6
  command 'login' do |c|
23
7
  c.syntax = 'kontena login'
24
8
  c.description = 'Login to Kontena server'
25
9
  c.action do |args, options|
26
- Kontena::Cli::Server::User.new.login
10
+ Kontena::Cli::Server::User.new.login(args[0])
27
11
  end
28
12
  end
29
13
 
@@ -38,16 +22,17 @@ end
38
22
  command 'whoami' do |c|
39
23
  c.syntax = 'kontena whoami'
40
24
  c.description = 'Display your Kontena email address and server url'
25
+ c.option '--bash-completion-path'
41
26
  c.action do |args, options|
42
- Kontena::Cli::Server::User.new.whoami
27
+ Kontena::Cli::Server::User.new.whoami(options)
43
28
  end
44
29
  end
45
30
 
46
31
  command 'register' do |c|
47
32
  c.syntax = 'kontena register'
48
- c.description = 'Register to Kontena.io'
33
+ c.description = 'Register Kontena account. URL of auth provider can be given optionally.'
49
34
  c.action do |args, options|
50
- Kontena::Cli::Server::User.new.register
35
+ Kontena::Cli::Server::User.new.register(args[0], options)
51
36
  end
52
37
  end
53
38
 
@@ -82,11 +67,3 @@ command 'reset password' do |c|
82
67
  Kontena::Cli::Server::User.new.reset_password(args[0])
83
68
  end
84
69
  end
85
-
86
- command 'registry add' do |c|
87
- c.syntax = 'kontena registry add'
88
- c.description = 'Add registry information'
89
- c.action do |args, options|
90
- Kontena::Cli::Server::User.new.add_registry
91
- end
92
- end