morpheus-cli 5.3.2 → 5.3.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- register_subcommands :list, :get, :add, :update, :remove, {:types => :lb_types}
11
- alias_subcommand :details, :get
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
- def handle(args)
24
- handle_subcommand(args)
25
- end
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 list(args)
28
- options = {}
29
- optparse = Morpheus::Cli::OptionParser.new do |opts|
30
- opts.banner = subcommand_usage()
31
- build_common_options(opts, options, [:list, :json, :csv, :yaml, :fields, :dry_run, :remote])
32
- end
33
- optparse.parse!(args)
34
- connect(options)
35
- begin
36
- params = {}
37
- [:phrase, :offset, :max, :sort, :direction].each do |k|
38
- params[k] = options[k] unless options[k].nil?
39
- end
40
- @load_balancers_interface.setopts(options)
41
- if options[:dry_run]
42
- print_dry_run @load_balancers_interface.dry.list(params)
43
- return
44
- end
45
- json_response = @load_balancers_interface.list(params)
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
- rescue RestClient::Exception => e
74
- print_rest_exception(e, options)
75
- return 1
41
+ print reset,"\n"
76
42
  end
77
43
  end
78
44
 
79
- def get(args)
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
- build_common_options(opts, options, [:json, :csv, :yaml, :fields, :dry_run, :remote])
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
- if args.count < 1
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
- begin
93
- @load_balancers_interface.setopts(options)
94
- if options[:dry_run]
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("[name] [options]")
167
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
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
- # todo: fix this...
192
- #puts "parsed params is : #{params.inspect}"
193
- lb_keys = ['name']
194
- changes_payload = (params.select {|k,v| task_keys.include?(k) })
195
- task_payload = task
196
- if changes_payload
197
- task_payload.merge!(changes_payload)
198
- end
199
- puts params
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
- response = @load_balancers_interface.update(task['id'], payload)
210
- if options[:json]
211
- print JSON.pretty_generate(json_response)
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
- print "\n", cyan, "Task #{response['task']['name']} updated", reset, "\n\n"
135
+ # tags = prompt_metadata(options)
136
+ # payload[load_balancer_object_key]['tags'] = tags of tags
217
137
  end
218
- rescue RestClient::Exception => e
219
- print_rest_exception(e, options)
220
- exit 1
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
- json_response = @load_balancers_interface.load_balancer_types()
240
- if options[:json]
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
- rescue RestClient::Exception => e
258
- print_rest_exception(e, options)
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
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
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
- if lb_type_name.nil?
281
- puts optparse
282
- exit 1
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
- connect(options)
285
- begin
286
- lb_type = load_balancer_type_for_name_or_id(lb_type_name)
287
- if lb_type.nil?
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 = find_lb_by_name_or_id(lb_name)
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
- private
350
-
351
- def find_lb_by_name_or_id(val)
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
- def find_lb_by_id(id)
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 find_lb_by_name(name)
373
- lbs = @load_balancers_interface.list({name: name.to_s})['loadBalancers']
374
- if lbs.empty?
375
- print_red_alert "Load Balancer not found by name #{name}"
376
- return nil
377
- elsif lbs.size > 1
378
- print_red_alert "#{lbs.size} load balancers found by name #{name}"
379
- #print_lbs_table(lbs, {color: red})
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 get_available_load_balancer_types(refresh=false)
388
- if !@available_load_balancer_types || refresh
389
- @available_load_balancer_types = @load_balancers_interface.load_balancer_types['loadBalancerTypes']
390
- end
391
- return @available_load_balancer_types
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
- def load_balancer_type_for_name_or_id(val)
395
- if val.to_s =~ /\A\d{1,}\Z/
396
- return load_balancer_type_for_id(val)
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