kontena-plugin-cloud 1.0.0.pre1 → 1.0.0.pre2

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: 59e599cd1a6b5a74ff9854efbffc34bc2faba4fc
4
- data.tar.gz: 114cbd20de9d08e733c9790e113473dfabbda920
3
+ metadata.gz: 4ba51db007412d9c1f0cc5153e7972712627866d
4
+ data.tar.gz: dfb686674f831a540a732277ed44bdd824a2d3b1
5
5
  SHA512:
6
- metadata.gz: 6c59729a771e4d39e6a6a84a7e1db59803c7779e14dd907f4fa82e77413b971227c10a1f2dce3dec558c9b1a1940a986a26e16077618cbba652c2b6f0c0d1f6d
7
- data.tar.gz: 41c156dad9f34cfd32990ccbde6655fc6c1708113350be06c7c4981859ad50a84c3aacb92f17c11344c86f3e5e0fa5799f09ba177887d16b42b35cf22117c64c
6
+ metadata.gz: 37d98e085cf4ca833fb93152d9be9e178c54c04c743093b2233c247f5b1debef5c6b3cef310c1d789aefe9d9387f2c2cf80a149bb33af49a3fc62ec65d7cf6a9
7
+ data.tar.gz: 949e677350a6b488bd7c7984f757733acb70e9b570baf55400d886539b82da49218465a5747a70eabb5cd6c897c5496d5e1b091dc233683456cc026a1fc0de11
data/Gemfile CHANGED
@@ -5,5 +5,4 @@ gemspec
5
5
 
6
6
  group :development do
7
7
  gem 'rspec'
8
- gem 'kontena-plugin-digitalocean'
9
8
  end
@@ -0,0 +1,26 @@
1
+ module Kontena::Cli::Models
2
+ module CloudApiModel
3
+
4
+ attr_reader :api_data
5
+
6
+ def initialize(api_data)
7
+ @api_data = api_data || {}
8
+ end
9
+
10
+ def id
11
+ api_data['id']
12
+ end
13
+
14
+ def method_missing(method, *args, &block)
15
+ key = method.to_s.gsub('_', '-')
16
+
17
+ return api_data['attributes'].has_key?(key) && api_data['attributes'][key] if key.end_with?('?'.freeze)
18
+
19
+ if api_data['attributes'].has_key?(key)
20
+ api_data['attributes'][key]
21
+ else
22
+ raise ArgumentError.new("Method `#{m}` doesn't exist.")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'master_api_model'
2
+
3
+ module Kontena::Cli::Models
4
+ class Grid
5
+ include MasterApiModel
6
+
7
+ class Stats
8
+ include MasterApiModel
9
+
10
+ Statsd = Struct.new(:server, :port)
11
+
12
+ def statsd
13
+ @statsd ||= Statsd.new(@api_data.dig('statsd', 'server'), @api_data.dig('statsd', 'port'))
14
+ end
15
+ end
16
+
17
+ class Logs
18
+ include MasterApiModel
19
+ end
20
+
21
+ def id
22
+ api_data['id']
23
+ end
24
+
25
+ def logs
26
+ @logs ||= Logs.new(api_data['logs'])
27
+ end
28
+
29
+ def stats
30
+ @stats ||= Stats.new(api_data['stats'])
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ module Kontena::Cli::Models
2
+ module MasterApiModel
3
+
4
+ attr_reader :api_data
5
+
6
+ def initialize(api_data)
7
+ @api_data = api_data || {}
8
+ end
9
+
10
+ def method_missing(method, *args, &block)
11
+ key = method.to_s
12
+
13
+ return @api_data.has_key?(key) && @api_data[key] if key.end_with?('?'.freeze)
14
+
15
+ if @api_data.has_key?(key)
16
+ @api_data[key]
17
+ else
18
+ raise ArgumentError.new("Method `#{m}` doesn't exist.")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,16 +1,11 @@
1
+ require_relative 'cloud_api_model'
2
+
1
3
  module Kontena::Cli::Models
2
4
  class Platform
3
-
4
- def initialize(api_data)
5
- @api_data = api_data
6
- end
7
-
8
- def id
9
- @api_data['id']
10
- end
5
+ include CloudApiModel
11
6
 
12
7
  def region
13
- @api_data.dig('relationships', 'datacenter', 'data', 'id')
8
+ @api_data.dig('relationships', 'region', 'data', 'id')
14
9
  end
15
10
 
16
11
  def online?
@@ -20,14 +15,5 @@ module Kontena::Cli::Models
20
15
  def organization
21
16
  @api_data.dig('relationships', 'organization', 'data', 'id')
22
17
  end
23
-
24
- def method_missing(method, *args, &block)
25
- key = method.to_s.gsub('_', '-')
26
- if @api_data['attributes'].has_key?(key)
27
- @api_data['attributes'][key]
28
- else
29
- raise ArgumentError.new("Method `#{m}` doesn't exist.")
30
- end
31
- end
32
18
  end
33
19
  end
@@ -10,18 +10,6 @@ class Kontena::Plugin::Cloud::Organization::User::AddCommand < Kontena::Command
10
10
 
11
11
  def execute
12
12
  members = []
13
- spinner "Resolving organization #{pastel.cyan(name)} current members" do
14
- members = cloud_client.get("/organizations/#{name}/members")['data']
15
- members = members.map { |m|
16
- {
17
- type: 'users',
18
- id: m.dig('attributes', 'username'),
19
- meta: {
20
- role: m.dig('attributes', 'role')
21
- }
22
- }
23
- }
24
- end
25
13
  username_list.each do |u|
26
14
  members << {
27
15
  type: 'users',
@@ -31,7 +19,7 @@ class Kontena::Plugin::Cloud::Organization::User::AddCommand < Kontena::Command
31
19
  end
32
20
  spinner "Adding #{pastel.cyan(username_list.join(', '))} to organization #{pastel.cyan(name)} with role #{pastel.cyan(role)}" do
33
21
  data = {data: members}
34
- cloud_client.put("/organizations/#{name}/relationships/members", data)
22
+ cloud_client.post("/organizations/#{name}/relationships/members", data)
35
23
  end
36
24
  end
37
25
  end
@@ -12,22 +12,15 @@ class Kontena::Plugin::Cloud::Organization::User::RemoveCommand < Kontena::Comma
12
12
  confirm_command(username_list.join(',')) unless forced?
13
13
 
14
14
  members = []
15
- spinner "Resolving organization #{pastel.cyan(name)} current members" do
16
- members = cloud_client.get("/organizations/#{name}/members")['data']
17
- members = members.map { |m|
18
- {
19
- type: 'users',
20
- id: m.dig('attributes', 'username'),
21
- meta: {
22
- role: m.dig('attributes', 'role')
23
- }
24
- }
15
+ username_list.each do |u|
16
+ members << {
17
+ type: 'users',
18
+ id: u
25
19
  }
26
20
  end
27
- members.delete_if { |m| username_list.include?(m[:id]) }
28
21
  spinner "Removing #{pastel.cyan(username_list.join(', '))} from organization #{pastel.cyan(name)}" do
29
22
  data = {data: members}
30
- cloud_client.put("/organizations/#{name}/relationships/members", data)
23
+ cloud_client.delete("/organizations/#{name}/relationships/members", data)
31
24
  end
32
25
  end
33
26
  end
@@ -5,8 +5,8 @@ class Kontena::Plugin::Cloud::Region::ListCommand < Kontena::Command
5
5
  requires_current_account_token
6
6
 
7
7
  def execute
8
- datacenters = cloud_client.get('/datacenters')['data']
9
- print_table(datacenters) do |row|
8
+ regions = cloud_client.get('/regions')['data']
9
+ print_table(regions) do |row|
10
10
  row.merge!(row['attributes'])
11
11
  end
12
12
  end
@@ -1,18 +1,16 @@
1
1
  module Kontena
2
2
  module Plugin
3
3
  module Cloud
4
- VERSION = "1.0.0.pre1"
4
+ VERSION = "1.0.0.pre2"
5
5
 
6
6
  module Organization
7
- module User
8
- end
9
- end
10
-
11
- module Region
7
+ module User; end
12
8
  end
9
+ module Region; end
13
10
  end
14
11
 
15
12
  module Platform
13
+ module TrustedSubnet; end
16
14
  end
17
15
 
18
16
  module Grid
@@ -31,12 +31,7 @@ module Kontena::Plugin::Platform::Common
31
31
 
32
32
  # @param [String] name
33
33
  def require_platform(name)
34
- unless name.include?('/')
35
- name = "#{current_organization}/#{name}"
36
- end
37
- org, platform = name.split('/')
38
-
39
- raise ArgumentError, "Organization missing" unless org
34
+ org, platform = parse_platform_name(name)
40
35
 
41
36
  @current_organization = org
42
37
 
@@ -50,6 +45,19 @@ module Kontena::Plugin::Platform::Common
50
45
  self.current_grid = platform
51
46
  end
52
47
 
48
+ # @param [String] name
49
+ # @return [Array<String>] organization, platform
50
+ def parse_platform_name(name)
51
+ unless name.include?('/')
52
+ name = "#{current_organization}/#{name}"
53
+ end
54
+ org, platform = name.split('/')
55
+
56
+ raise ArgumentError, "Organization missing" unless org
57
+
58
+ [org, platform]
59
+ end
60
+
53
61
  def platform_config_exists?(name)
54
62
  !self.config.find_server_by(name: name).nil?
55
63
  end
@@ -54,9 +54,9 @@ class Kontena::Plugin::Platform::CreateCommand < Kontena::Command
54
54
  end
55
55
 
56
56
  def prompt_region
57
- datacenters = cloud_client.get('/datacenters')['data']
57
+ regions = cloud_client.get('/regions')['data']
58
58
  prompt.select("Choose region:") do |menu|
59
- datacenters.each do |d|
59
+ regions.each do |d|
60
60
  menu.choice d.dig('attributes', 'name'), d['id']
61
61
  end
62
62
  end
@@ -74,8 +74,8 @@ class Kontena::Plugin::Platform::CreateCommand < Kontena::Command
74
74
  data = {
75
75
  attributes: { "name": name, "initial-size": initial_size },
76
76
  relationships: {
77
- datacenter: {
78
- "data": { "type": "datacenters", "id": region }
77
+ region: {
78
+ "data": { "type": "region", "id": region }
79
79
  }
80
80
  }
81
81
  }
@@ -7,21 +7,21 @@ class Kontena::Plugin::Platform::ListCommand < Kontena::Command
7
7
 
8
8
  requires_current_account_token
9
9
 
10
- parameter "[ORG]", "Organization name", environment_variable: "KONTENA_ORGANIZATION"
10
+ option ["--organization", "--org"], "ORG", "Organization", environment_variable: "KONTENA_ORGANIZATION"
11
11
 
12
12
  def execute
13
- platforms = cloud_client.get("/organizations/#{org}/platforms")['data']
13
+ platforms = cloud_client.get("/organizations/#{organization}/platforms")['data']
14
14
 
15
15
  print_table(platforms) do |p|
16
16
  platform = Kontena::Cli::Models::Platform.new(p)
17
- p['name'] = "#{state_icon(platform.state)} #{org}/#{platform.name}"
17
+ p['name'] = "#{state_icon(platform.state)} #{organization}/#{platform.name}"
18
18
  p['organization'] = platform.organization
19
19
  p['url'] = platform.url
20
20
  p['region'] = platform.region
21
21
  end
22
22
  end
23
23
 
24
- def default_org
24
+ def default_organization
25
25
  current_account.username
26
26
  end
27
27
 
@@ -11,7 +11,7 @@ class Kontena::Plugin::Platform::RemoveCommand < Kontena::Command
11
11
 
12
12
  def execute
13
13
  require_platform(name)
14
- platform = find_platform_by_name(name)
14
+ platform = find_platform_by_name(current_platform, current_organization)
15
15
 
16
16
  confirm_command(name) unless forced?
17
17
 
@@ -1,8 +1,11 @@
1
+ require 'kontena/cli/grids/common'
1
2
  require_relative 'common'
3
+ require_relative '../../cli/models/grid'
2
4
 
3
5
  class Kontena::Plugin::Platform::ShowCommand < Kontena::Command
4
6
  include Kontena::Cli::Common
5
7
  include Kontena::Plugin::Platform::Common
8
+ include Kontena::Cli::Grids::Common
6
9
 
7
10
  requires_current_account_token
8
11
 
@@ -14,12 +17,42 @@ class Kontena::Plugin::Platform::ShowCommand < Kontena::Command
14
17
  platform = find_platform_by_name(current_platform, current_organization)
15
18
 
16
19
  puts "#{name}:"
17
- puts " id: #{platform.id}"
18
20
  puts " name: #{platform.name}"
19
21
  puts " organization: #{current_organization}"
20
22
  puts " state: #{platform.state}"
21
23
  puts " region: #{platform.region || '-'}"
22
24
  puts " initial_size: #{platform.initial_size}"
23
25
  puts " master: #{platform.url}"
26
+
27
+ grid = nil
28
+ begin
29
+ data = client.get("grids/#{platform.grid_id}")
30
+ grid = Kontena::Cli::Models::Grid.new(data)
31
+ rescue Kontena::Errors::StandardError
32
+ exit_with_error "Cannot fetch grid information"
33
+ end
34
+
35
+ if grid.default_affinity?
36
+ puts " default_affinity: "
37
+ grid.default_affinity.to_a.each do |a|
38
+ puts " - #{a}"
39
+ end
40
+ else
41
+ puts " default_affinity: -"
42
+ end
43
+ puts " subnet: #{grid.subnet}"
44
+ puts " supernet: #{grid.supernet}"
45
+ if grid.stats.statsd?
46
+ statsd = grid.stats.statsd
47
+ puts " exports:"
48
+ puts " statsd: #{statsd.server}:#{statsd.port}"
49
+ end
50
+ if grid.logs.forwarder?
51
+ puts "logs:"
52
+ puts " forwarder: #{grid.logs.forwarder}"
53
+ grid.logs.opts.each do |k,v|
54
+ puts " #{k}: #{v}"
55
+ end
56
+ end
24
57
  end
25
58
  end
@@ -0,0 +1,20 @@
1
+ require_relative '../../../cli/models/grid'
2
+ require_relative '../common'
3
+
4
+ class Kontena::Plugin::Platform::TrustedSubnet::AddCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Plugin::Platform::Common
7
+
8
+ parameter "NAME", "Platform name"
9
+ parameter "SUBNET", "Subnet"
10
+
11
+ def execute
12
+ require_platform(name)
13
+
14
+ grid = client.get("grids/#{current_grid}")
15
+ data = {trusted_subnets: grid['trusted_subnets'] + [self.subnet]}
16
+ spinner "Adding #{subnet.colorize(:cyan)} as a trusted subnet in #{current_grid.colorize(:cyan)} platform " do
17
+ client.put("grids/#{current_grid}", data)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ require_relative '../../../cli/models/grid'
2
+ require_relative '../common'
3
+ require 'ipaddr'
4
+
5
+ class Kontena::Plugin::Platform::TrustedSubnet::ListCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Plugin::Platform::Common
8
+ include Kontena::Cli::TableGenerator::Helper
9
+
10
+ parameter "NAME", "Platform name"
11
+
12
+ def execute
13
+ require_platform(name)
14
+ grid = Kontena::Cli::Models::Grid.new(client.get("grids/#{current_grid}"))
15
+ if grid.trusted_subnets.size > 0
16
+ nodes = client.get("grids/#{current_grid}/nodes")['nodes']
17
+ else
18
+ nodes = []
19
+ end
20
+ items = grid.trusted_subnets.map { |s|
21
+ item = {
22
+ 'subnet' => s
23
+ }
24
+ subnet = IPAddr.new(s)
25
+ item['nodes'] = trusted_nodes(subnet, nodes).map { |n| n['name'] }.join(',')
26
+
27
+ item
28
+ }
29
+
30
+ print_table(items)
31
+ end
32
+
33
+ # @param [IPAddr] subnet
34
+ # @param [Array<Hash>] nodes
35
+ def trusted_nodes(subnet, nodes)
36
+ nodes.select { |n|
37
+ begin
38
+ n['private_ip'] && subnet.include?( IPAddr.new(n['private_ip']) )
39
+ rescue => exc
40
+ STDERR.puts "Failed to parse #{n['private_ip']} (#{n['name']}): #{exc.message}"
41
+ end
42
+ }
43
+ end
44
+
45
+ def fields
46
+ {
47
+ subnet: 'subnet',
48
+ nodes: 'nodes'
49
+ }
50
+ end
51
+ end
@@ -0,0 +1,27 @@
1
+ require_relative '../../../cli/models/grid'
2
+ require_relative '../common'
3
+
4
+ class Kontena::Plugin::Platform::TrustedSubnet::RemoveCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Plugin::Platform::Common
7
+
8
+ parameter "NAME", "Platform name"
9
+ parameter "SUBNET", "Subnet"
10
+
11
+ option "--force", :flag, "Force remove", default: false, attribute_name: :forced
12
+
13
+ def execute
14
+ require_platform(name)
15
+
16
+ grid = client.get("grids/#{current_grid}")
17
+ confirm_command(subnet) unless forced?
18
+ trusted_subnets = grid['trusted_subnets'] || []
19
+ unless trusted_subnets.delete(self.subnet)
20
+ exit_with_error("Platform #{name.colorize(:cyan)} does not have trusted subnet #{subnet.colorize(:cyan)}")
21
+ end
22
+ data = {trusted_subnets: trusted_subnets}
23
+ spinner "Removing trusted subnet #{subnet.colorize(:cyan)} from #{name.colorize(:cyan)} platform " do
24
+ client.put("grids/#{current_grid}", data)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'common'
2
+
3
+ class Kontena::Plugin::Platform::TrustedSubnetCommand < Kontena::Command
4
+
5
+ subcommand ["list", "ls"], "List trusted subnets", load_subcommand('kontena/plugin/platform/trusted_subnet/list_command')
6
+ subcommand ["add"], "Add trusted subnet", load_subcommand('kontena/plugin/platform/trusted_subnet/add_command')
7
+ subcommand ["remove", "rm"], "Remove trusted subnet", load_subcommand('kontena/plugin/platform/trusted_subnet/remove_command')
8
+
9
+ def execute
10
+ end
11
+ end
@@ -7,6 +7,7 @@ class Kontena::Plugin::PlatformCommand < Kontena::Command
7
7
  subcommand ['remove', 'rm'], 'Remove platform', load_subcommand('kontena/plugin/platform/remove_command')
8
8
  subcommand 'audit-log', 'Show platform audit logs', load_subcommand('kontena/plugin/platform/audit_log_command')
9
9
  subcommand 'health', 'Show platform health', load_subcommand('kontena/plugin/platform/health_command')
10
+ subcommand 'trusted-subnet', 'Trusted subnet specific commands', load_subcommand('kontena/plugin/platform/trusted_subnet_command')
10
11
  subcommand 'import-grid', 'Import grid as Kontena Platform', load_subcommand('kontena/plugin/platform/import_grid_command')
11
12
 
12
13
  def execute
@@ -48,4 +48,26 @@ module Kontena
48
48
  class Command < Clamp::Command
49
49
  prepend CloudCommand
50
50
  end
51
+
52
+ module CloudClient
53
+ def parse_response(response)
54
+ data = super(response)
55
+ if data.is_a?(Hash) && data['errors']
56
+ data['error'] = {}
57
+ errors = data.delete('errors')
58
+ if errors.size == 1
59
+ data['error'] = errors[0]['title']
60
+ else
61
+ errors.each do |e|
62
+ data['error'][e['id']] = e['title']
63
+ end
64
+ end
65
+ end
66
+ data
67
+ end
68
+ end
69
+
70
+ class Client
71
+ prepend CloudClient
72
+ end
51
73
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kontena-plugin-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre1
4
+ version: 1.0.0.pre2
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-08-09 00:00:00.000000000 Z
11
+ date: 2017-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kontena-cli
@@ -67,6 +67,9 @@ files:
67
67
  - Rakefile
68
68
  - kontena-plugin-cloud.gemspec
69
69
  - lib/kontena/cli/master_code_exchanger.rb
70
+ - lib/kontena/cli/models/cloud_api_model.rb
71
+ - lib/kontena/cli/models/grid.rb
72
+ - lib/kontena/cli/models/master_api_model.rb
70
73
  - lib/kontena/cli/models/platform.rb
71
74
  - lib/kontena/plugin/cloud.rb
72
75
  - lib/kontena/plugin/cloud/organization/list_command.rb
@@ -87,6 +90,10 @@ files:
87
90
  - lib/kontena/plugin/platform/list_command.rb
88
91
  - lib/kontena/plugin/platform/remove_command.rb
89
92
  - lib/kontena/plugin/platform/show_command.rb
93
+ - lib/kontena/plugin/platform/trusted_subnet/add_command.rb
94
+ - lib/kontena/plugin/platform/trusted_subnet/list_command.rb
95
+ - lib/kontena/plugin/platform/trusted_subnet/remove_command.rb
96
+ - lib/kontena/plugin/platform/trusted_subnet_command.rb
90
97
  - lib/kontena/plugin/platform/use_command.rb
91
98
  - lib/kontena/plugin/platform_command.rb
92
99
  - lib/kontena_cli_plugin.rb