kontena-cli 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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