morpheus-cli 6.1.0 → 6.1.2
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 +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +8 -4
- data/lib/morpheus/api/cypher_interface.rb +11 -5
- data/lib/morpheus/api/load_balancer_pool_nodes_interface.rb +8 -0
- data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
- data/lib/morpheus/api/load_balancer_pools_secondary_interface.rb +9 -0
- data/lib/morpheus/api/roles_interface.rb +8 -8
- data/lib/morpheus/cli/commands/instances.rb +5 -0
- data/lib/morpheus/cli/commands/load_balancer_pool_nodes.rb +87 -0
- data/lib/morpheus/cli/commands/load_balancer_pools.rb +43 -4
- data/lib/morpheus/cli/commands/roles.rb +403 -586
- data/lib/morpheus/cli/commands/security_groups.rb +58 -37
- data/lib/morpheus/cli/commands/users.rb +46 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +6 -6
- data/lib/morpheus/cli/version.rb +1 -1
- metadata +5 -8
- data/lib/morpheus/api/doc_interface.rb +0 -50
- data/lib/morpheus/cli/commands/doc.rb +0 -182
- data/test/api/doc_interface_test.rb +0 -35
- data/test/cli/doc_test.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 683efa948a958a0fb4a6def11cb94ae525bdde8cbde0ba1d1aa313adeef3387d
|
4
|
+
data.tar.gz: c19c0522892a7f96a8398811b89ea4324815f4494011bf6696be1fb362787304
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1b269a981ec0fcbeecbad62a91ba90f6e7429c26593579185a0a513d0ab5ea5e2394ab11d7bf138570314a418059b6a072e47fb04b0393010dc0f66a463db54
|
7
|
+
data.tar.gz: 3c211238b4a2dae07c4da54659be1c43e9f0cf7aaf25f7bbfcf53f0c6a0482b43b87b44db541287dfd7201228902902e80c0a1b4a5b538207f3303174940cff9
|
data/Dockerfile
CHANGED
@@ -336,10 +336,6 @@ class Morpheus::APIClient
|
|
336
336
|
}
|
337
337
|
end
|
338
338
|
|
339
|
-
def doc
|
340
|
-
Morpheus::DocInterface.new(common_interface_options).setopts(@options)
|
341
|
-
end
|
342
|
-
|
343
339
|
def ping
|
344
340
|
Morpheus::PingInterface.new(common_interface_options).setopts(@options)
|
345
341
|
end
|
@@ -492,6 +488,10 @@ class Morpheus::APIClient
|
|
492
488
|
Morpheus::LoadBalancerPoolsInterface.new(common_interface_options).setopts(@options)
|
493
489
|
end
|
494
490
|
|
491
|
+
def load_balancer_pools_secondary
|
492
|
+
Morpheus::LoadBalancerPoolsSecondaryInterface.new(common_interface_options).setopts(@options)
|
493
|
+
end
|
494
|
+
|
495
495
|
def load_balancer_profiles
|
496
496
|
Morpheus::LoadBalancerProfilesInterface.new(common_interface_options).setopts(@options)
|
497
497
|
end
|
@@ -500,6 +500,10 @@ class Morpheus::APIClient
|
|
500
500
|
Morpheus::LoadBalancerMonitorsInterface.new(common_interface_options).setopts(@options)
|
501
501
|
end
|
502
502
|
|
503
|
+
def load_balancer_pool_nodes
|
504
|
+
Morpheus::LoadBalancerPoolNodesInterface.new(common_interface_options).setopts(@options)
|
505
|
+
end
|
506
|
+
|
503
507
|
def tasks
|
504
508
|
Morpheus::TasksInterface.new(common_interface_options).setopts(@options)
|
505
509
|
end
|
@@ -9,7 +9,7 @@ class Morpheus::CypherInterface < Morpheus::APIClient
|
|
9
9
|
|
10
10
|
def get(item_key, params={})
|
11
11
|
raise "#{self.class}.get() passed a blank item_key!" if item_key.to_s == ''
|
12
|
-
url = "#{@base_url}#{base_path}/#{item_key}"
|
12
|
+
url = "#{@base_url}#{base_path}/#{escape_item_key(item_key)}"
|
13
13
|
headers = { :params => params, :authorization => "Bearer #{@access_token}" }
|
14
14
|
execute({method: :get, url: url, headers: headers})
|
15
15
|
end
|
@@ -17,29 +17,35 @@ class Morpheus::CypherInterface < Morpheus::APIClient
|
|
17
17
|
# list url is the same as get but uses $itemKey/?list=true
|
18
18
|
# method: 'LIST' would be neat though
|
19
19
|
def list(item_key=nil, params={})
|
20
|
-
url = item_key ? "#{@base_url}#{base_path}/#{item_key}" : "#{@base_url}#{base_path}"
|
20
|
+
url = item_key ? "#{@base_url}#{base_path}/#{escape_item_key(item_key)}" : "#{@base_url}#{base_path}"
|
21
21
|
params.merge!({list:'true'}) # ditch this probably
|
22
22
|
headers = { :params => params, :authorization => "Bearer #{@access_token}" }
|
23
23
|
execute({method: :get, url: url, headers: headers})
|
24
24
|
end
|
25
25
|
|
26
26
|
def create(item_key, params={}, payload={})
|
27
|
-
url = "#{@base_url}#{base_path}/#{item_key}"
|
27
|
+
url = "#{@base_url}#{base_path}/#{escape_item_key(item_key)}"
|
28
28
|
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
29
29
|
execute({method: :post, url: url, headers: headers, payload: payload.to_json})
|
30
30
|
end
|
31
31
|
|
32
32
|
# update is not even needed I don't think, same as POST
|
33
33
|
def update(item_key, params={}, payload={})
|
34
|
-
url = "#{@base_url}#{base_path}/#{item_key}"
|
34
|
+
url = "#{@base_url}#{base_path}/#{escape_item_key(item_key)}"
|
35
35
|
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
36
36
|
execute({method: :put, url: url, headers: headers, payload: payload.to_json})
|
37
37
|
end
|
38
38
|
|
39
39
|
def destroy(item_key, params={})
|
40
|
-
url = "#{@base_url}#{base_path}/#{item_key}"
|
40
|
+
url = "#{@base_url}#{base_path}/#{escape_item_key(item_key)}"
|
41
41
|
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
42
42
|
execute({method: :delete, url: url, headers: headers})
|
43
43
|
end
|
44
44
|
|
45
|
+
protected
|
46
|
+
|
47
|
+
def escape_item_key(item_key)
|
48
|
+
item_key.to_s.split("/").collect {|i| CGI::escape(i.to_s) }.join("/")
|
49
|
+
end
|
50
|
+
|
45
51
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'morpheus/api/
|
1
|
+
require 'morpheus/api/rest_interface'
|
2
2
|
|
3
|
-
class Morpheus::LoadBalancerPoolsInterface < Morpheus::
|
3
|
+
class Morpheus::LoadBalancerPoolsInterface < Morpheus::RestInterface
|
4
4
|
|
5
|
-
def base_path
|
6
|
-
"/api/load-
|
5
|
+
def base_path
|
6
|
+
"/api/load-balancer-pools"
|
7
7
|
end
|
8
8
|
|
9
9
|
end
|
@@ -2,10 +2,10 @@ require 'morpheus/api/api_client'
|
|
2
2
|
|
3
3
|
class Morpheus::RolesInterface < Morpheus::APIClient
|
4
4
|
|
5
|
-
def get(account_id, id)
|
5
|
+
def get(account_id, id, params={})
|
6
6
|
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
7
7
|
url = build_url(account_id, id)
|
8
|
-
headers = { params:
|
8
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
9
9
|
execute(method: :get, url: url, headers: headers)
|
10
10
|
end
|
11
11
|
|
@@ -21,24 +21,24 @@ class Morpheus::RolesInterface < Morpheus::APIClient
|
|
21
21
|
execute(method: :get, url: url, headers: headers)
|
22
22
|
end
|
23
23
|
|
24
|
-
def create(account_id, options)
|
24
|
+
def create(account_id, options, params={})
|
25
25
|
url = build_url(account_id)
|
26
26
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
27
27
|
payload = options
|
28
|
-
execute(method: :post, url: url, headers: headers, payload: payload.to_json)
|
28
|
+
execute(method: :post, url: url, headers: headers, payload: payload.to_json, params: params)
|
29
29
|
end
|
30
30
|
|
31
|
-
def update(account_id, id, options)
|
31
|
+
def update(account_id, id, options, params={})
|
32
32
|
url = build_url(account_id, id)
|
33
33
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
34
34
|
payload = options
|
35
|
-
execute(method: :put, url: url, headers: headers, payload: payload.to_json)
|
35
|
+
execute(method: :put, url: url, headers: headers, payload: payload.to_json, params: params)
|
36
36
|
end
|
37
37
|
|
38
|
-
def destroy(account_id, id)
|
38
|
+
def destroy(account_id, id, params={})
|
39
39
|
url = build_url(account_id, id)
|
40
40
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
41
|
-
execute(method: :delete, url: url, headers: headers)
|
41
|
+
execute(method: :delete, url: url, headers: headers, params: params)
|
42
42
|
end
|
43
43
|
|
44
44
|
def update_permission(account_id, id, options)
|
@@ -599,6 +599,9 @@ class Morpheus::Cli::Instances
|
|
599
599
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
600
600
|
opts.banner = subcommand_usage("[instance]")
|
601
601
|
opts.on('--name VALUE', String, "Name") do |val|
|
602
|
+
params['name'] = val
|
603
|
+
end
|
604
|
+
opts.on('--displayName VALUE', String, "Name") do |val|
|
602
605
|
params['displayName'] = val
|
603
606
|
end
|
604
607
|
opts.on('--description VALUE', String, "Description") do |val|
|
@@ -1400,6 +1403,7 @@ class Morpheus::Cli::Instances
|
|
1400
1403
|
description_cols = {
|
1401
1404
|
"ID" => 'id',
|
1402
1405
|
"Name" => 'name',
|
1406
|
+
"Display Name" => 'displayName',
|
1403
1407
|
"Description" => 'description',
|
1404
1408
|
"Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
|
1405
1409
|
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
@@ -5423,6 +5427,7 @@ private
|
|
5423
5427
|
def add_instance_schedule_option_types()
|
5424
5428
|
[
|
5425
5429
|
{'code' => 'scheduleType', 'fieldName' => 'scheduleType', 'fieldLabel' => 'Schedule Type', 'type' => 'select', 'selectOptions' => [{'name'=>'Day Of Week', 'value'=>'dayOfWeek'},{'name'=>'Exact', 'value'=>'exact'}], 'description' => "Schedule type can be recurring day of the week str or exact start and end timestamp", 'required' => true, 'defaultValue' => 'dayOfWeek'},
|
5430
|
+
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'scheduleTimezone', 'fieldLabel' => 'Timezone', 'type' => 'select', 'optionSource' => 'timezones' , 'description' => "The timezone", 'defaultValue' => "UTC", 'required' => false},
|
5426
5431
|
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'startDayOfWeek', 'fieldLabel' => 'Start Day Of Week', 'type' => 'select', 'selectOptions' => day_of_week_dropdown, 'description' => "Start day of the week Sunday-Saturday (1-7)", 'defaultValue' => "Sunday", 'required' => true},
|
5427
5432
|
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'startTime', 'fieldLabel' => 'Start Time (HH:MM)', 'type' => 'text', 'description' => "Start time in HH:MM 24-hour format", 'placeHolder' => 'HH:MM', 'defaultValue' => "01:00", 'required' => true},
|
5428
5433
|
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'endDayOfWeek', 'fieldLabel' => 'End Day Of Week', 'type' => 'select', 'selectOptions' => day_of_week_dropdown, 'description' => "End day of the week Sunday-Saturday (1-7)", 'defaultValue' => "Sunday", 'required' => true},
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
class Morpheus::Cli::LoadBalancerPoolNodes
|
4
|
+
include Morpheus::Cli::CliCommand
|
5
|
+
include Morpheus::Cli::RestCommand
|
6
|
+
include Morpheus::Cli::SecondaryRestCommand
|
7
|
+
include Morpheus::Cli::LoadBalancersHelper
|
8
|
+
|
9
|
+
set_command_description "View and manage load balancer pool member nodes."
|
10
|
+
set_command_name :'load-balancer-pool-nodes'
|
11
|
+
|
12
|
+
set_rest_key :load_balancer_node
|
13
|
+
set_rest_parent_name :load_balancer_pools
|
14
|
+
set_rest_option_context_map({'loadBalancerNode' => ''})
|
15
|
+
|
16
|
+
register_subcommands :list, :get, :add, :update, :remove
|
17
|
+
register_interfaces :load_balancer_types, :load_balancer_pools
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def load_balancer_node_list_column_definitions(options)
|
22
|
+
{
|
23
|
+
"ID" => 'id',
|
24
|
+
"Status" => 'status',
|
25
|
+
"Name" => 'name',
|
26
|
+
"IP Address" => 'ipAddress',
|
27
|
+
"Port" => 'port'
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_balancer_node_column_definitions(options)
|
32
|
+
{
|
33
|
+
"ID" => 'id',
|
34
|
+
"Name" => 'name',
|
35
|
+
"Description" => 'description',
|
36
|
+
"State" => lambda {|it| it['config']['adminState']},
|
37
|
+
"IP Address" => 'ipAddress',
|
38
|
+
"Port" => 'port',
|
39
|
+
"Weight" => 'weight',
|
40
|
+
"Backup Member" => lambda {|it| format_boolean it['config']['backupMember']},
|
41
|
+
"Max Concurrent Connections" => lambda {|it| it['config']['maxConcurrentConnections']}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_balancer_node_object_key
|
46
|
+
'loadBalancerNode'
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_balancer_node_list_key
|
50
|
+
'loadBalancerNodes'
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_balancer_node_label
|
54
|
+
'Load Balancer Node'
|
55
|
+
end
|
56
|
+
|
57
|
+
def load_balancer_node_label_plural
|
58
|
+
'Load Balancer Nodes'
|
59
|
+
end
|
60
|
+
|
61
|
+
def format_load_balancer_pool_status(record, return_color=cyan)
|
62
|
+
out = ""
|
63
|
+
status_string = record['status']
|
64
|
+
if status_string.nil? || status_string.empty? || status_string == "unknown"
|
65
|
+
out << "#{white}UNKNOWN#{return_color}"
|
66
|
+
elsif status_string == 'ok'
|
67
|
+
out << "#{green}#{status_string.upcase}#{return_color}"
|
68
|
+
elsif status_string == 'warning'
|
69
|
+
out << "#{yellow}#{status_string.upcase}#{return_color}"
|
70
|
+
else
|
71
|
+
out << "#{red}#{status_string ? status_string.upcase : 'N/A'}#{record['statusMessage'] ? "#{return_color} - #{record['statusMessage']}" : ''}#{return_color}"
|
72
|
+
end
|
73
|
+
out
|
74
|
+
end
|
75
|
+
|
76
|
+
def load_option_types_for_load_balancer_node(type_record, parent_record)
|
77
|
+
load_balancer_pool = parent_record
|
78
|
+
load_balancer_type = find_by_id(:load_balancer_type, load_balancer_pool['loadBalancer']['type']['id'])
|
79
|
+
load_balancer_type['nodeOptionTypes']
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_load_balancer_node_by_name_or_id(parent_id, val)
|
83
|
+
(@load_balancer_pool_nodes_interface.get(parent_id, val)['loadBalancerNode']) rescue nil
|
84
|
+
end
|
85
|
+
## using CliCommand's generic find_by methods
|
86
|
+
|
87
|
+
end
|
@@ -8,12 +8,14 @@ class Morpheus::Cli::LoadBalancerPools
|
|
8
8
|
|
9
9
|
set_command_description "View and manage load balancer pools."
|
10
10
|
set_command_name :'load-balancer-pools'
|
11
|
-
register_subcommands :list, :get, :add, :update, :remove
|
12
|
-
register_interfaces :load_balancer_pools,
|
13
|
-
:load_balancers, :load_balancer_types
|
14
11
|
|
12
|
+
set_rest_interface_name :load_balancer_pools_secondary
|
15
13
|
set_rest_parent_name :load_balancers
|
16
14
|
|
15
|
+
register_subcommands :list, :get, :add, :update, :remove
|
16
|
+
register_interfaces :load_balancer_pools_secondary, :load_balancers, :load_balancer_types
|
17
|
+
|
18
|
+
|
17
19
|
# set_rest_interface_name :load_balancer_pools
|
18
20
|
# set_parent_rest_interface_name :load_balancers
|
19
21
|
|
@@ -30,6 +32,7 @@ class Morpheus::Cli::LoadBalancerPools
|
|
30
32
|
"Name" => 'name',
|
31
33
|
#"Load Balancer" => lambda {|it| it['loadBalancer'] ? it['loadBalancer']['name'] : '' },
|
32
34
|
"Balancer Mode" => lambda {|it| it['vipBalance'] },
|
35
|
+
"Status" => lambda {|it| format_load_balancer_pool_status(it) }
|
33
36
|
}
|
34
37
|
end
|
35
38
|
|
@@ -68,7 +71,7 @@ class Morpheus::Cli::LoadBalancerPools
|
|
68
71
|
status_string = record['status']
|
69
72
|
if status_string.nil? || status_string.empty? || status_string == "unknown"
|
70
73
|
out << "#{white}UNKNOWN#{return_color}"
|
71
|
-
elsif status_string == 'ok'
|
74
|
+
elsif status_string == 'online' || status_string == 'ok'
|
72
75
|
out << "#{green}#{status_string.upcase}#{return_color}"
|
73
76
|
elsif status_string == 'syncing'
|
74
77
|
out << "#{yellow}#{status_string.upcase}#{return_color}"
|
@@ -87,4 +90,40 @@ class Morpheus::Cli::LoadBalancerPools
|
|
87
90
|
|
88
91
|
## using CliCommand's generic find_by methods
|
89
92
|
|
93
|
+
def find_load_balancer_pool_by_name_or_id(load_balancer_pool_id, val)
|
94
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
95
|
+
return find_load_balancer_pool_by_id(load_balancer_pool_id, val)
|
96
|
+
else
|
97
|
+
return find_load_balancer_pool_by_name(load_balancer_pool_id, val)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_load_balancer_pool_by_id(load_balancer_pool_id, id)
|
102
|
+
begin
|
103
|
+
json_response = @load_balancer_pools_secondary_interface.get(load_balancer_pool_id, id.to_i)
|
104
|
+
return json_response[load_balancer_pool_object_key]
|
105
|
+
rescue RestClient::Exception => e
|
106
|
+
if e.response && e.response.code == 404
|
107
|
+
print_red_alert "Load Balancer Pool not found by id #{id}"
|
108
|
+
else
|
109
|
+
raise e
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def find_load_balancer_pool_by_name(load_balancer_pool_id, name)
|
115
|
+
lbs = @load_balancer_pools_secondary_interface.list(load_balancer_pool_id, {name: name.to_s})[load_balancer_pool_list_key]
|
116
|
+
if lbs.empty?
|
117
|
+
print_red_alert "Load Balancer Pool not found by name #{name}"
|
118
|
+
return nil
|
119
|
+
elsif lbs.size > 1
|
120
|
+
print_red_alert "#{lbs.size} load balancer pools found by name #{name}"
|
121
|
+
#print_lbs_table(lbs, {color: red})
|
122
|
+
print reset,"\n\n"
|
123
|
+
return nil
|
124
|
+
else
|
125
|
+
return lbs[0]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
90
129
|
end
|