kontena-cli 0.7.3 → 0.8.0

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