kontena-plugin-upcloud 0.3.0 → 0.3.1.rc1

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: 2c4c7355ad5cb678eae3164eab3d4e7a431737b0
4
- data.tar.gz: f2cacd22c569d7f9c71ea3dbfa10d54d385dc36a
3
+ metadata.gz: aa71abdd5e6d879f8868bfb1e14f669a5879d197
4
+ data.tar.gz: 35cd56ca6f880a201813cfc4ed2724c01a84cbd8
5
5
  SHA512:
6
- metadata.gz: 6ab242dc67aa75f27f53bae70f0c2cd1ccebc5d139e286ffdb725950a074982b6c45fef817d33f7cd6e21abb030595971f45461d2c57785732ffe2777f73ef84
7
- data.tar.gz: 7ea9fb517948d7225fe869a542fcc0e7b742f1695f1147cb3846784c780384d6bf1318e17e8bb25bbf1c6cf0e0c15ee5938bac92a10279e22ede1a70d7b83138
6
+ metadata.gz: 5c82aabaaa2c8b6f97d0ad708590e67178aede22b22955d8e1aa7c4320951b7c3b1ea730dafc7a019bb7176aed4f46905439685a4837be72bc8551d2d60fa8a3
7
+ data.tar.gz: 0791e9666f8b9fad40fb3b6558046b1c4cbd0004cc0fc5e9772f841db61aa33c5b22356a1d6e7e13d6c770a4ab897459ba2834c10d190fe202c93e06feea3082
@@ -0,0 +1,92 @@
1
+ require 'excon'
2
+ require 'json'
3
+
4
+ module Kontena
5
+ module Machine
6
+ module Upcloud
7
+ class Client
8
+
9
+ API_URL = 'https://api.upcloud.com'.freeze
10
+ ACCEPT = 'Accept'.freeze
11
+ CTYPE = 'Content-Type'.freeze
12
+ APP_JSON = 'application/json'.freeze
13
+ CTYPE_HEAD = { CTYPE => APP_JSON }
14
+
15
+ attr_reader :http_client
16
+
17
+ def initialize(username, password)
18
+ @http_client = Excon.new(
19
+ API_URL,
20
+ omit_default_port: true,
21
+ user: username,
22
+ password: password,
23
+ )
24
+ end
25
+
26
+ def get(path)
27
+ request(method: :get, path: path)
28
+ end
29
+
30
+ def post(path, body)
31
+ request(method: :post, path: path, body: body, headers: CTYPE_HEAD)
32
+ end
33
+
34
+ def delete(path)
35
+ request(method: :delete, path: path)
36
+ end
37
+
38
+ def find_template(name)
39
+ get('storage/template')[:storages][:storage].find{|s| s[:title].downcase.start_with?(name.downcase)}
40
+ end
41
+
42
+ def find_plan(name)
43
+ list_plans.find{|s| s[:name].downcase.eql?(name.downcase)}
44
+ end
45
+
46
+ def list_plans
47
+ get('plan')[:plans][:plan]
48
+ end
49
+
50
+ def list_zones
51
+ get('zone')[:zones][:zone]
52
+ end
53
+
54
+ def zone_exist?(name)
55
+ list_zones.any? { |zone| zone[:id] == name }
56
+ end
57
+
58
+ def get_server(id)
59
+ get("server/#{id}").fetch(:server, nil)
60
+ end
61
+
62
+ def api_access?
63
+ response = get('account')
64
+ response.kind_of?(Hash) && response.has_key?(:account)
65
+ rescue
66
+ false
67
+ end
68
+
69
+ private
70
+
71
+ def request(opts)
72
+ response = http_client.request(
73
+ opts.merge(
74
+ path: "/1.2/#{opts[:path]}",
75
+ headers: (opts[:headers] || {}).merge(ACCEPT => APP_JSON),
76
+ )
77
+ )
78
+
79
+ if (200..299).cover?(response.status)
80
+ if response.body && response.body.start_with?('{'.freeze)
81
+ JSON.parse(response.body, symbolize_names: true)
82
+ else
83
+ { success: true }
84
+ end
85
+ else
86
+ raise "Request to Upcloud failed: #{response.status} #{response.body}"
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -9,23 +9,17 @@ module Kontena
9
9
  class MasterProvisioner
10
10
  include RandomName
11
11
  include Machine::CertHelper
12
- include UpcloudCommon
13
12
  include Kontena::Cli::Common
14
13
 
15
- attr_reader :http_client, :username, :password
14
+ attr_reader :http_client, :uc_client
16
15
 
17
16
  # @param [String] token Upcloud token
18
17
  def initialize(upcloud_username, upcloud_password)
19
- @username = upcloud_username
20
- @password = upcloud_password
18
+ @uc_client = Kontena::Machine::Upcloud::Client.new(upcloud_username, upcloud_password)
21
19
  end
22
20
 
23
21
  def run!(opts)
24
- if File.readable?(File.expand_path(opts[:ssh_key]))
25
- ssh_key = File.read(File.expand_path(opts[:ssh_key])).strip
26
- end
27
-
28
- abort('Invalid ssh key') unless ssh_key && ssh_key.start_with?('ssh-')
22
+ abort('Invalid ssh key') unless opts[:ssh_key].to_s.start_with?('ssh-')
29
23
 
30
24
  if opts[:ssl_cert]
31
25
  abort('Invalid ssl cert') unless File.exists?(File.expand_path(opts[:ssl_cert]))
@@ -36,11 +30,9 @@ module Kontena
36
30
  end
37
31
  end
38
32
 
39
- abort_unless_api_access
40
-
41
- abort('CoreOS template not found on Upcloud') unless coreos_template = find_template('CoreOS Stable')
42
- abort('Server plan not found on Upcloud') unless plan = find_plan(opts[:plan])
43
- abort('Zone not found on Upcloud') unless zone_exist?(opts[:zone])
33
+ abort('CoreOS template not found on Upcloud') unless coreos_template = uc_client.find_template('CoreOS Stable')
34
+ abort('Server plan not found on Upcloud') unless plan = uc_client.find_plan(opts[:plan])
35
+ abort('Zone not found on Upcloud') unless uc_client.zone_exist?(opts[:zone])
44
36
 
45
37
  if opts[:name]
46
38
  server_name = opts[:name]
@@ -61,7 +53,7 @@ module Kontena
61
53
  device_data = {
62
54
  server: {
63
55
  zone: opts[:zone],
64
- title: server_name,
56
+ title: hostname,
65
57
  hostname: hostname,
66
58
  plan: plan[:name],
67
59
  vnc: 'off',
@@ -83,21 +75,21 @@ module Kontena
83
75
  create_password: 'no',
84
76
  username: 'root',
85
77
  ssh_keys: {
86
- ssh_key: [ssh_key]
78
+ ssh_key: [opts[:ssh_key]]
87
79
  }
88
80
  }
89
81
  }
90
82
  }.to_json
91
83
 
92
84
  spinner "Creating an Upcloud server #{hostname.colorize(:cyan)} " do
93
- response = post('server', body: device_data)
85
+ response = uc_client.post('server', device_data)
94
86
  if response.has_key?(:error)
95
87
  abort("\nUpcloud server creation failed (#{response[:error].fetch(:error_message, '')})")
96
88
  end
97
89
  device_data = response[:server]
98
90
 
99
91
  until device_data && device_data.fetch(:state, nil).to_s == 'maintenance'
100
- device_data = get("server/#{device[:uuid]}").fetch(:server, {}) rescue nil
92
+ device_data = uc_client.get("server/#{device[:uuid]}").fetch(:server, {}) rescue nil
101
93
  sleep 5
102
94
  end
103
95
  end
@@ -128,7 +120,8 @@ module Kontena
128
120
  public_ip: device_public_ip[:address],
129
121
  provider: 'upcloud',
130
122
  version: master_version,
131
- code: opts[:initial_admin_code]
123
+ code: opts[:initial_admin_code],
124
+ ssl_certificate: (respond_to?(:certificate_public_key) && !opts[:ssl_cert]) ? certificate_public_key(ssl_cert) : nil
132
125
  }
133
126
  end
134
127
 
@@ -3,24 +3,20 @@ module Kontena
3
3
  module Upcloud
4
4
  class NodeDestroyer
5
5
  include RandomName
6
- include UpcloudCommon
7
6
  include Kontena::Cli::ShellSpinner
8
7
 
9
- attr_reader :api_client, :username, :password
8
+ attr_reader :api_client, :uc_client
10
9
 
11
10
  # @param [Kontena::Client] api_client Kontena api client
12
11
  # @param [String] token Upcloud token
13
12
  def initialize(api_client, upcloud_username, upcloud_password)
14
13
  @api_client = api_client
15
- @username = upcloud_username
16
- @password = upcloud_password
14
+ @uc_client = Kontena::Machine::Upcloud::Client.new(upcloud_username, upcloud_password)
17
15
  end
18
16
 
19
17
  def run!(grid, name)
20
18
 
21
- abort_unless_api_access
22
-
23
- servers = get('server')
19
+ servers = uc_client.get('server')
24
20
  unless servers && servers.has_key?(:servers)
25
21
  abort('Upcloud API error')
26
22
  end
@@ -29,7 +25,7 @@ module Kontena
29
25
 
30
26
  abort "Cannot find node #{name.colorize(:cyan)} in UpCloud" unless server
31
27
 
32
- server_data = get("server/#{server[:uuid]}")
28
+ server_data = uc_client.get("server/#{server[:uuid]}")
33
29
 
34
30
  storage_devices = server_data.fetch(:server, {}).fetch(:storage_devices, {}).fetch(:storage_device, [])
35
31
  storage_uuids = storage_devices.map{|s| s[:storage]}
@@ -39,8 +35,8 @@ module Kontena
39
35
  if server
40
36
  unless server[:state].eql?('stopped')
41
37
  spinner "Shutting down UpCloud node #{name.colorize(:cyan)} " do
42
- device_data = post(
43
- "server/#{server[:uuid]}/stop", body: {
38
+ device_data = uc_client.post(
39
+ "server/#{server[:uuid]}/stop", {
44
40
  stop_server: {
45
41
  stop_type: 'soft',
46
42
  timeout: 120
@@ -49,20 +45,20 @@ module Kontena
49
45
  )
50
46
 
51
47
  until device_data && device_data.fetch(:state, nil).to_s.eql?('stopped')
52
- device_data = get("server/#{server[:uuid]}").fetch(:server, {}) rescue nil
48
+ device_data = uc_client.get("server/#{server[:uuid]}").fetch(:server, {}) rescue nil
53
49
  sleep 5
54
50
  end
55
51
  end
56
52
  end
57
53
 
58
54
  spinner "Terminating UpCloud node #{name.colorize(:cyan)} " do
59
- response = delete("server/#{server[:uuid]}")
55
+ response = uc_client.delete("server/#{server[:uuid]}")
60
56
  abort "Cannot delete node #{name.colorize(:cyan)} in Upcloud" unless response[:success]
61
57
  end
62
58
 
63
59
  storage_uuids.each do |uuid|
64
60
  spinner "Deleting UpCloud storage device '#{uuid.colorize(:cyan)}' " do
65
- response = delete("storage/#{uuid}")
61
+ response = uc_client.delete("storage/#{uuid}")
66
62
  unless response[:success]
67
63
  puts "#{"WARNING".colorize(:red)}: Couldn't delete UpCloud storage '#{uuid.colorize(:cyan)}', check manually."
68
64
  end
@@ -7,26 +7,20 @@ module Kontena
7
7
  module Upcloud
8
8
  class NodeProvisioner
9
9
  include RandomName
10
- include UpcloudCommon
11
10
  include Kontena::Cli::ShellSpinner
12
11
 
13
- attr_reader :api_client, :username, :password
12
+ attr_reader :api_client, :uc_client
14
13
 
15
14
  # @param [Kontena::Client] api_client Kontena api client
16
15
  # @param [String] upcloud_username Upcloud username
17
16
  # @param [String] upcloud_password Upcloud password
18
17
  def initialize(api_client, upcloud_username, upcloud_password)
19
18
  @api_client = api_client
20
- @username = upcloud_username
21
- @password = upcloud_password
19
+ @uc_client = Kontena::Machine::Upcloud::Client.new(upcloud_username, upcloud_password)
22
20
  end
23
21
 
24
22
  def run!(opts)
25
- if File.readable?(File.expand_path(opts[:ssh_key]))
26
- ssh_key = File.read(File.expand_path(opts[:ssh_key])).strip
27
- end
28
-
29
- abort('Invalid ssh key') unless ssh_key && ssh_key.start_with?('ssh-')
23
+ abort('Invalid ssh key') unless opts[:ssh_key].to_s.start_with?('ssh-')
30
24
 
31
25
  count = opts[:count].to_i
32
26
  userdata_vars = {
@@ -35,11 +29,9 @@ module Kontena
35
29
  grid_token: opts[:grid_token],
36
30
  }
37
31
 
38
- abort_unless_api_access
39
-
40
- abort('CoreOS template not found on Upcloud') unless coreos_template = find_template('CoreOS Stable')
41
- abort('Server plan not found on Upcloud') unless plan = find_plan(opts[:plan])
42
- abort('Zone not found on Upcloud') unless zone_exist?(opts[:zone])
32
+ abort('CoreOS template not found on Upcloud') unless coreos_template = uc_client.find_template('CoreOS Stable')
33
+ abort('Server plan not found on Upcloud') unless plan = uc_client.find_plan(opts[:plan])
34
+ abort('Zone not found on Upcloud') unless uc_client.zone_exist?(opts[:zone])
43
35
 
44
36
  count.times do |i|
45
37
  if opts[:name]
@@ -72,14 +64,14 @@ module Kontena
72
64
  create_password: 'no',
73
65
  username: 'root',
74
66
  ssh_keys: {
75
- ssh_key: [ssh_key]
67
+ ssh_key: [opts[:ssh_key]]
76
68
  }
77
69
  }
78
70
  }
79
71
  }.to_json
80
72
 
81
73
  spinner "Creating UpCloud node #{hostname.colorize(:cyan)} " do
82
- response = post('server', body: device_data)
74
+ response = uc_client.post('server', device_data)
83
75
 
84
76
  if response.has_key?(:error)
85
77
  abort("\nUpCloud server creation failed (#{response[:error].fetch(:error_message, '')})")
@@ -87,7 +79,7 @@ module Kontena
87
79
  device_data = response[:server]
88
80
 
89
81
  until device_data && device_data.fetch(:state, nil).to_s == 'maintenance'
90
- device_data = get("server/#{device[:uuid]}").fetch(:server, {}) rescue nil
82
+ device_data = uc_client.get("server/#{device[:uuid]}").fetch(:server, {}) rescue nil
91
83
  sleep 5
92
84
  end
93
85
  end
@@ -3,22 +3,19 @@ module Kontena
3
3
  module Upcloud
4
4
  class NodeRestarter
5
5
  include RandomName
6
- include UpcloudCommon
7
6
  include Kontena::Cli::ShellSpinner
8
7
 
9
- attr_reader :username, :password
8
+ attr_reader :uc_client
10
9
 
11
10
  # @param [String] upcloud_username Upcloud username
12
11
  # @param [String] upcloud_password Upcloud password
13
12
  def initialize(upcloud_username, upcloud_password)
14
- @username = upcloud_username
15
- @password = upcloud_password
13
+ @uc_client = Kontena::Machine::Upcloud::Client.new(upcloud_username, upcloud_password)
16
14
  end
17
15
 
18
16
  def run!(name)
19
- abort_unless_api_access
20
17
 
21
- servers = get('server')
18
+ servers = uc_client.get('server')
22
19
  unless servers && servers.has_key?(:servers)
23
20
  abort('Upcloud API error')
24
21
  end
@@ -27,8 +24,8 @@ module Kontena
27
24
 
28
25
  if server
29
26
  spinner "Restarting UpCloud node #{name.colorize(:cyan)} " do
30
- result = post(
31
- "server/#{server[:uuid]}/restart", body: {
27
+ result = uc_client.post(
28
+ "server/#{server[:uuid]}/restart", {
32
29
  restart_server: {
33
30
  stop_type: 'soft',
34
31
  timeout: 600,
@@ -1,6 +1,6 @@
1
1
  require 'kontena/machine/random_name'
2
2
  require 'kontena/machine/cert_helper'
3
- require_relative 'upcloud/upcloud_common'
3
+ require_relative 'upcloud/client'
4
4
  require_relative 'upcloud/node_provisioner'
5
5
  require_relative 'upcloud/node_destroyer'
6
6
  require_relative 'upcloud/node_restarter'
@@ -1,24 +1,24 @@
1
1
  require 'securerandom'
2
+ require 'kontena/plugin/upcloud/prompts'
2
3
 
3
4
  module Kontena::Plugin::Upcloud::Master
4
5
  class CreateCommand < Kontena::Command
5
6
  include Kontena::Cli::Common
6
7
 
7
8
  option "--name", "[NAME]", "Set Kontena Master name"
8
- option "--username", "USER", "Upcloud username", required: true, environment_variable: 'UPCLOUD_USERNAME'
9
- option "--password", "PASS", "Upcloud password", required: true, environment_variable: 'UPCLOUD_PASSWORD'
10
- option "--ssh-key", "SSH_KEY", "Path to ssh public key", default: '~/.ssh/id_rsa.pub'
9
+
10
+ include Kontena::Plugin::Upcloud::Prompts::Create
11
+
11
12
  option "--ssl-cert", "SSL CERT", "SSL certificate file (optional)"
12
- option "--plan", "PLAN", "Server plan", required: true
13
- option "--zone", "ZONE", "Zone", required: true
14
13
  option "--vault-secret", "VAULT_SECRET", "Secret key for Vault (optional)"
15
14
  option "--vault-iv", "VAULT_IV", "Initialization vector for Vault (optional)"
16
15
  option "--mongodb-uri", "URI", "External MongoDB uri (optional)"
17
- option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
18
16
 
19
17
  def execute
20
18
  require_relative '../../../machine/upcloud'
21
19
 
20
+ abort_unless_api_access
21
+
22
22
  provisioner.run!(
23
23
  name: self.name,
24
24
  ssh_key: ssh_key,
@@ -36,29 +36,5 @@ module Kontena::Plugin::Upcloud::Master
36
36
  def provisioner
37
37
  Kontena::Machine::Upcloud::MasterProvisioner.new(username, password)
38
38
  end
39
-
40
- def default_username
41
- prompt.ask('UpCloud username:', echo: true)
42
- end
43
-
44
- def default_password
45
- prompt.ask('UpCloud password:', echo: false)
46
- end
47
-
48
- def default_plan
49
- prompt.select("Choose plan:") do |menu|
50
- Kontena::Plugin::Upcloud::PLANS.each do |plan, name|
51
- menu.choice name, plan
52
- end
53
- end
54
- end
55
-
56
- def default_zone
57
- prompt.select("Choose availability zone:") do |menu|
58
- Kontena::Plugin::Upcloud::ZONES.each do |zone, name|
59
- menu.choice name, zone
60
- end
61
- end
62
- end
63
39
  end
64
40
  end
@@ -1,21 +1,23 @@
1
+ require 'kontena/plugin/upcloud/prompts'
2
+
1
3
  module Kontena::Plugin::Upcloud::Nodes
2
4
  class CreateCommand < Kontena::Command
3
5
  include Kontena::Cli::Common
4
6
  include Kontena::Cli::GridOptions
5
7
 
6
8
  parameter "[NAME]", "Node name"
7
- option "--username", "USER", "Upcloud username", required: true, environment_variable: 'UPCLOUD_USERNAME'
8
- option "--password", "PASS", "Upcloud password", required: true, environment_variable: 'UPCLOUD_PASSWORD'
9
- option "--ssh-key", "SSH_KEY", "Path to ssh public key", default: '~/.ssh/id_rsa.pub'
9
+
10
+ include Kontena::Plugin::Upcloud::Prompts::Create
11
+
10
12
  option "--count", "COUNT", "How many nodes should be created"
11
- option "--zone", "ZONE", "Zone", required: true
12
- option "--plan", "PLAN", "Server size", required: true
13
- option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
14
13
 
15
14
  requires_current_master_token
16
15
 
17
16
  def execute
18
17
  require_relative '../../../machine/upcloud'
18
+
19
+ abort_unless_api_access
20
+
19
21
  grid = fetch_grid
20
22
  provisioner = Kontena::Machine::Upcloud::NodeProvisioner.new(client, username, password)
21
23
  provisioner.run!(
@@ -37,33 +39,8 @@ module Kontena::Plugin::Upcloud::Nodes
37
39
  client.get("grids/#{current_grid}")
38
40
  end
39
41
 
40
-
41
- def default_username
42
- prompt.ask('UpCloud username:', echo: true)
43
- end
44
-
45
- def default_password
46
- prompt.ask('UpCloud password:', echo: false)
47
- end
48
-
49
42
  def default_count
50
43
  prompt.ask('How many servers:', default: 1)
51
44
  end
52
-
53
- def default_plan
54
- prompt.select("Choose plan:") do |menu|
55
- Kontena::Plugin::Upcloud::PLANS.each do |plan, name|
56
- menu.choice name, plan
57
- end
58
- end
59
- end
60
-
61
- def default_zone
62
- prompt.select("Choose availability zone:") do |menu|
63
- Kontena::Plugin::Upcloud::ZONES.each do |zone, name|
64
- menu.choice name, zone
65
- end
66
- end
67
- end
68
45
  end
69
46
  end
@@ -1,16 +1,19 @@
1
+ require 'kontena/plugin/upcloud/prompts'
2
+
1
3
  module Kontena::Plugin::Upcloud::Nodes
2
4
  class RestartCommand < Kontena::Command
3
5
  include Kontena::Cli::Common
4
6
  include Kontena::Cli::GridOptions
5
7
 
6
- parameter "NAME", "Node name"
7
- option "--username", "USER", "Upcloud username", required: true, environment_variable: 'UPCLOUD_USERNAME'
8
- option "--password", "PASS", "Upcloud password", required: true, environment_variable: 'UPCLOUD_PASSWORD'
8
+ include Kontena::Plugin::Upcloud::Prompts::NodeName
9
+ include Kontena::Plugin::Upcloud::Prompts::Common
9
10
 
10
11
  def execute
11
12
  require_api_url
12
13
  require_current_grid
13
14
 
15
+ abort_unless_api_access
16
+
14
17
  require 'kontena/machine/upcloud'
15
18
 
16
19
  restarter = Kontena::Machine::Upcloud::NodeRestarter.new(username, password)
@@ -1,17 +1,18 @@
1
+ require 'kontena/plugin/upcloud/prompts'
1
2
  module Kontena::Plugin::Upcloud::Nodes
2
3
  class TerminateCommand < Kontena::Command
3
4
  include Kontena::Cli::Common
4
5
  include Kontena::Cli::GridOptions
5
6
 
6
- parameter "[NAME]", "Node name"
7
- option "--username", "USER", "Upcloud username", required: true, environment_variable: 'UPCLOUD_USERNAME'
8
- option "--password", "PASS", "Upcloud password", required: true, environment_variable: 'UPCLOUD_PASSWORD'
7
+ include Kontena::Plugin::Upcloud::Prompts::NodeName
8
+ include Kontena::Plugin::Upcloud::Prompts::Common
9
9
 
10
10
  option '--force', :flag, "Force terminate", attribute_name: :forced
11
11
 
12
12
  requires_current_master_token
13
13
 
14
14
  def execute
15
+ abort_unless_api_access
15
16
  require_relative '../../../machine/upcloud'
16
17
  confirm_command(name) unless forced?
17
18
  grid = client.get("grids/#{current_grid}")
@@ -0,0 +1,99 @@
1
+ require 'kontena/machine/upcloud/client'
2
+
3
+ module Kontena
4
+ module Plugin
5
+ module Upcloud
6
+ module Prompts
7
+ module Common
8
+ def self.included(base)
9
+ base.prepend Defaults
10
+ base.option "--username", "USER", "Upcloud username", required: true, environment_variable: 'UPCLOUD_USERNAME'
11
+ base.option "--password", "PASS", "Upcloud password", required: true, environment_variable: 'UPCLOUD_PASSWORD'
12
+ end
13
+
14
+ def upcloud_client
15
+ @upcloud_client ||= Kontena::Machine::Upcloud::Client.new(username, password)
16
+ end
17
+
18
+ def abort_unless_api_access
19
+ unless upcloud_client.api_access?
20
+ exit_with_error('Upcloud API authentication failed. Check that API access is enabled for the user.')
21
+ end
22
+ end
23
+
24
+ module Defaults
25
+ def default_username
26
+ prompt.ask('UpCloud username:', echo: true)
27
+ end
28
+
29
+ def default_password
30
+ pass = prompt.ask('UpCloud password:', echo: false)
31
+ end
32
+ end
33
+ end
34
+
35
+ module NodeName
36
+ def self.included(base)
37
+ base.prepend Defaults
38
+ base.parameter "[NAME]", "Node name"
39
+ end
40
+
41
+ module Defaults
42
+ def default_name
43
+ nodes = client.get("grids/#{current_grid}/nodes")
44
+ nodes = nodes['nodes'].select{ |n|
45
+ n['labels'] && n['labels'].include?('provider=upcloud'.freeze)
46
+ }
47
+ raise "Did not find any nodes with label provider=upcloud" if nodes.empty?
48
+ prompt.select("Select node:") do |menu|
49
+ nodes.sort_by{|n| n['node_number'] }.reverse.each do |node|
50
+ initial = node['initial_member'] ? '(initial) ' : ''
51
+ menu.choice "#{node['name']} #{initial}", node['name']
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ module Create
59
+ def self.included(base)
60
+ base.include Common
61
+ base.prepend Defaults
62
+ base.option "--ssh-key", "SSH_KEY", "Path to ssh public key", attribute_name: :ssh_key_path
63
+ base.option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
64
+ base.option "--zone", "ZONE", "Zone", required: true
65
+ base.option "--plan", "PLAN", "Server size", required: true
66
+ end
67
+
68
+ def ssh_key
69
+ return File.read(ssh_key_path) unless ssh_key_path.nil?
70
+ default = File.read(Defaults::DEFAULT_SSH_KEY_PATH).strip rescue nil
71
+ prompt.ask('SSH public key: (enter an ssh key in OpenSSH format "ssh-xxx xxxxx key_name")', default: default) do |q|
72
+ q.validate /^ssh-rsa \S+ \S+$/
73
+ end
74
+ end
75
+
76
+ module Defaults
77
+ DEFAULT_SSH_KEY_PATH = File.join(Dir.home, '.ssh', 'id_rsa.pub')
78
+
79
+ def default_plan
80
+ prompt.select("Choose plan:") do |menu|
81
+ upcloud_client.list_plans.each do |plan|
82
+ menu.choice "#{plan[:name]} (#{plan[:memory_amount]}MB #{plan[:storage_size]}GB #{plan[:storage_tier]})", plan[:name]
83
+ end
84
+ end
85
+ end
86
+
87
+ def default_zone
88
+ prompt.select("Choose availability zone:") do |menu|
89
+ upcloud_client.list_zones.each do |zone|
90
+ menu.choice zone[:description], zone[:id]
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -1,23 +1,7 @@
1
1
  module Kontena
2
2
  module Plugin
3
3
  module Upcloud
4
- VERSION = "0.3.0"
5
-
6
- ZONES = {
7
- 'nl-ams1' => 'Amsterdam #1',
8
- 'us-chi1' => 'Chicago #1',
9
- 'de-fra1' => 'Frankfurt #1',
10
- 'fi-hel1' => 'Helsinki #1',
11
- 'uk-lon1' => 'London #1',
12
- 'sg-sin1' => 'Singapore #1'
13
- }.freeze
14
-
15
- PLANS = {
16
- '1xCPU-1GB' => '1024MB / 1 CPU, 30GB MaxIOPS disk, 2048GB transfer',
17
- '2xCPU-2GB' => '2048MB / 2 CPU, 50GB MaxIOPS disk, 3072GB transfer',
18
- '4xCPU-4GB' => '4096MB / 4 CPU, 100GB MaxIOPS disk, 4096GB transfer',
19
- '6xCPU-8GB' => '8192MB / 6 CPU, 200GB MaxIOPS disk, 8192GB transfer'
20
- }.freeze
4
+ VERSION = "0.3.1.rc1"
21
5
  end
22
6
  end
23
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kontena-plugin-upcloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kontena, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-20 00:00:00.000000000 Z
11
+ date: 2017-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kontena-cli
@@ -67,13 +67,13 @@ files:
67
67
  - README.md
68
68
  - kontena-plugin-upcloud.gemspec
69
69
  - lib/kontena/machine/upcloud.rb
70
+ - lib/kontena/machine/upcloud/client.rb
70
71
  - lib/kontena/machine/upcloud/cloudinit.yml
71
72
  - lib/kontena/machine/upcloud/cloudinit_master.yml
72
73
  - lib/kontena/machine/upcloud/master_provisioner.rb
73
74
  - lib/kontena/machine/upcloud/node_destroyer.rb
74
75
  - lib/kontena/machine/upcloud/node_provisioner.rb
75
76
  - lib/kontena/machine/upcloud/node_restarter.rb
76
- - lib/kontena/machine/upcloud/upcloud_common.rb
77
77
  - lib/kontena/plugin/upcloud.rb
78
78
  - lib/kontena/plugin/upcloud/master/create_command.rb
79
79
  - lib/kontena/plugin/upcloud/master_command.rb
@@ -81,6 +81,7 @@ files:
81
81
  - lib/kontena/plugin/upcloud/nodes/create_command.rb
82
82
  - lib/kontena/plugin/upcloud/nodes/restart_command.rb
83
83
  - lib/kontena/plugin/upcloud/nodes/terminate_command.rb
84
+ - lib/kontena/plugin/upcloud/prompts.rb
84
85
  - lib/kontena/plugin/upcloud_command.rb
85
86
  - lib/kontena_cli_plugin.rb
86
87
  homepage: https://github.com/kontena/kontena-plugin-upcloud
@@ -98,9 +99,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
99
  version: '0'
99
100
  required_rubygems_version: !ruby/object:Gem::Requirement
100
101
  requirements:
101
- - - ">="
102
+ - - ">"
102
103
  - !ruby/object:Gem::Version
103
- version: '0'
104
+ version: 1.3.1
104
105
  requirements: []
105
106
  rubyforge_project:
106
107
  rubygems_version: 2.4.5
@@ -1,72 +0,0 @@
1
- require 'excon'
2
- require 'json'
3
-
4
- module Kontena
5
- module Machine
6
- module Upcloud
7
- module UpcloudCommon
8
-
9
- attr_reader :username
10
- attr_reader :password
11
-
12
- def upcloud_client
13
- @upcloud_client ||= Excon.new(
14
- 'https://api.upcloud.com',
15
- omit_default_port: true,
16
- user: username,
17
- password: password,
18
- headers: { "Accept-Encoding" => 'application/json' }
19
- )
20
- end
21
-
22
- def find_template(name)
23
- get('storage/template')[:storages][:storage].find{|s| s[:title].downcase.start_with?(name.downcase)}
24
- end
25
-
26
- def find_plan(name)
27
- get('plan')[:plans][:plan].find{|s| s[:name].downcase.eql?(name.downcase)}
28
- end
29
-
30
- def zone_exist?(name)
31
- get('zone')[:zones][:zone].map{|p| p[:id]}.include?(name)
32
- end
33
-
34
- def get_server(id)
35
- get("server/#{id}").fetch(:server, nil)
36
- end
37
-
38
- def api_access?
39
- response = get('account')
40
- response.kind_of?(Hash) && response.has_key?(:account)
41
- rescue
42
- false
43
- end
44
-
45
- def abort_unless_api_access
46
- unless api_access?
47
- abort('Upcloud API authentication failed. Check that API access is enabled for the user.')
48
- end
49
- end
50
-
51
- [:get, :post, :delete].each do |http_method|
52
- define_method http_method do |path, options={}|
53
- response = upcloud_client.send(
54
- http_method,
55
- {
56
- path: File.join('/1.2', path),
57
- headers: { 'Content-Type' => 'application/json' }
58
- }.merge(options)
59
- )
60
- if response.body && response.body.start_with?('{')
61
- JSON.parse(response.body, symbolize_names: true)
62
- elsif response.status.to_s.start_with?('2')
63
- {success: true}
64
- else
65
- {error: response.status}
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end