nex_client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +202 -0
- data/README.md +28 -0
- data/bin/nex-cli +7 -0
- data/lib/nex_client.rb +20 -0
- data/lib/nex_client/addon.rb +7 -0
- data/lib/nex_client/app.rb +24 -0
- data/lib/nex_client/base_resource.rb +19 -0
- data/lib/nex_client/cli.rb +348 -0
- data/lib/nex_client/commands.rb +17 -0
- data/lib/nex_client/commands/addons.rb +98 -0
- data/lib/nex_client/commands/apps.rb +301 -0
- data/lib/nex_client/commands/cube_instances.rb +89 -0
- data/lib/nex_client/commands/cube_templates.rb +44 -0
- data/lib/nex_client/commands/domains.rb +90 -0
- data/lib/nex_client/commands/helpers.rb +22 -0
- data/lib/nex_client/commands/organizations.rb +27 -0
- data/lib/nex_client/commands/racks.rb +90 -0
- data/lib/nex_client/commands/ssl_certificates.rb +100 -0
- data/lib/nex_client/commands/users.rb +49 -0
- data/lib/nex_client/compute_rack.rb +10 -0
- data/lib/nex_client/cube_instance.rb +21 -0
- data/lib/nex_client/cube_template.rb +8 -0
- data/lib/nex_client/domain.rb +7 -0
- data/lib/nex_client/gateway_rack.rb +7 -0
- data/lib/nex_client/organization.rb +5 -0
- data/lib/nex_client/resource_workflow.rb +17 -0
- data/lib/nex_client/routing_rack.rb +7 -0
- data/lib/nex_client/ssl_certificate.rb +7 -0
- data/lib/nex_client/storage_rack.rb +10 -0
- data/lib/nex_client/user.rb +5 -0
- data/lib/nex_client/version.rb +3 -0
- metadata +146 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
module Commands
|
4
|
+
module CubeTemplates
|
5
|
+
extend Helpers
|
6
|
+
|
7
|
+
TEMPLATES_TITLE = "Cube Templates".colorize(:red)
|
8
|
+
TEMPLATES_HEADERS = ['id','name','image','tag','layer','min_pu','stack'].map(&:upcase)
|
9
|
+
|
10
|
+
def self.list(args,opts)
|
11
|
+
filters = {}
|
12
|
+
filters[:human_id] = opts.name if opts.name.present?
|
13
|
+
filters[:stack] = opts.stack if opts.stack.present?
|
14
|
+
filters[:image] = opts.image if opts.image.present?
|
15
|
+
|
16
|
+
# Create table
|
17
|
+
list = NexClient::CubeTemplate.where(filters).order('human_id')
|
18
|
+
self.display_templates(list)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.display_templates(list)
|
22
|
+
table = Terminal::Table.new title: TEMPLATES_TITLE, headings: TEMPLATES_HEADERS do |t|
|
23
|
+
[list].flatten.compact.each do |e|
|
24
|
+
t.add_row(self.format_record(e))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
puts table
|
28
|
+
puts "\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.format_record(record)
|
32
|
+
[
|
33
|
+
record.id,
|
34
|
+
record.human_id,
|
35
|
+
record.image,
|
36
|
+
record.tag,
|
37
|
+
record.layer,
|
38
|
+
record.min_pu,
|
39
|
+
record.stack
|
40
|
+
]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
module Commands
|
4
|
+
module Domains
|
5
|
+
extend Helpers
|
6
|
+
|
7
|
+
DOMAINS_TITLE = "Domains".colorize(:magenta)
|
8
|
+
DOMAINS_HEADERS = ['id','cname','origin'].map(&:upcase)
|
9
|
+
|
10
|
+
def self.list(args,opts)
|
11
|
+
filters = {}
|
12
|
+
filters[:'origin.name'] = args.first if args.first.present?
|
13
|
+
|
14
|
+
# Create table
|
15
|
+
list = NexClient::Domain.includes(:origin).where(filters).order('cname')
|
16
|
+
self.display_domains(list)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create(args,opts)
|
20
|
+
domain_name,app_name = args
|
21
|
+
app = NexClient::App.find(name: app_name).first
|
22
|
+
app ||= NexClient::CubeInstance.find(name: app_name).first
|
23
|
+
|
24
|
+
# Display error
|
25
|
+
unless app
|
26
|
+
error("Error! Could not find app: #{app_name}")
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
domain = NexClient::Domain.new(cname: domain_name)
|
31
|
+
domain.relationships.attributes = { origin: { data: { type: app.type, id: app.id } } }
|
32
|
+
domain.save
|
33
|
+
|
34
|
+
# Display errors if any
|
35
|
+
if domain.errors.any?
|
36
|
+
display_record_errors(domain)
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
# Display domains
|
41
|
+
self.display_domains(NexClient::Domain.includes(:origin).find(domain.id).first)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.destroy(args,opts)
|
45
|
+
name = args.first
|
46
|
+
e = NexClient::Domain.find(cname: name).first
|
47
|
+
|
48
|
+
# Display error
|
49
|
+
unless e
|
50
|
+
error("Error! Could not find domain: #{name}")
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
# Ask confirmation
|
55
|
+
answer = ask("Enter the name of this domain to confirm: ")
|
56
|
+
unless answer == e.cname
|
57
|
+
error("Aborting deletion...")
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
61
|
+
e.destroy
|
62
|
+
success("Successfully destroyed domain: #{name}")
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.display_domains(list)
|
66
|
+
table = Terminal::Table.new title: DOMAINS_TITLE, headings: DOMAINS_HEADERS do |t|
|
67
|
+
[list].flatten.compact.each do |e|
|
68
|
+
t.add_row(self.format_record(e))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
puts table
|
72
|
+
puts "\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.format_record(record)
|
76
|
+
origin = self.format_origin(record)
|
77
|
+
[
|
78
|
+
record.id,
|
79
|
+
record.cname,
|
80
|
+
origin
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.format_origin(record)
|
85
|
+
return "-" unless record.origin
|
86
|
+
record.origin.name
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NexClient
|
4
|
+
module Commands
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
def display_record_errors(record)
|
8
|
+
record.errors.messages.each do |k,v|
|
9
|
+
v.each { |m| puts "#{k} #{m}" }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def success(msg)
|
14
|
+
puts msg.colorize(:green)
|
15
|
+
end
|
16
|
+
|
17
|
+
def error(msg)
|
18
|
+
puts msg.colorize(:red)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
module Commands
|
4
|
+
module Organizations
|
5
|
+
extend Helpers
|
6
|
+
|
7
|
+
ORGS_TITLE = "Organizations".colorize(:green)
|
8
|
+
ORGS_HEADERS = ['id','name','handle'].map(&:upcase)
|
9
|
+
|
10
|
+
def self.list(args,opts)
|
11
|
+
# Create table
|
12
|
+
self.display_organizations(NexClient::Organization.order('handle'))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.display_organizations(list)
|
16
|
+
table = Terminal::Table.new title: ORGS_TITLE, headings: ORGS_HEADERS do |t|
|
17
|
+
[list].flatten.compact.each do |e|
|
18
|
+
t.add_row([e.id,e.name,e.handle])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
puts table
|
22
|
+
puts "\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
module Commands
|
4
|
+
module Racks
|
5
|
+
extend Helpers
|
6
|
+
|
7
|
+
COMPUTE_RACKS_TITLE = "Compute Racks".colorize(:cyan)
|
8
|
+
STORAGE_RACKS_TITLE = "Storage Racks".colorize(:blue)
|
9
|
+
ROUTING_RACKS_TITLE = "Routing Racks".colorize(:green)
|
10
|
+
GATEWAY_RACKS_TITLE = "Gateway Racks".colorize(:yellow)
|
11
|
+
RACKS_HEADERS = ['type','id','region','stack','status','iip','eip','capacity'].map(&:upcase)
|
12
|
+
|
13
|
+
def self.list(args,opts)
|
14
|
+
filters = {}
|
15
|
+
|
16
|
+
# Type filter
|
17
|
+
only_type = opts.type
|
18
|
+
only_type = 'compute' if opts.stack.present?
|
19
|
+
|
20
|
+
# Status filter
|
21
|
+
filters[:status] = opts.status || 'running'
|
22
|
+
|
23
|
+
# Stack filter
|
24
|
+
if opts.stack.present?
|
25
|
+
filters[:stack] = opts.stack
|
26
|
+
end
|
27
|
+
|
28
|
+
# All option
|
29
|
+
filters = {} if opts.all
|
30
|
+
|
31
|
+
# Create table
|
32
|
+
if !only_type || only_type == 'compute'
|
33
|
+
self.display_compute_racks(NexClient::ComputeRack.where(filters).order('aws_region,status'))
|
34
|
+
end
|
35
|
+
|
36
|
+
if !only_type || only_type == 'storage'
|
37
|
+
self.display_storage_racks(NexClient::StorageRack.where(filters).order('aws_region,status'))
|
38
|
+
end
|
39
|
+
|
40
|
+
if !only_type || only_type == 'routing'
|
41
|
+
self.display_routing_racks(NexClient::RoutingRack.where(filters).order('aws_region,status'))
|
42
|
+
end
|
43
|
+
|
44
|
+
if !only_type || only_type == 'gateway'
|
45
|
+
self.display_gateway_racks(NexClient::GatewayRack.where(filters).order('aws_region,status'))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.display_compute_racks(list)
|
50
|
+
table = Terminal::Table.new title: COMPUTE_RACKS_TITLE, headings: RACKS_HEADERS do |t|
|
51
|
+
[list].flatten.compact.each do |e|
|
52
|
+
t.add_row(['compute',e.id,e.aws_region,e.stack,e.status,e.aws_local_ip_address,'-',"#{e.used_pu}/#{e.total_pu}"])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
puts table
|
56
|
+
puts "\n"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.display_storage_racks(list)
|
60
|
+
table = Terminal::Table.new title: STORAGE_RACKS_TITLE, headings: RACKS_HEADERS do |t|
|
61
|
+
[list].flatten.compact.each do |e|
|
62
|
+
t.add_row(['storage',e.id,e.aws_region,'-',e.status,e.aws_local_ip_address,'-',"#{e.used_su}/#{e.total_su}"])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
puts table
|
66
|
+
puts "\n"
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.display_routing_racks(list)
|
70
|
+
table = Terminal::Table.new title: ROUTING_RACKS_TITLE, headings: RACKS_HEADERS do |t|
|
71
|
+
[list].flatten.compact.each do |e|
|
72
|
+
t.add_row(['routing',e.id,e.aws_region,'-',e.status,e.aws_local_ip_address,'-','-'])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
puts table
|
76
|
+
puts "\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.display_gateway_racks(list)
|
80
|
+
table = Terminal::Table.new title: GATEWAY_RACKS_TITLE, headings: RACKS_HEADERS do |t|
|
81
|
+
[list].flatten.compact.each do |e|
|
82
|
+
t.add_row(['gateway',e.id,e.aws_region,'-',e.status,e.aws_local_ip_address,e.ip_address,'-'])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
puts table
|
86
|
+
puts "\n"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
module Commands
|
4
|
+
module SslCertificates
|
5
|
+
extend Helpers
|
6
|
+
|
7
|
+
DOMAINS_TITLE = "SSL Certificates".colorize(:light_yellow)
|
8
|
+
DOMAINS_HEADERS = ['id','cname','origin'].map(&:upcase)
|
9
|
+
|
10
|
+
def self.list(args,opts)
|
11
|
+
filters = {}
|
12
|
+
filters[:'origin.name'] = args.first if args.first.present?
|
13
|
+
|
14
|
+
# Create table
|
15
|
+
list = NexClient::SslCertificate.includes(:origin).where(filters).order('cname')
|
16
|
+
self.display_certs(list)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create(args,opts)
|
20
|
+
cert_name,app_name = args
|
21
|
+
app = NexClient::App.find(name: app_name).first
|
22
|
+
app ||= NexClient::CubeInstance.find(name: app_name).first
|
23
|
+
|
24
|
+
# Display error
|
25
|
+
unless app
|
26
|
+
error("Error! Could not find app: #{app_name}")
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
# Load or ask certificate content from specified files
|
31
|
+
pubcert = opts.cert.present? ? File.read(opts.cert) : ask("Copy/paste your certificate below:") { |q| q.gather = "" }
|
32
|
+
bundle = opts.bundle.present? ? File.read(opts.bundle) : ask("Copy/paste your cert bundle below:") { |q| q.gather = "" }
|
33
|
+
privkey = opts.privkey.present? ? File.read(opts.privkey) : ask("Copy/paste your cert private key below:") { |q| q.gather = "" }
|
34
|
+
|
35
|
+
cert = NexClient::SslCertificate.new(
|
36
|
+
cname: cert_name,
|
37
|
+
public_cert: pubcert,
|
38
|
+
cert_bundle: bundle,
|
39
|
+
private_key: privkey
|
40
|
+
)
|
41
|
+
cert.relationships.attributes = { origin: { data: { type: app.type, id: app.id } } }
|
42
|
+
cert.save
|
43
|
+
|
44
|
+
# Display errors if any
|
45
|
+
if cert.errors.any?
|
46
|
+
display_record_errors(cert)
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
|
50
|
+
# Display certs
|
51
|
+
self.display_certs(NexClient::SslCertificate.includes(:origin).find(cert.id).first)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.destroy(args,opts)
|
55
|
+
name = args.first
|
56
|
+
e = NexClient::SslCertificate.find(cname: name).first
|
57
|
+
|
58
|
+
# Display error
|
59
|
+
unless e
|
60
|
+
error("Error! Could not find cert: #{name}")
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
# Ask confirmation
|
65
|
+
answer = ask("Enter the name of this cert to confirm: ")
|
66
|
+
unless answer == e.cname
|
67
|
+
error("Aborting deletion...")
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
|
71
|
+
e.destroy
|
72
|
+
success("Successfully destroyed cert: #{name}")
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.display_certs(list)
|
76
|
+
table = Terminal::Table.new title: DOMAINS_TITLE, headings: DOMAINS_HEADERS do |t|
|
77
|
+
[list].flatten.compact.each do |e|
|
78
|
+
t.add_row(self.format_record(e))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
puts table
|
82
|
+
puts "\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.format_record(record)
|
86
|
+
origin = self.format_origin(record)
|
87
|
+
[
|
88
|
+
record.id,
|
89
|
+
record.cname,
|
90
|
+
origin
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.format_origin(record)
|
95
|
+
return "-" unless record.origin
|
96
|
+
record.origin.name
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
module Commands
|
4
|
+
module Users
|
5
|
+
extend Helpers
|
6
|
+
|
7
|
+
USERS_TITLE = "Users".colorize(:blue)
|
8
|
+
USERS_HEADERS = ['id','name','email','handle','orgs'].map(&:upcase)
|
9
|
+
|
10
|
+
def self.list(args,opts)
|
11
|
+
filters = {}
|
12
|
+
|
13
|
+
# Stack filter
|
14
|
+
if opts.organization.present?
|
15
|
+
filters[:'organization.handle'] = opts.organization
|
16
|
+
end
|
17
|
+
|
18
|
+
# Create table
|
19
|
+
self.display_users(NexClient::User.includes(:organizations).where(filters).order('handle'))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.display_users(list)
|
23
|
+
table = Terminal::Table.new title: USERS_TITLE, headings: USERS_HEADERS do |t|
|
24
|
+
[list].flatten.compact.each do |e|
|
25
|
+
t.add_row(self.format_record(e))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
puts table
|
29
|
+
puts "\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.format_record(record)
|
33
|
+
orgs = self.format_orgs(record)
|
34
|
+
[
|
35
|
+
record.id,
|
36
|
+
record.first_name,
|
37
|
+
record.email,
|
38
|
+
record.handle,
|
39
|
+
orgs
|
40
|
+
]
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.format_orgs(record)
|
44
|
+
return "-" unless record.organizations.present?
|
45
|
+
record.organizations.map(&:name).join(',')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
class ComputeRack < BaseResource
|
4
|
+
property :created_at, type: :time
|
5
|
+
property :updated_at, type: :time
|
6
|
+
property :total_pu, type: :int
|
7
|
+
property :available_pu, type: :int
|
8
|
+
property :used_pu, type: :int
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module NexClient
|
3
|
+
class CubeInstance < BaseResource
|
4
|
+
property :created_at, type: :time
|
5
|
+
property :updated_at, type: :time
|
6
|
+
property :pu, type: :int
|
7
|
+
property :soa_enabled, type: :boolean
|
8
|
+
property :ssl_enabled, type: :boolean
|
9
|
+
property :persistent_storage, type: :boolean
|
10
|
+
property :port, type: :int
|
11
|
+
|
12
|
+
# PATCH <api_root>/apps/:id/restart
|
13
|
+
custom_endpoint :restart, on: :member, request_method: :patch
|
14
|
+
|
15
|
+
# PATCH <api_root>/apps/:id/start
|
16
|
+
custom_endpoint :start, on: :member, request_method: :patch
|
17
|
+
|
18
|
+
# PATCH <api_root>/apps/:id/stop
|
19
|
+
custom_endpoint :stop, on: :member, request_method: :patch
|
20
|
+
end
|
21
|
+
end
|