morpheus-cli 5.3.1.1 → 5.3.2.3
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/accounts_interface.rb +4 -30
- data/lib/morpheus/api/api_client.rb +12 -0
- data/lib/morpheus/api/load_balancer_pools_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_types_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +9 -0
- data/lib/morpheus/api/load_balancers_interface.rb +4 -53
- data/lib/morpheus/api/network_routers_interface.rb +56 -0
- data/lib/morpheus/api/option_type_lists_interface.rb +19 -7
- data/lib/morpheus/api/secondary_read_interface.rb +25 -0
- data/lib/morpheus/api/secondary_rest_interface.rb +42 -0
- data/lib/morpheus/cli/cli_command.rb +9 -9
- data/lib/morpheus/cli/instances.rb +39 -37
- data/lib/morpheus/cli/library_cluster_layouts_command.rb +2 -3
- data/lib/morpheus/cli/library_container_scripts_command.rb +3 -4
- data/lib/morpheus/cli/library_container_templates_command.rb +4 -0
- data/lib/morpheus/cli/library_container_types_command.rb +2 -3
- data/lib/morpheus/cli/library_instance_types_command.rb +2 -3
- data/lib/morpheus/cli/library_layouts_command.rb +4 -0
- data/lib/morpheus/cli/library_option_lists_command.rb +68 -16
- data/lib/morpheus/cli/library_option_types_command.rb +4 -0
- data/lib/morpheus/cli/library_spec_templates_command.rb +3 -4
- data/lib/morpheus/cli/load_balancer_types.rb +37 -0
- data/lib/morpheus/cli/load_balancers.rb +149 -314
- data/lib/morpheus/cli/log_settings_command.rb +7 -3
- data/lib/morpheus/cli/mixins/load_balancers_helper.rb +156 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +11 -0
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -7
- data/lib/morpheus/cli/mixins/rest_command.rb +657 -0
- data/lib/morpheus/cli/network_routers_command.rb +1183 -185
- data/lib/morpheus/cli/networks_command.rb +194 -101
- data/lib/morpheus/cli/option_types.rb +29 -39
- data/lib/morpheus/cli/tenants_command.rb +18 -20
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/ext/string.rb +41 -0
- data/lib/morpheus/formatters.rb +4 -0
- metadata +11 -2
@@ -41,10 +41,9 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
|
|
41
41
|
opts.footer = "List cluster layouts."
|
42
42
|
end
|
43
43
|
optparse.parse!(args)
|
44
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
44
45
|
if args.count > 0
|
45
|
-
|
46
|
-
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
47
|
-
return 1
|
46
|
+
options[:phrase] = args.join(" ")
|
48
47
|
end
|
49
48
|
connect(options)
|
50
49
|
begin
|
@@ -25,12 +25,11 @@ class Morpheus::Cli::LibraryContainerScriptsCommand
|
|
25
25
|
opts.footer = "List container scripts."
|
26
26
|
end
|
27
27
|
optparse.parse!(args)
|
28
|
-
|
28
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
29
29
|
if args.count > 0
|
30
|
-
|
31
|
-
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(', ')}\n#{optparse}"
|
32
|
-
return 1
|
30
|
+
options[:phrase] = args.join(" ")
|
33
31
|
end
|
32
|
+
connect(options)
|
34
33
|
begin
|
35
34
|
# construct payload
|
36
35
|
params.merge!(parse_list_options(options))
|
@@ -26,6 +26,10 @@ class Morpheus::Cli::LibraryContainerTemplatesCommand
|
|
26
26
|
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
27
27
|
end
|
28
28
|
optparse.parse!(args)
|
29
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
30
|
+
if args.count > 0
|
31
|
+
options[:phrase] = args.join(" ")
|
32
|
+
end
|
29
33
|
connect(options)
|
30
34
|
begin
|
31
35
|
[:phrase, :offset, :max, :sort, :direction, :lastUpdated].each do |k|
|
@@ -49,10 +49,9 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
49
49
|
opts.footer = "List node types."
|
50
50
|
end
|
51
51
|
optparse.parse!(args)
|
52
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
52
53
|
if args.count > 0
|
53
|
-
|
54
|
-
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
55
|
-
return 1
|
54
|
+
options[:phrase] = args.join(" ")
|
56
55
|
end
|
57
56
|
connect(options)
|
58
57
|
begin
|
@@ -47,10 +47,9 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
|
|
47
47
|
opts.footer = "List instance types."
|
48
48
|
end
|
49
49
|
optparse.parse!(args)
|
50
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
50
51
|
if args.count > 0
|
51
|
-
|
52
|
-
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
53
|
-
return 1
|
52
|
+
options[:phrase] = args.join(" ")
|
54
53
|
end
|
55
54
|
connect(options)
|
56
55
|
begin
|
@@ -59,6 +59,10 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
59
59
|
opts.footer = "List layouts."
|
60
60
|
end
|
61
61
|
optparse.parse!(args)
|
62
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
63
|
+
if args.count > 0
|
64
|
+
options[:phrase] = args.join(" ")
|
65
|
+
end
|
62
66
|
connect(options)
|
63
67
|
begin
|
64
68
|
# construct payload
|
@@ -9,7 +9,7 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
9
9
|
include Morpheus::Cli::LibraryHelper
|
10
10
|
|
11
11
|
set_command_name :'library-option-lists'
|
12
|
-
register_subcommands :list, :get, :add, :update, :remove
|
12
|
+
register_subcommands :list, :get, :list_items, :add, :update, :remove
|
13
13
|
|
14
14
|
def initialize()
|
15
15
|
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
@@ -35,6 +35,10 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
35
35
|
opts.footer = "List option lists."
|
36
36
|
end
|
37
37
|
optparse.parse!(args)
|
38
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
39
|
+
if args.count > 0
|
40
|
+
options[:phrase] = args.join(" ")
|
41
|
+
end
|
38
42
|
connect(options)
|
39
43
|
begin
|
40
44
|
params = {}
|
@@ -61,16 +65,14 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
61
65
|
id: option_type_list['id'],
|
62
66
|
name: option_type_list['name'],
|
63
67
|
description: option_type_list['description'],
|
64
|
-
type: option_type_list['type']
|
65
|
-
size: option_type_list['listItems'] ? option_type_list['listItems'].size : ''
|
68
|
+
type: ((option_type_list['type'] == 'api') ? "#{option_type_list['type']} (#{option_type_list['apiType']})" : option_type_list['type'])
|
66
69
|
}
|
67
70
|
end
|
68
71
|
columns = [
|
69
72
|
:id,
|
70
73
|
:name,
|
71
74
|
:description,
|
72
|
-
:type
|
73
|
-
:size
|
75
|
+
:type
|
74
76
|
]
|
75
77
|
print cyan
|
76
78
|
print as_pretty_table(rows, columns, options)
|
@@ -90,8 +92,8 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
90
92
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
91
93
|
opts.banner = subcommand_usage("[name]")
|
92
94
|
build_standard_get_options(opts, options)
|
93
|
-
opts.on(nil,'--
|
94
|
-
options[:
|
95
|
+
opts.on(nil,'--items', "Load and display option list items") do |val|
|
96
|
+
options[:list_items] = true
|
95
97
|
end
|
96
98
|
opts.footer = "Get details about an option list.\n" +
|
97
99
|
"[name] is required. This is the name or id of an option list. Supports 1-N [name] arguments."
|
@@ -108,20 +110,31 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
108
110
|
end
|
109
111
|
|
110
112
|
def _get(id, options)
|
111
|
-
|
113
|
+
params = {}
|
114
|
+
params.merge!(parse_query_options(options))
|
112
115
|
begin
|
113
116
|
@option_type_lists_interface.setopts(options)
|
114
117
|
if options[:dry_run]
|
115
118
|
if id.to_s =~ /\A\d{1,}\Z/
|
116
|
-
print_dry_run @option_type_lists_interface.dry.get(id.to_i)
|
119
|
+
print_dry_run @option_type_lists_interface.dry.get(id.to_i, params)
|
117
120
|
else
|
118
|
-
print_dry_run @option_type_lists_interface.dry.list({name: id})
|
121
|
+
print_dry_run @option_type_lists_interface.dry.list(params.merge({name: id}))
|
119
122
|
end
|
120
123
|
return
|
121
124
|
end
|
122
125
|
option_type_list = find_option_type_list_by_name_or_id(id)
|
123
126
|
return 1 if option_type_list.nil?
|
124
|
-
|
127
|
+
list_items = nil
|
128
|
+
if options[:list_items]
|
129
|
+
list_items = option_type_list['listItems']
|
130
|
+
if list_items.nil?
|
131
|
+
begin
|
132
|
+
list_items = @option_type_lists_interface.list_items(option_type_list['id'])['listItems']
|
133
|
+
rescue => e
|
134
|
+
puts_error "Failed to load option list items: #{e.message}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
125
138
|
json_response = {'optionTypeList' => option_type_list}
|
126
139
|
render_result = render_with_format(json_response, options, 'optionTypeList')
|
127
140
|
return 0 if render_result
|
@@ -142,12 +155,14 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
142
155
|
"ID" => 'id',
|
143
156
|
"Name" => 'name',
|
144
157
|
"Description" => 'description',
|
145
|
-
"Type" => lambda {|it| it['type']
|
158
|
+
"Type" => lambda {|it| it['type'] },
|
159
|
+
"API Type" => lambda {|it| it['apiType'] },
|
146
160
|
"Source URL" => 'sourceUrl',
|
147
161
|
"Real Time" => lambda {|it| format_boolean it['realTime'] },
|
148
162
|
"Ignore SSL Errors" => lambda {|it| format_boolean it['ignoreSSLErrors'] },
|
149
163
|
"Source Method" => lambda {|it| it['sourceMethod'].to_s.upcase }
|
150
164
|
}
|
165
|
+
option_list_columns.delete("API Type") if option_type_list['type'] != 'api'
|
151
166
|
source_headers = []
|
152
167
|
if option_type_list['config'] && option_type_list['config']['sourceHeaders']
|
153
168
|
source_headers = option_type_list['config']['sourceHeaders'].collect do |header|
|
@@ -174,12 +189,13 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
174
189
|
print reset,"#{option_type_list['requestScript']}","\n",reset
|
175
190
|
end
|
176
191
|
end
|
177
|
-
if options[:
|
178
|
-
|
192
|
+
if options[:list_items]
|
193
|
+
print_h2 "List Items"
|
179
194
|
if list_items && list_items.size > 0
|
180
|
-
print_h2 "List Items"
|
181
195
|
print as_pretty_table(list_items, [:name, :value], options)
|
182
196
|
print_results_pagination({size: list_items.size, total: list_items.size})
|
197
|
+
else
|
198
|
+
print cyan,"No list items found.",reset,"\n"
|
183
199
|
end
|
184
200
|
end
|
185
201
|
print reset,"\n"
|
@@ -189,6 +205,42 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
189
205
|
end
|
190
206
|
end
|
191
207
|
|
208
|
+
def list_items(args)
|
209
|
+
params = {}
|
210
|
+
options = {}
|
211
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
212
|
+
opts.banner = subcommand_usage("[name]")
|
213
|
+
build_standard_get_options(opts, options)
|
214
|
+
opts.footer = "List items for an option list.\n" +
|
215
|
+
"[name] is required. This is the name or id of an option list."
|
216
|
+
end
|
217
|
+
optparse.parse!(args)
|
218
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
219
|
+
connect(options)
|
220
|
+
option_type_list = find_option_type_list_by_name_or_id(args[0])
|
221
|
+
return 1 if option_type_list.nil?
|
222
|
+
|
223
|
+
params.merge!(parse_list_options(options))
|
224
|
+
@option_type_lists_interface.setopts(options)
|
225
|
+
if options[:dry_run]
|
226
|
+
print_dry_run @option_type_lists_interface.dry.list_items(option_type_list['id'], params)
|
227
|
+
return
|
228
|
+
end
|
229
|
+
json_response = @option_type_lists_interface.list_items(option_type_list['id'], params)
|
230
|
+
list_items = json_response['listItems']
|
231
|
+
render_response(json_response, options, "listItems") do
|
232
|
+
print_h2 "List Items"
|
233
|
+
if list_items && list_items.size > 0
|
234
|
+
print as_pretty_table(list_items, [:name, :value], options)
|
235
|
+
print_results_pagination({size: list_items.size, total: list_items.size})
|
236
|
+
else
|
237
|
+
print cyan,"No list items found.",reset,"\n"
|
238
|
+
end
|
239
|
+
print reset,"\n"
|
240
|
+
end
|
241
|
+
return 0, nil
|
242
|
+
end
|
243
|
+
|
192
244
|
def add(args)
|
193
245
|
options = {}
|
194
246
|
my_option_types = nil
|
@@ -373,7 +425,7 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
373
425
|
{'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'realTime', 'fieldLabel' => 'Real Time', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 7},
|
374
426
|
{'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'sourceMethod', 'fieldLabel' => 'Source Method', 'type' => 'select', 'selectOptions' => [{'name' => 'GET', 'value' => 'GET'}, {'name' => 'POST', 'value' => 'POST'}], 'defaultValue' => 'GET', 'required' => true, 'displayOrder' => 8},
|
375
427
|
# sourceHeaders component (is done afterwards manually)
|
376
|
-
{'dependsOnCode' => 'optionTypeList.type:api', 'fieldName' => 'apiType', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'apiOptionLists', 'required' => true, 'description' => 'The code of the api list to use, eg. clouds, servers,
|
428
|
+
{'dependsOnCode' => 'optionTypeList.type:api', 'fieldName' => 'apiType', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'apiOptionLists', 'required' => true, 'description' => 'The code of the api option list to use, eg. clouds, environments, groups, instances, instance-wiki, networks, servicePlans, resourcePools, securityGroups, servers, server-wiki', 'displayOrder' => 9},
|
377
429
|
{'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'sourceUsername', 'fieldLabel' => 'Source Username', 'type' => 'text', 'description' => "An LDAP Username for use when type is 'ldap'.", 'displayOrder' => 10},
|
378
430
|
{'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'sourcePassword', 'fieldLabel' => 'Source Username', 'type' => 'text', 'description' => "An LDAP Password for use when type is 'ldap'.", 'displayOrder' => 11},
|
379
431
|
{'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'ldapQuery', 'fieldLabel' => 'LDAP Query', 'type' => 'text', 'description' => "LDAP Queries are standard LDAP formatted queries where different objects can be searched. Dependent parameters can be loaded into the query using the <%=phrase%> syntax.", 'displayOrder' => 12},
|
@@ -35,6 +35,10 @@ class Morpheus::Cli::LibraryOptionTypesCommand
|
|
35
35
|
opts.footer = "List option types."
|
36
36
|
end
|
37
37
|
optparse.parse!(args)
|
38
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
39
|
+
if args.count > 0
|
40
|
+
options[:phrase] = args.join(" ")
|
41
|
+
end
|
38
42
|
connect(options)
|
39
43
|
begin
|
40
44
|
params = {}
|
@@ -26,12 +26,11 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
26
26
|
opts.footer = "List spec templates."
|
27
27
|
end
|
28
28
|
optparse.parse!(args)
|
29
|
-
|
29
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
30
30
|
if args.count > 0
|
31
|
-
|
32
|
-
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
33
|
-
return 1
|
31
|
+
options[:phrase] = args.join(" ")
|
34
32
|
end
|
33
|
+
connect(options)
|
35
34
|
begin
|
36
35
|
# construct payload
|
37
36
|
params.merge!(parse_list_options(options))
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# require 'yaml'
|
2
|
+
require 'io/console'
|
3
|
+
require 'rest_client'
|
4
|
+
require 'optparse'
|
5
|
+
require 'morpheus/cli/cli_command'
|
6
|
+
|
7
|
+
class Morpheus::Cli::LoadBalancerTypes
|
8
|
+
include Morpheus::Cli::CliCommand
|
9
|
+
include Morpheus::Cli::RestCommand
|
10
|
+
include Morpheus::Cli::LoadBalancersHelper
|
11
|
+
|
12
|
+
set_command_name :'load-balancer-types'
|
13
|
+
register_subcommands :list, :get
|
14
|
+
|
15
|
+
# register_interfaces :load_balancer_types
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def load_balancer_type_column_definitions
|
20
|
+
{
|
21
|
+
"ID" => 'id',
|
22
|
+
"Name" => 'name',
|
23
|
+
"Code" => 'code'
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_balancer_type_list_column_definitions
|
28
|
+
load_balancer_type_column_definitions
|
29
|
+
end
|
30
|
+
|
31
|
+
# overridden to support name or code
|
32
|
+
def find_load_balancer_type_by_name_or_id(name)
|
33
|
+
load_balancer_type_for_name_or_id(name)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
@@ -1,161 +1,106 @@
|
|
1
1
|
# require 'yaml'
|
2
|
-
require 'io/console'
|
3
|
-
require 'rest_client'
|
4
|
-
require 'optparse'
|
5
2
|
require 'morpheus/cli/cli_command'
|
6
3
|
|
7
4
|
class Morpheus::Cli::LoadBalancers
|
8
5
|
include Morpheus::Cli::CliCommand
|
6
|
+
include Morpheus::Cli::RestCommand
|
7
|
+
include Morpheus::Cli::LoadBalancersHelper
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def initialize()
|
14
|
-
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
15
|
-
end
|
16
|
-
|
17
|
-
def connect(opts)
|
18
|
-
@api_client = establish_remote_appliance_connection(opts)
|
19
|
-
@load_balancers_interface = @api_client.load_balancers
|
20
|
-
end
|
9
|
+
set_command_name :'load-balancers'
|
10
|
+
register_subcommands :list, :get, :add, :update, :remove
|
21
11
|
|
12
|
+
# deprecated the `load-balancers types` command in 5.3.2, it moved to `load-balancer-types list`
|
13
|
+
register_subcommands :types
|
14
|
+
set_subcommands_hidden :types
|
22
15
|
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
# RestCommand settings
|
17
|
+
register_interfaces :load_balancers, :load_balancer_types
|
18
|
+
set_rest_has_type true
|
19
|
+
# set_rest_type :load_balancer_types
|
26
20
|
|
27
|
-
def
|
28
|
-
options
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
if options[:json]
|
47
|
-
puts as_json(json_response, options, "loadBalancers")
|
48
|
-
return 0
|
49
|
-
elsif options[:csv]
|
50
|
-
puts records_as_csv(json_response["loadBalancers"], options)
|
51
|
-
return 0
|
52
|
-
elsif options[:yaml]
|
53
|
-
puts as_yaml(json_response, options, "loadBalancers")
|
54
|
-
return 0
|
55
|
-
else
|
56
|
-
lbs = json_response['loadBalancers']
|
57
|
-
print_h1 "Morpheus Load Balancers"
|
58
|
-
if lbs.empty?
|
59
|
-
print cyan,"No load balancers found.",reset,"\n"
|
60
|
-
else
|
61
|
-
columns = [
|
62
|
-
{"ID" => 'id'},
|
63
|
-
{"Name" => 'name'},
|
64
|
-
{"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' } },
|
65
|
-
{"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' } },
|
66
|
-
{"Host" => lambda {|it| it['host'] } },
|
67
|
-
]
|
68
|
-
print as_pretty_table(lbs, columns, options)
|
69
|
-
end
|
70
|
-
print reset,"\n"
|
71
|
-
return 0
|
21
|
+
def render_response_for_get(json_response, options)
|
22
|
+
render_response(json_response, options, rest_object_key) do
|
23
|
+
record = json_response[rest_object_key]
|
24
|
+
print_h1 rest_label, [], options
|
25
|
+
print cyan
|
26
|
+
print_description_list(rest_column_definitions, record, options)
|
27
|
+
# show LB Ports
|
28
|
+
ports = record['ports']
|
29
|
+
if ports && ports.size > 0
|
30
|
+
print_h2 "LB Ports", options
|
31
|
+
columns = [
|
32
|
+
{"ID" => 'id'},
|
33
|
+
{"Name" => 'name'},
|
34
|
+
#{"Description" => 'description'},
|
35
|
+
{"Port" => lambda {|it| it['port'] } },
|
36
|
+
{"Protocol" => lambda {|it| it['proxyProtocol'] } },
|
37
|
+
{"SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" } },
|
38
|
+
]
|
39
|
+
print as_pretty_table(ports, columns, options)
|
72
40
|
end
|
73
|
-
|
74
|
-
print_rest_exception(e, options)
|
75
|
-
return 1
|
41
|
+
print reset,"\n"
|
76
42
|
end
|
77
43
|
end
|
78
44
|
|
79
|
-
|
45
|
+
=begin
|
46
|
+
|
47
|
+
# now using RestCommand
|
48
|
+
|
49
|
+
def add(args)
|
50
|
+
lb_type_name = nil
|
80
51
|
options = {}
|
81
52
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
82
|
-
opts.banner = subcommand_usage("[name]")
|
83
|
-
|
53
|
+
opts.banner = subcommand_usage("[name] -t LB_TYPE")
|
54
|
+
opts.on( '-t', '--type CODE', "Load Balancer Type" ) do |val|
|
55
|
+
lb_type_name = val
|
56
|
+
end
|
57
|
+
#build_option_type_options(opts, options, add_load_balancer_option_types)
|
58
|
+
build_standard_add_options(opts, options)
|
84
59
|
end
|
85
60
|
optparse.parse!(args)
|
86
|
-
|
61
|
+
lb_name = args[0]
|
62
|
+
# verify_args!(args:args, optparse:optparse, min:0, max: 1)
|
63
|
+
verify_args!(args:args, optparse:optparse, min:1, max: 1)
|
64
|
+
if lb_type_name.nil?
|
65
|
+
raise_command_error "Load Balancer Type is required.\n#{optparse}"
|
87
66
|
puts optparse
|
88
67
|
exit 1
|
89
68
|
end
|
90
|
-
lb_name = args[0]
|
91
69
|
connect(options)
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
if lb_name.to_s =~ /\A\d{1,}\Z/
|
96
|
-
print_dry_run @load_balancers_interface.dry.get(lb_name.to_i)
|
97
|
-
else
|
98
|
-
print_dry_run @load_balancers_interface.dry.list({name:lb_name})
|
99
|
-
end
|
100
|
-
return
|
101
|
-
end
|
102
|
-
lb = find_lb_by_name_or_id(lb_name)
|
103
|
-
exit 1 if lb.nil?
|
104
|
-
# refetch
|
105
|
-
json_response = @load_balancers_interface.get(lb['id'])
|
106
|
-
lb_type = load_balancer_type_for_name_or_id(lb['type']['code'])
|
107
|
-
#puts "LB TYPE: #{lb_type}"
|
108
|
-
if options[:json]
|
109
|
-
puts JSON.pretty_generate({loadBalancer: lb})
|
110
|
-
puts as_json(json_response, options, "loadBalancer")
|
111
|
-
return 0
|
112
|
-
elsif options[:csv]
|
113
|
-
puts records_as_csv(json_response["loadBalancer"], options)
|
114
|
-
return 0
|
115
|
-
elsif options[:yaml]
|
116
|
-
puts as_yaml(json_response, options, "loadBalancer")
|
117
|
-
return 0
|
118
|
-
else
|
119
|
-
print_h1 "Load Balancer Details"
|
120
|
-
description_cols = {
|
121
|
-
"ID" => 'id',
|
122
|
-
"Name" => 'name',
|
123
|
-
"Description" => 'description',
|
124
|
-
"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
|
125
|
-
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
126
|
-
"Visibility" => 'visibility',
|
127
|
-
"IP" => 'ip',
|
128
|
-
"Host" => 'host',
|
129
|
-
"Port" => 'port',
|
130
|
-
"Username" => 'username',
|
131
|
-
# "SSL Enabled" => lambda {|it| format_boolean it['sslEnabled'] },
|
132
|
-
# "SSL Cert" => lambda {|it| it['sslCert'] ? it['sslCert']['name'] : '' },
|
133
|
-
# "SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" },
|
134
|
-
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
135
|
-
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
136
|
-
}
|
137
|
-
print_description_list(description_cols, lb)
|
138
|
-
|
139
|
-
|
140
|
-
if lb['ports'] && lb['ports'].size > 0
|
141
|
-
print_h2 "LB Ports"
|
142
|
-
columns = [
|
143
|
-
{"ID" => 'id'},
|
144
|
-
{"Name" => 'name'},
|
145
|
-
#{"Description" => 'description'},
|
146
|
-
{"Port" => lambda {|it| it['port'] } },
|
147
|
-
{"Protocol" => lambda {|it| it['proxyProtocol'] } },
|
148
|
-
{"SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" } },
|
149
|
-
]
|
150
|
-
print as_pretty_table(lb['ports'], columns, options)
|
151
|
-
end
|
152
|
-
print reset,"\n"
|
153
|
-
return 0
|
154
|
-
end
|
155
|
-
rescue RestClient::Exception => e
|
156
|
-
print_rest_exception(e, options)
|
70
|
+
lb_type = load_balancer_type_for_name_or_id(lb_type_name)
|
71
|
+
if lb_type.nil?
|
72
|
+
print_red_alert "LB Type #{lb_type_name} not found!"
|
157
73
|
exit 1
|
158
74
|
end
|
75
|
+
passed_options = parse_passed_options(options)
|
76
|
+
payload = {}
|
77
|
+
if options[:payload]
|
78
|
+
payload = options[:payload]
|
79
|
+
payload.deep_merge!({load_balancer_object_key => passed_options})
|
80
|
+
else
|
81
|
+
load_balancer_payload = {'name' => lb_name, 'type' => {'code' => lb_type['code'], 'id' => lb_type['id']}}
|
82
|
+
load_balancer_payload.deep_merge!({load_balancer_object_key => passed_options})
|
83
|
+
# options by type
|
84
|
+
my_option_types = lb_type['optionTypes']
|
85
|
+
if my_option_types && !my_option_types.empty?
|
86
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, options[:params])
|
87
|
+
v_prompt.deep_compact!
|
88
|
+
load_balancer_payload.deep_merge!(v_prompt)
|
89
|
+
end
|
90
|
+
payload[load_balancer_object_key] = load_balancer_payload
|
91
|
+
end
|
92
|
+
@load_balancers_interface.setopts(options)
|
93
|
+
if options[:dry_run]
|
94
|
+
print_dry_run @load_balancers_interface.dry.create(payload)
|
95
|
+
return
|
96
|
+
end
|
97
|
+
json_response = @load_balancers_interface.create(payload)
|
98
|
+
render_response(json_response, options, load_balancer_object_key) do
|
99
|
+
load_balancer = json_response[load_balancer_object_key]
|
100
|
+
print_green_success "Added load balancer #{load_balancer['name']}"
|
101
|
+
return _get(load_balancer["id"], {}, options)
|
102
|
+
end
|
103
|
+
return 0, nil
|
159
104
|
end
|
160
105
|
|
161
106
|
def update(args)
|
@@ -163,8 +108,8 @@ class Morpheus::Cli::LoadBalancers
|
|
163
108
|
options = {}
|
164
109
|
account_name = nil
|
165
110
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
166
|
-
opts.banner = subcommand_usage("[
|
167
|
-
|
111
|
+
opts.banner = subcommand_usage("[lb] [options]")
|
112
|
+
build_standard_update_options(opts, options)
|
168
113
|
end
|
169
114
|
optparse.parse!(args)
|
170
115
|
if args.count < 1
|
@@ -172,141 +117,47 @@ class Morpheus::Cli::LoadBalancers
|
|
172
117
|
exit 1
|
173
118
|
end
|
174
119
|
connect(options)
|
175
|
-
begin
|
176
|
-
|
177
|
-
lb = find_lb_by_name_or_id(lb_name)
|
178
|
-
exit 1 if lb.nil?
|
179
|
-
lb_type = load_balancer_type_for_name_or_id(lb['type']['code'])
|
180
|
-
|
181
|
-
#params = Morpheus::Cli::OptionTypes.prompt(add_load_balancer_option_types, options[:options], @api_client, options[:params]) # options[:params] is mysterious
|
182
|
-
params = options[:options] || {}
|
183
|
-
|
184
|
-
if params.empty?
|
185
|
-
puts optparse
|
186
|
-
option_lines = update_task_option_types(lb_type).collect {|it| "\t-O #{it['fieldContext'] ? (it['fieldContext'] + '.') : ''}#{it['fieldName']}=\"value\"" }.join("\n")
|
187
|
-
puts "\nAvailable Options:\n#{option_lines}\n\n"
|
188
|
-
exit 1
|
189
|
-
end
|
190
120
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
if params['taskOptions']
|
201
|
-
task_payload['taskOptions'].merge!(params['taskOptions'])
|
202
|
-
end
|
203
|
-
payload = {task: task_payload}
|
204
|
-
@load_balancers_interface.setopts(options)
|
205
|
-
if options[:dry_run]
|
206
|
-
print_dry_run @load_balancers_interface.dry.update(task['id'], payload)
|
207
|
-
return
|
121
|
+
passed_options = parse_passed_options(options)
|
122
|
+
payload = nil
|
123
|
+
if options[:payload]
|
124
|
+
payload = options[:payload]
|
125
|
+
payload.deep_merge!({load_balancer_object_key => passed_options}) unless passed_options.empty?
|
126
|
+
else
|
127
|
+
load_balancer_payload = passed_options
|
128
|
+
if tenants_list
|
129
|
+
load_balancer_payload['accounts'] = tenants_list
|
208
130
|
end
|
209
|
-
|
210
|
-
if options[:
|
211
|
-
|
212
|
-
if !response['success']
|
213
|
-
exit 1
|
214
|
-
end
|
131
|
+
# metadata tags
|
132
|
+
if options[:tags]
|
133
|
+
load_balancer_payload['tags'] = parse_metadata(options[:tags])
|
215
134
|
else
|
216
|
-
|
135
|
+
# tags = prompt_metadata(options)
|
136
|
+
# payload[load_balancer_object_key]['tags'] = tags of tags
|
217
137
|
end
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
|
225
|
-
def lb_types(args)
|
226
|
-
options = {}
|
227
|
-
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
228
|
-
opts.banner = subcommand_usage()
|
229
|
-
build_common_options(opts, options, [:json, :dry_run, :remote])
|
230
|
-
end
|
231
|
-
optparse.parse!(args)
|
232
|
-
connect(options)
|
233
|
-
begin
|
234
|
-
@load_balancers_interface.setopts(options)
|
235
|
-
if options[:dry_run]
|
236
|
-
print_dry_run @load_balancers_interface.dry.load_balancer_types()
|
237
|
-
return
|
138
|
+
# metadata tags
|
139
|
+
if options[:add_tags]
|
140
|
+
load_balancer_payload['addTags'] = parse_metadata(options[:add_tags])
|
238
141
|
end
|
239
|
-
|
240
|
-
|
241
|
-
print JSON.pretty_generate(json_response)
|
242
|
-
else
|
243
|
-
lb_types = json_response['loadBalancerTypes']
|
244
|
-
print_h1 "Morpheus Load Balancer Types"
|
245
|
-
if lb_types.nil? || lb_types.empty?
|
246
|
-
print cyan,"No load balancer types found.",reset,"\n"
|
247
|
-
else
|
248
|
-
print cyan
|
249
|
-
lb_table_data = lb_types.collect do |lb_type|
|
250
|
-
{name: lb_type['name'], id: lb_type['id'], code: lb_type['code']}
|
251
|
-
end
|
252
|
-
print as_pretty_table(lb_table_data, [:id, :name, :code], options)
|
253
|
-
end
|
254
|
-
|
255
|
-
print reset,"\n"
|
142
|
+
if options[:remove_tags]
|
143
|
+
load_balancer_payload['removeTags'] = parse_metadata(options[:remove_tags])
|
256
144
|
end
|
257
|
-
|
258
|
-
|
259
|
-
exit 1
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
# JD: This is broken.. copied from tasks? should optionTypes exist?
|
264
|
-
def add(args)
|
265
|
-
lb_type_name = nil
|
266
|
-
options = {}
|
267
|
-
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
268
|
-
opts.banner = subcommand_usage("[name] -t LB_TYPE")
|
269
|
-
opts.on( '-t', '--type LB_TYPE', "Load Balancer Type" ) do |val|
|
270
|
-
lb_type_name = val
|
145
|
+
if load_balancer_payload.empty?
|
146
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
271
147
|
end
|
272
|
-
|
273
|
-
end
|
274
|
-
optparse.parse!(args)
|
275
|
-
lb_name = args[0]
|
276
|
-
if args.count < 1
|
277
|
-
puts optparse
|
278
|
-
exit 1
|
148
|
+
payload = {'virtualImage' => load_balancer_payload}
|
279
149
|
end
|
280
|
-
|
281
|
-
|
282
|
-
|
150
|
+
@load_balancers_interface.setopts(options)
|
151
|
+
if options[:dry_run]
|
152
|
+
print_dry_run @load_balancers_interface.dry.update(load_balancer['id'], payload)
|
153
|
+
return
|
283
154
|
end
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
print_red_alert "LB Type #{lb_type_name} not found!"
|
289
|
-
exit 1
|
290
|
-
end
|
291
|
-
|
292
|
-
payload = {loadBalancer: {name: lb_name, type: {code: lb_type['code'], id: lb_type['id']}}}
|
293
|
-
# todo: The options available here are specific by type...
|
294
|
-
#input_options = Morpheus::Cli::OptionTypes.prompt(lb_type['optionTypes'],options[:options],@api_client, options[:params])
|
295
|
-
@load_balancers_interface.setopts(options)
|
296
|
-
if options[:dry_run]
|
297
|
-
print_dry_run @load_balancers_interface.dry.create(payload)
|
298
|
-
return
|
299
|
-
end
|
300
|
-
json_response = @load_balancers_interface.create(payload)
|
301
|
-
if options[:json]
|
302
|
-
print JSON.pretty_generate(json_response)
|
303
|
-
else
|
304
|
-
print "\n", cyan, "LB #{json_response['loadBalancer']['name']} created successfully", reset, "\n\n"
|
305
|
-
end
|
306
|
-
rescue RestClient::Exception => e
|
307
|
-
print_rest_exception(e, options)
|
308
|
-
exit 1
|
155
|
+
json_response = @load_balancers_interface.update(load_balancer['id'], payload)
|
156
|
+
render_response(json_response, options, 'virtualImage') do
|
157
|
+
print_green_success "Updated virtual image #{load_balancer['name']}"
|
158
|
+
_get(load_balancer["id"], {}, options)
|
309
159
|
end
|
160
|
+
return 0, nil
|
310
161
|
end
|
311
162
|
|
312
163
|
def remove(args)
|
@@ -323,7 +174,7 @@ class Morpheus::Cli::LoadBalancers
|
|
323
174
|
end
|
324
175
|
connect(options)
|
325
176
|
begin
|
326
|
-
lb =
|
177
|
+
lb = find_load_balancer_by_name_or_id(lb_name)
|
327
178
|
exit 1 if lb.nil?
|
328
179
|
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the load balancer #{lb['name']}?")
|
329
180
|
exit
|
@@ -344,67 +195,51 @@ class Morpheus::Cli::LoadBalancers
|
|
344
195
|
exit 1
|
345
196
|
end
|
346
197
|
end
|
198
|
+
=end
|
347
199
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
353
|
-
return find_lb_by_id(val)
|
354
|
-
else
|
355
|
-
return find_lb_by_name(val)
|
356
|
-
end
|
200
|
+
# deprecated, to be removed in the future.
|
201
|
+
def types(args)
|
202
|
+
print_error yellow,"[DEPRECATED] The command `load-balancers types` is deprecated and replaced by `load-balancer-types list`.",reset,"\n"
|
203
|
+
my_terminal.execute("load-balancer-types list #{args.join(' ')}")
|
357
204
|
end
|
358
205
|
|
359
|
-
|
360
|
-
begin
|
361
|
-
json_response = @load_balancers_interface.get(id.to_i)
|
362
|
-
return json_response['loadBalancer']
|
363
|
-
rescue RestClient::Exception => e
|
364
|
-
if e.response && e.response.code == 404
|
365
|
-
print_red_alert "Load Balancer not found by id #{id}"
|
366
|
-
else
|
367
|
-
raise e
|
368
|
-
end
|
369
|
-
end
|
370
|
-
end
|
206
|
+
protected
|
371
207
|
|
372
|
-
def
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
print reset,"\n\n"
|
381
|
-
return nil
|
382
|
-
else
|
383
|
-
return lbs[0]
|
384
|
-
end
|
208
|
+
def load_balancer_list_column_definitions()
|
209
|
+
{
|
210
|
+
"ID" => 'id',
|
211
|
+
"Name" => 'name',
|
212
|
+
"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
|
213
|
+
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
214
|
+
"Host" => lambda {|it| it['host'] }
|
215
|
+
}
|
385
216
|
end
|
386
217
|
|
387
|
-
def
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
218
|
+
def load_balancer_column_definitions()
|
219
|
+
{
|
220
|
+
"ID" => 'id',
|
221
|
+
"Name" => 'name',
|
222
|
+
"Description" => 'description',
|
223
|
+
"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
|
224
|
+
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
225
|
+
"Visibility" => 'visibility',
|
226
|
+
"IP" => 'ip',
|
227
|
+
"Host" => 'host',
|
228
|
+
"Port" => 'port',
|
229
|
+
"Username" => 'username',
|
230
|
+
# "SSL Enabled" => lambda {|it| format_boolean it['sslEnabled'] },
|
231
|
+
# "SSL Cert" => lambda {|it| it['sslCert'] ? it['sslCert']['name'] : '' },
|
232
|
+
# "SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" },
|
233
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
234
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
235
|
+
}
|
392
236
|
end
|
393
237
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
else
|
398
|
-
return load_balancer_type_for_name(val)
|
399
|
-
end
|
238
|
+
# overridden to work with name or code
|
239
|
+
def find_load_balancer_type_by_name_or_id(name)
|
240
|
+
load_balancer_type_for_name_or_id(name)
|
400
241
|
end
|
401
242
|
|
402
|
-
def load_balancer_type_for_id(id)
|
403
|
-
return get_available_load_balancer_types().find { |z| z['id'].to_i == id.to_i}
|
404
|
-
end
|
405
243
|
|
406
|
-
def load_balancer_type_for_name(name)
|
407
|
-
return get_available_load_balancer_types().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
|
408
|
-
end
|
409
244
|
|
410
245
|
end
|