kontena-cli 0.7.3 → 0.8.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/kontena +64 -2
  4. data/kontena-cli.gemspec +4 -2
  5. data/lib/kontena/cli/app_command.rb +20 -0
  6. data/lib/kontena/cli/apps/common.rb +53 -0
  7. data/lib/kontena/cli/{stacks/stacks.rb → apps/deploy_command.rb} +17 -31
  8. data/lib/kontena/cli/apps/init_command.rb +101 -0
  9. data/lib/kontena/cli/apps/list_command.rb +41 -0
  10. data/lib/kontena/cli/apps/logs_command.rb +58 -0
  11. data/lib/kontena/cli/apps/remove_command.rb +64 -0
  12. data/lib/kontena/cli/apps/start_command.rb +38 -0
  13. data/lib/kontena/cli/apps/stop_command.rb +38 -0
  14. data/lib/kontena/cli/container_command.rb +9 -0
  15. data/lib/kontena/cli/containers/{containers.rb → exec_command.rb} +5 -5
  16. data/lib/kontena/cli/deploy_command.rb +159 -0
  17. data/lib/kontena/cli/external_registries/add_command.rb +22 -0
  18. data/lib/kontena/cli/external_registries/delete_command.rb +13 -0
  19. data/lib/kontena/cli/external_registries/list_command.rb +16 -0
  20. data/lib/kontena/cli/external_registry_command.rb +14 -0
  21. data/lib/kontena/cli/forgot_password_command.rb +13 -0
  22. data/lib/kontena/cli/grid_command.rb +27 -0
  23. data/lib/kontena/cli/grids/add_user_command.rb +17 -0
  24. data/lib/kontena/cli/grids/{audit_log.rb → audit_log_command.rb} +7 -6
  25. data/lib/kontena/cli/grids/common.rb +24 -0
  26. data/lib/kontena/cli/grids/create_command.rb +26 -0
  27. data/lib/kontena/cli/grids/current_command.rb +18 -0
  28. data/lib/kontena/cli/grids/list_command.rb +26 -0
  29. data/lib/kontena/cli/grids/list_users_command.rb +18 -0
  30. data/lib/kontena/cli/grids/remove_command.rb +26 -0
  31. data/lib/kontena/cli/grids/remove_user_command.rb +16 -0
  32. data/lib/kontena/cli/grids/show_command.rb +19 -0
  33. data/lib/kontena/cli/grids/use_command.rb +21 -0
  34. data/lib/kontena/cli/invite_command.rb +13 -0
  35. data/lib/kontena/cli/login_command.rb +114 -0
  36. data/lib/kontena/cli/logout_command.rb +8 -0
  37. data/lib/kontena/cli/node_command.rb +21 -0
  38. data/lib/kontena/cli/nodes/digital_ocean/create_command.rb +31 -0
  39. data/lib/kontena/cli/nodes/digital_ocean/restart_command.rb +26 -0
  40. data/lib/kontena/cli/nodes/digital_ocean/terminate_command.rb +18 -0
  41. data/lib/kontena/cli/nodes/digital_ocean_command.rb +15 -0
  42. data/lib/kontena/cli/nodes/list_command.rb +28 -0
  43. data/lib/kontena/cli/nodes/remove_command.rb +15 -0
  44. data/lib/kontena/cli/nodes/show_command.rb +31 -0
  45. data/lib/kontena/cli/nodes/update_command.rb +18 -0
  46. data/lib/kontena/cli/nodes/vagrant/create_command.rb +26 -0
  47. data/lib/kontena/cli/nodes/vagrant/restart_command.rb +25 -0
  48. data/lib/kontena/cli/nodes/vagrant/ssh_command.rb +20 -0
  49. data/lib/kontena/cli/nodes/vagrant/start_command.rb +25 -0
  50. data/lib/kontena/cli/nodes/vagrant/stop_command.rb +25 -0
  51. data/lib/kontena/cli/nodes/vagrant/terminate_command.rb +16 -0
  52. data/lib/kontena/cli/nodes/vagrant_command.rb +21 -0
  53. data/lib/kontena/cli/register_command.rb +21 -0
  54. data/lib/kontena/cli/{grids/registry.rb → registry/create_command.rb} +32 -35
  55. data/lib/kontena/cli/registry/delete_command.rb +15 -0
  56. data/lib/kontena/cli/registry_command.rb +11 -0
  57. data/lib/kontena/cli/reset_password_command.rb +17 -0
  58. data/lib/kontena/cli/service_command.rb +33 -0
  59. data/lib/kontena/cli/services/container_command.rb +9 -0
  60. data/lib/kontena/cli/services/containers_command.rb +31 -0
  61. data/lib/kontena/cli/services/create_command.rb +62 -0
  62. data/lib/kontena/cli/services/delete_command.rb +17 -0
  63. data/lib/kontena/cli/services/deploy_command.rb +23 -0
  64. data/lib/kontena/cli/services/list_command.rb +20 -0
  65. data/lib/kontena/cli/services/logs_command.rb +51 -0
  66. data/lib/kontena/cli/services/restart_command.rb +16 -0
  67. data/lib/kontena/cli/services/scale_command.rb +20 -0
  68. data/lib/kontena/cli/services/services_helper.rb +94 -0
  69. data/lib/kontena/cli/services/show_command.rb +17 -0
  70. data/lib/kontena/cli/services/start_command.rb +16 -0
  71. data/lib/kontena/cli/services/{stats.rb → stats_command.rb} +11 -10
  72. data/lib/kontena/cli/services/stop_command.rb +16 -0
  73. data/lib/kontena/cli/services/update_command.rb +51 -0
  74. data/lib/kontena/cli/verify_account_command.rb +13 -0
  75. data/lib/kontena/cli/version_command.rb +8 -0
  76. data/lib/kontena/cli/vpn/config_command.rb +12 -0
  77. data/lib/kontena/cli/{grids/vpn.rb → vpn/create_command.rb} +12 -29
  78. data/lib/kontena/cli/vpn/delete_command.rb +15 -0
  79. data/lib/kontena/cli/vpn_command.rb +13 -0
  80. data/lib/kontena/cli/whoami_command.rb +19 -0
  81. data/lib/kontena/client.rb +14 -11
  82. data/lib/kontena/machine/common.rb +17 -0
  83. data/lib/kontena/machine/digital_ocean.rb +11 -0
  84. data/lib/kontena/machine/digital_ocean/cloudinit.yml +66 -0
  85. data/lib/kontena/machine/digital_ocean/node_destroyer.rb +38 -0
  86. data/lib/kontena/machine/digital_ocean/node_provisioner.rb +74 -0
  87. data/lib/kontena/machine/random_name.rb +42 -0
  88. data/lib/kontena/machine/vagrant.rb +10 -0
  89. data/lib/kontena/machine/vagrant/Vagrantfile.coreos.rb.erb +32 -0
  90. data/lib/kontena/machine/vagrant/cloudinit.yml +65 -0
  91. data/lib/kontena/machine/vagrant/node_destroyer.rb +36 -0
  92. data/lib/kontena/machine/vagrant/node_provisioner.rb +68 -0
  93. data/lib/kontena/scripts/completer +5 -5
  94. data/spec/kontena/cli/app/deploy_command_spec.rb +227 -0
  95. data/spec/kontena/cli/deploy_command_spec.rb +213 -0
  96. data/spec/kontena/cli/login_command_spec.rb +22 -0
  97. data/spec/kontena/cli/register_command_spec.rb +57 -0
  98. data/spec/spec_helper.rb +5 -1
  99. metadata +132 -36
  100. data/lib/kontena/cli/commands.rb +0 -20
  101. data/lib/kontena/cli/containers/commands.rb +0 -12
  102. data/lib/kontena/cli/grids/commands.rb +0 -169
  103. data/lib/kontena/cli/grids/external_registries.rb +0 -40
  104. data/lib/kontena/cli/grids/grids.rb +0 -108
  105. data/lib/kontena/cli/grids/users.rb +0 -32
  106. data/lib/kontena/cli/nodes/commands.rb +0 -27
  107. data/lib/kontena/cli/nodes/nodes.rb +0 -64
  108. data/lib/kontena/cli/server/commands.rb +0 -69
  109. data/lib/kontena/cli/server/server.rb +0 -45
  110. data/lib/kontena/cli/server/user.rb +0 -174
  111. data/lib/kontena/cli/services/commands.rb +0 -138
  112. data/lib/kontena/cli/services/containers.rb +0 -24
  113. data/lib/kontena/cli/services/logs.rb +0 -44
  114. data/lib/kontena/cli/services/services.rb +0 -175
  115. data/lib/kontena/cli/stacks/commands.rb +0 -13
  116. data/spec/kontena/cli/server/user_spec.rb +0 -59
  117. data/spec/kontena/cli/stacks/stacks_spec.rb +0 -212
@@ -0,0 +1,17 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class AddUserCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "EMAIL", "Email address"
9
+
10
+ def execute
11
+ require_api_url
12
+ token = require_token
13
+ data = { email: email }
14
+ client(token).post("grids/#{current_grid}/users", data)
15
+ end
16
+ end
17
+ end
@@ -1,20 +1,21 @@
1
- require 'kontena/client'
2
- require_relative '../common'
1
+ require_relative 'common'
3
2
 
4
3
  module Kontena::Cli::Grids
5
- class AuditLog
4
+ class AuditLogCommand < Clamp::Command
6
5
  include Kontena::Cli::Common
6
+ include Common
7
7
 
8
- def show(options)
8
+ option ["-l", "--lines"], "LINES", "Number of lines"
9
+
10
+ def execute
9
11
  require_api_url
10
12
  require_current_grid
11
13
  token = require_token
12
- audit_logs = client(token).get("grids/#{current_grid}/audit_log", {limit: options.limit})
14
+ audit_logs = client(token).get("grids/#{current_grid}/audit_log", {limit: lines})
13
15
  puts '%-30.30s %-10s %-15s %-25s %-15s %-25s %-15s %-15s' % ['Time', 'Grid', 'Resource Type', 'Resource Name', 'Event Name', 'User', 'Source IP', 'User-Agent']
14
16
  audit_logs['logs'].each do |log|
15
17
  puts '%-30.30s %-10s %-15s %-25s %-15s %-25s %-15s %-15s' % [ log['time'], log['grid'], log['resource_type'], log['resource_name'], log['event_name'], log['user_identity']['email'], log['source_ip'], log['user_agent']]
16
18
  end
17
-
18
19
  end
19
20
  end
20
21
  end
@@ -0,0 +1,24 @@
1
+ module Kontena::Cli::Grids
2
+ module Common
3
+
4
+ ##
5
+ # @param [Hash] grid
6
+ def print_grid(grid)
7
+ puts "#{grid['name']}:"
8
+ puts " uri: #{settings['server']['url'].sub('http', 'ws')}"
9
+ puts " token: #{grid['token']}"
10
+ puts " users: #{grid['user_count']}"
11
+ puts " nodes: #{grid['node_count']}"
12
+ puts " services: #{grid['service_count']}"
13
+ puts " containers: #{grid['container_count']}"
14
+ end
15
+
16
+ def grids
17
+ @grids ||= client(require_token).get('grids')
18
+ end
19
+
20
+ def find_grid_by_name(name)
21
+ grids['grids'].find {|grid| grid['name'] == name }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class CreateCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name"
9
+ option "--initial-size", "INITIAL_SIZE", "Initial grid size (number of nodes)", default: 1
10
+
11
+ def execute
12
+ require_api_url
13
+
14
+ token = require_token
15
+ payload = {
16
+ name: name
17
+ }
18
+ payload[:initial_size] = initial_size if initial_size
19
+ grid = client(token).post('grids', payload)
20
+ if grid
21
+ self.current_grid = grid
22
+ puts "Using grid: #{grid['name'].cyan}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class CurrentCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ def execute
9
+ require_api_url
10
+ if current_grid.nil?
11
+ abort 'No grid selected. To select grid, please run: kontena grid use <grid name>'
12
+ else
13
+ grid = client(require_token).get("grids/#{current_grid}")
14
+ print_grid(grid)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class ListCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ def execute
9
+ require_api_url
10
+
11
+ if grids['grids'].size == 0
12
+ puts "You don't have any grids yet. Create first one with 'kontena grids create' command".colorize(:yellow)
13
+ end
14
+
15
+ puts '%-30.30s %-8s %-12s %-10s' % ['Name', 'Nodes', 'Services', 'Users']
16
+ grids['grids'].each do |grid|
17
+ if grid['id'] == current_grid
18
+ name = "#{grid['name']} *"
19
+ else
20
+ name = grid['name']
21
+ end
22
+ puts '%-30.30s %-8s %-12s %-10s' % [name, grid['node_count'], grid['service_count'], grid['user_count']]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class ListUsersCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ def execute
9
+ require_api_url
10
+ token = require_token
11
+ result = client(token).get("grids/#{current_grid}/users")
12
+ puts "%-40s %-40s" % ['Email', 'Name']
13
+ result['users'].each { |user|
14
+ puts "%-40.40s %-40.40s" % [user['email'], user['name']]
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class RemoveCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name"
9
+
10
+ def execute
11
+ require_api_url
12
+ token = require_token
13
+ grid = find_grid_by_name(name)
14
+
15
+ if !grid.nil?
16
+ response = client(token).delete("grids/#{grid['id']}")
17
+ if response
18
+ clear_current_grid if grid['id'] == current_grid
19
+ puts "removed #{grid['name'].cyan}"
20
+ end
21
+ else
22
+ abort "Could not resolve grid by name [#{name}]. For a list of existing grids please run: kontena grid list".colorize(:red)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class RemoveUserCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "EMAIL", "Email address"
9
+
10
+ def execute
11
+ require_api_url
12
+ token = require_token
13
+ result = client(token).delete("grids/#{current_grid}/users/#{email}")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class ShowCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name"
9
+
10
+ def execute
11
+ require_api_url
12
+
13
+ grid = find_grid_by_name(name)
14
+ abort("Grid not found".colorize(:red)) unless grid
15
+
16
+ print_grid(grid)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Grids
4
+ class UseCommand < Clamp::Command
5
+ include Kontena::Cli::Common
6
+ include Common
7
+
8
+ parameter "NAME", "Grid name to use"
9
+
10
+ def execute
11
+ require_api_url
12
+ grid = find_grid_by_name(name)
13
+ if !grid.nil?
14
+ self.current_grid = grid
15
+ puts "Using grid: #{grid['name'].cyan}"
16
+ else
17
+ abort "Could not resolve grid by name [#{name}]. For a list of existing grids please run: kontena grid list".colorize(:red)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ class Kontena::Cli::InviteCommand < Clamp::Command
2
+ include Kontena::Cli::Common
3
+
4
+ parameter "EMAIL", "Invited email"
5
+
6
+ def execute
7
+ require_api_url
8
+ token = require_token
9
+ data = { email: email }
10
+ response = client(token).post('users', data)
11
+ puts 'User invited' if response
12
+ end
13
+ end
@@ -0,0 +1,114 @@
1
+ class Kontena::Cli::LoginCommand < Clamp::Command
2
+ include Kontena::Cli::Common
3
+
4
+ parameter "URL", "Kontena Master URI"
5
+
6
+ def execute
7
+ require 'highline/import'
8
+
9
+ until !url.nil? && !url.empty?
10
+ api_url = ask('Kontena Master Node URL: ')
11
+ end
12
+ update_api_url(url)
13
+
14
+ unless request_server_info
15
+ puts 'Could not connect to server'.colorize(:red)
16
+ return false
17
+ end
18
+
19
+ email = ask("Email: ")
20
+ password = ask("Password: ") { |q| q.echo = "*" }
21
+ response = do_login(email, password)
22
+
23
+ if response
24
+ update_access_token(response['access_token'])
25
+ display_logo
26
+ puts ''
27
+ puts "Logged in as #{response['user']['name'].green}"
28
+ reset_client
29
+ grids = client(require_token).get('grids')['grids']
30
+ grid = grids[0]
31
+ if grid
32
+ self.current_grid = grid
33
+ puts "Using grid #{grid['name'].cyan}"
34
+ puts ""
35
+ if grids.size > 1
36
+ puts "You have access to following grids and can switch between them using 'kontena grid use <name>'"
37
+ puts ""
38
+ grids.each do |grid|
39
+ puts " * #{grid['name']}"
40
+ end
41
+ puts ""
42
+ end
43
+ else
44
+ clear_current_grid
45
+ end
46
+
47
+ puts "Welcome! See 'kontena --help' to get started."
48
+ true
49
+ else
50
+ puts 'Login Failed'.colorize(:red)
51
+ false
52
+ end
53
+ end
54
+
55
+ def do_login(email, password)
56
+ params = {
57
+ username: email,
58
+ password: password,
59
+ grant_type: 'password',
60
+ scope: 'user'
61
+ }
62
+ client.post('auth', params)
63
+ end
64
+
65
+ def request_server_info
66
+ valid = true
67
+ begin
68
+ client.get('ping') # test server connection
69
+ rescue Excon::Errors::SocketError => exc
70
+ if exc.message.include?('Unable to verify certificate')
71
+ puts "The server uses a certificate signed by an unknown authority.".colorize(:red)
72
+ puts "Protip: you can bypass the certificate check by setting #{'SSL_IGNORE_ERRORS=true'.colorize(:yellow)} env variable, but any data you send to the server could be intercepted by others."
73
+ exit(1)
74
+ else
75
+ valid = false
76
+ end
77
+ rescue => exc
78
+ valid = false
79
+ end
80
+ valid
81
+ end
82
+
83
+ ##
84
+ # Store api_url to config file
85
+ #
86
+ # @param [String] api_url
87
+ def update_api_url(api_url)
88
+ settings['server']['url'] = api_url
89
+ save_settings
90
+ end
91
+
92
+ ##
93
+ # Store access token to config file
94
+ #
95
+ # @param [String] access_token
96
+ def update_access_token(access_token)
97
+ settings['server']['token'] = access_token
98
+ save_settings
99
+ end
100
+
101
+ def display_logo
102
+ logo = <<LOGO
103
+ _ _
104
+ | | _____ _ __ | |_ ___ _ __ __ _
105
+ | |/ / _ \\| '_ \\| __/ _ \\ '_ \\ / _` |
106
+ | < (_) | | | | || __/ | | | (_| |
107
+ |_|\\_\\___/|_| |_|\\__\\___|_| |_|\\__,_|
108
+ -------------------------------------
109
+ Copyright (c)2015 Kontena, Inc.
110
+ LOGO
111
+ puts logo
112
+ end
113
+
114
+ end
@@ -0,0 +1,8 @@
1
+ class Kontena::Cli::LogoutCommand < Clamp::Command
2
+ include Kontena::Cli::Common
3
+
4
+ def execute
5
+ settings['server'].delete('token')
6
+ save_settings
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'nodes/list_command'
2
+ require_relative 'nodes/remove_command'
3
+ require_relative 'nodes/show_command'
4
+ require_relative 'nodes/update_command'
5
+
6
+ require_relative 'nodes/vagrant_command'
7
+ require_relative 'nodes/digital_ocean_command'
8
+
9
+ class Kontena::Cli::NodeCommand < Clamp::Command
10
+
11
+ subcommand "list", "List grid nodes", Kontena::Cli::Nodes::ListCommand
12
+ subcommand "show", "Show node", Kontena::Cli::Nodes::ShowCommand
13
+ subcommand "update", "Update node", Kontena::Cli::Nodes::UpdateCommand
14
+ subcommand "remove", "Remove node", Kontena::Cli::Nodes::RemoveCommand
15
+
16
+ subcommand "vagrant", "Vagrant specific commands", Kontena::Cli::Nodes::VagrantCommand
17
+ subcommand "digitalocean", "DigitalOcean specific commands", Kontena::Cli::Nodes::DigitalOceanCommand
18
+
19
+ def execute
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module Kontena::Cli::Nodes::DigitalOcean
2
+ class CreateCommand < Clamp::Command
3
+ include Kontena::Cli::Common
4
+
5
+ option "--name", "NAME", "Node name"
6
+ option "--token", "TOKEN", "DigitalOcean API token", required: true
7
+ option "--ssh-key", "SSH_KEY", "Path to ssh public key", required: true
8
+ option "--size", "SIZE", "Droplet size", default: '1gb'
9
+ option "--region", "REGION", "Region", default: 'ams2'
10
+ option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
11
+
12
+ def execute
13
+ require_api_url
14
+ require_current_grid
15
+
16
+ require 'kontena/machine/digital_ocean'
17
+ grid = client(require_token).get("grids/#{current_grid}")
18
+ provisioner = Kontena::Machine::DigitalOcean::NodeProvisioner.new(client(require_token), token)
19
+ provisioner.run!(
20
+ master_uri: api_url,
21
+ grid_token: grid['token'],
22
+ grid: current_grid,
23
+ ssh_key: ssh_key,
24
+ name: name,
25
+ size: size,
26
+ region: region,
27
+ version: version
28
+ )
29
+ end
30
+ end
31
+ end