morpheus-cli 2.9.4 → 2.10.0

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.
@@ -10,7 +10,6 @@ class Morpheus::Cli::DashboardCommand
10
10
 
11
11
  def initialize()
12
12
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
13
- @active_groups = ::Morpheus::Cli::Groups.load_group_file
14
13
  end
15
14
 
16
15
  def connect(opts)
@@ -16,8 +16,6 @@ class Morpheus::Cli::Deploys
16
16
  @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
17
17
  @instances_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instances
18
18
  @deploy_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).deploy
19
- @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
20
- @active_groups = ::Morpheus::Cli::Groups.load_group_file
21
19
  end
22
20
 
23
21
  def handle(args)
@@ -13,7 +13,6 @@ class Morpheus::Cli::Hosts
13
13
 
14
14
  def initialize()
15
15
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
- @active_groups = ::Morpheus::Cli::Groups.load_group_file
17
16
  end
18
17
 
19
18
  def connect(opts)
@@ -26,12 +25,12 @@ class Morpheus::Cli::Hosts
26
25
  end
27
26
  @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
28
27
  @clouds_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).clouds
29
- @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
28
+ @options_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).options
29
+ @active_groups = ::Morpheus::Cli::Groups.load_group_file
30
30
  @tasks_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).tasks
31
31
  @task_sets_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).task_sets
32
32
  @servers_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).servers
33
33
  @logs_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).logs
34
- @cloud_types = @clouds_interface.cloud_types['zoneTypes']
35
34
  if @access_token.empty?
36
35
  print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
37
36
  exit 1
@@ -83,7 +82,7 @@ class Morpheus::Cli::Hosts
83
82
  optparse.parse(args)
84
83
  connect(options)
85
84
  begin
86
- host = find_host_by_name(args[0])
85
+ host = find_host_by_name_or_id(args[0])
87
86
  logs = @logs_interface.server_logs([host['id']], { max: options[:max] || 100, offset: options[:offset] || 0, query: options[:phrase]})
88
87
  if options[:json]
89
88
  print JSON.pretty_generate(logs)
@@ -128,18 +127,17 @@ class Morpheus::Cli::Hosts
128
127
 
129
128
  zone=nil
130
129
 
131
-
132
130
  if !options[:zone].nil?
133
131
  zone = find_zone_by_name(nil, options[:zone])
134
132
  end
135
133
 
136
134
  if zone.nil?
137
- print_red_alert "Cloud not found"
135
+ print_red_alert "Cloud not found for a"
138
136
  exit 1
139
137
  else
140
- zone_type = cloud_type_for_id(zone['zoneTypeId'])
138
+ cloud_type = cloud_type_for_id(zone['zoneTypeId'])
141
139
  end
142
- cloud_server_types = zone_type['serverTypes'].select{|b| b['creatable'] == true}
140
+ cloud_server_types = cloud_type['serverTypes'].select{|b| b['creatable'] == true}
143
141
  if options[:json]
144
142
  print JSON.pretty_generate(cloud_server_types)
145
143
  print "\n"
@@ -158,60 +156,97 @@ class Morpheus::Cli::Hosts
158
156
  end
159
157
 
160
158
  def add(args)
161
-
162
- options = {zone: args[0], params:{}}
163
- name = args[1]
164
-
159
+ options = {}
165
160
  optparse = OptionParser.new do|opts|
166
- opts.banner = "Usage: morpheus hosts add CLOUD NAME [options]"
167
- opts.on( '-t', '--type TYPE', "Server Type" ) do |server_type|
168
- options[:server_type] = server_type
161
+ opts.banner = "Usage: morpheus hosts add"
162
+ opts.on( '-g', '--group GROUP', "Group Name" ) do |val|
163
+ options[:group_name] = val
164
+ end
165
+ opts.on( '-G', '--group-id ID', "Group Id" ) do |val|
166
+ options[:group_id] = val
167
+ end
168
+ opts.on( '-c', '--cloud CLOUD', "Cloud Name" ) do |val|
169
+ options[:cloud_name] = val
170
+ end
171
+ opts.on( '-t', '--type TYPE', "Server Type" ) do |val|
172
+ options[:server_type_code] = val
169
173
  end
170
174
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
171
175
  end
172
- if args.count < 2
173
- puts "\n#{optparse}\n\n"
174
- exit 1
175
- end
176
176
  optparse.parse(args)
177
-
178
177
  connect(options)
179
178
 
180
- params = {}
179
+ # support old format of `hosts add CLOUD NAME`
180
+ if args[0] && args[0] !~ /\A\-/
181
+ options[:cloud_name] = args[0]
182
+ if args[1] && args[1] !~ /\A\-/
183
+ options[:host_name] = args[1]
184
+ end
185
+ end
181
186
 
182
- zone=nil
183
- if !options[:zone].nil?
184
- zone = find_zone_by_name(nil, options[:zone])
185
- options[:params][:zoneId] = zone['id'] if zone
187
+ # use active group by default
188
+ if !options[:group_name] && !options[:group_id]
189
+ options[:group_id] = @active_groups[@appliance_name.to_sym]
186
190
  end
187
191
 
188
- if zone.nil?
189
- print_red_alert "Either the cloud was not specified or was not found. Please make sure a cloud is specified at the beginning of the argument."
190
- exit 1
192
+ params = {}
193
+
194
+ # Group
195
+ group_id = nil
196
+ group = find_group_from_options(options)
197
+ if group
198
+ group_id = group["id"]
191
199
  else
192
- zone_type = cloud_type_for_id(zone['zoneTypeId'])
200
+ # print_red_alert "Group not found or specified!"
201
+ # exit 1
202
+ group_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'type' => 'select', 'fieldLabel' => 'Group', 'selectOptions' => get_available_groups(), 'required' => true, 'description' => 'Select Group.'}],options[:options],@api_client,{})
203
+ group_id = cloud_prompt['group']
193
204
  end
194
205
 
195
- cloud_server_types = zone_type['serverTypes'].select{|b| b['creatable'] == true }.sort { |x,y| x['displayOrder'] <=> y['displayOrder'] }
196
- if options[:server_type]
197
- server_type_code = options[:server_type]
206
+ # Cloud
207
+ cloud_id = nil
208
+ cloud = find_cloud_from_options(group_id, options)
209
+ if cloud
210
+ cloud_id = cloud["id"]
211
+ else
212
+ # print_red_alert "Cloud not specified!"
213
+ # exit 1
214
+ cloud_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'type' => 'select', 'fieldLabel' => 'Cloud', 'selectOptions' => get_available_clouds(group_id), 'required' => true, 'description' => 'Select Cloud.'}],options[:options],@api_client,{groupId: group_id})
215
+ cloud_id = cloud_prompt['cloud']
216
+ cloud = find_cloud_by_id(group_id, cloud_id)
217
+ end
218
+
219
+ # Zone Type
220
+ cloud_type = cloud_type_for_id(cloud['zoneTypeId'])
221
+
222
+ # Server Type
223
+ cloud_server_types = cloud_type['serverTypes'].select{|b| b['creatable'] == true }.sort { |x,y| x['displayOrder'] <=> y['displayOrder'] }
224
+ if options[:server_type_code]
225
+ server_type_code = options[:server_type_code]
198
226
  else
199
227
  server_type_options = cloud_server_types.collect {|it| {'name' => it['name'], 'value' => it['code']} }
200
228
  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => "Server Type", 'selectOptions' => server_type_options, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a server type.'}], options[:options])
201
- server_type_code = v_prompt['type']
229
+ server_type_code = v_prompt['type']
202
230
  end
203
-
204
- server_type = cloud_server_types.find {|it| it['code'] == server_type_code }
205
-
231
+ server_type = cloud_server_types.find {|it| it['code'] == server_type_code }
206
232
  if server_type.nil?
207
- print_red_alert "Server Type #{server_type_code} not found cloud #{zone['name']}"
233
+ print_red_alert "Server Type #{server_type_code} not found cloud #{cloud['name']}"
208
234
  exit 1
209
235
  end
210
236
 
237
+ # Server Name
238
+ host_name = nil
239
+ if options[:host_name]
240
+ host_name = options[:host_name]
241
+ else
242
+ name_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Server Name', 'type' => 'text', 'required' => true}], options[:options])
243
+ host_name = name_prompt['name'] || ''
244
+ end
245
+
211
246
  payload = {}
212
247
 
213
248
  # prompt for service plan
214
- service_plans_json = @servers_interface.service_plans({zoneId: zone['id'], serverTypeId: server_type["id"]})
249
+ service_plans_json = @servers_interface.service_plans({zoneId: cloud['id'], serverTypeId: server_type["id"]})
215
250
  service_plans = service_plans_json["plans"]
216
251
  service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"]} } # already sorted
217
252
  plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this server'}],options[:options])
@@ -227,7 +262,7 @@ class Morpheus::Cli::Hosts
227
262
  # prompt for network interfaces (if supported)
228
263
  if server_type["provisionType"] && server_type["provisionType"]["id"] && server_type["provisionType"]["hasNetworks"]
229
264
  begin
230
- network_interfaces = prompt_network_interfaces(zone['id'], server_type["provisionType"]["id"], options, @api_client)
265
+ network_interfaces = prompt_network_interfaces(cloud['id'], server_type["provisionType"]["id"], options, @api_client)
231
266
  if !network_interfaces.empty?
232
267
  payload[:networkInterfaces] = network_interfaces
233
268
  end
@@ -249,31 +284,22 @@ class Morpheus::Cli::Hosts
249
284
  # remove cpu and memory option types, which now come from the plan
250
285
  server_type_option_types = reject_service_plan_option_types(server_type_option_types)
251
286
 
252
- params = Morpheus::Cli::OptionTypes.prompt(server_type_option_types,options[:options],@api_client, options[:params])
287
+ params = Morpheus::Cli::OptionTypes.prompt(server_type_option_types,options[:options],@api_client, {zoneId: cloud['id']})
253
288
  begin
254
289
  params['server'] = params['server'] || {}
255
290
  payload = payload.merge({
256
291
  server: {
257
- name: name,
258
- zone: {id: zone['id']},
292
+ name: host_name,
293
+ zone: {id: cloud['id']},
259
294
  computeServerType: {id: server_type['id']},
260
295
  plan: {id: service_plan["id"]}
261
296
  }.merge(params['server'])
262
297
  })
263
298
  payload[:network] = params['network'] if params['network']
264
299
  payload[:config] = params['config'] if params['config']
300
+
265
301
  if options[:dry_run]
266
- print "\n" ,cyan, bold, "DRY RUN\n","==================", "\n\n", reset
267
- print cyan
268
- print "Request: ", "\n"
269
- print reset
270
- print "POST #{@appliance_url}/api/servers", "\n\n"
271
- print cyan
272
- print "JSON: ", "\n"
273
- print reset
274
- print JSON.pretty_generate(payload)
275
- print "\n"
276
- print reset
302
+ print_dry_run("POST #{@appliance_url}/api/servers", payload)
277
303
  return
278
304
  end
279
305
  json_response = @servers_interface.create(payload)
@@ -294,10 +320,7 @@ class Morpheus::Cli::Hosts
294
320
  options = {}
295
321
  query_params = {removeResources: 'on', force: 'off'}
296
322
  optparse = OptionParser.new do|opts|
297
- opts.banner = "Usage: morpheus hosts remove [name] [-c CLOUD] [-f] [-S]"
298
- opts.on( '-c', '--cloud CLOUD', "Cloud" ) do |cloud|
299
- options[:zone] = cloud
300
- end
323
+ opts.banner = "Usage: morpheus hosts remove [name] [-f] [-S]"
301
324
  opts.on( '-f', '--force', "Force Remove" ) do
302
325
  query_params[:force] = 'on'
303
326
  end
@@ -313,37 +336,13 @@ class Morpheus::Cli::Hosts
313
336
  exit 1
314
337
  end
315
338
  connect(options)
316
- zone=nil
317
- if !options[:zone].nil?
318
- zone = find_zone_by_name(nil, options[:zone])
319
- end
339
+
320
340
 
321
341
  begin
322
342
 
323
- if zone
324
- query_params[:zoneId] = zone['id']
325
- end
326
- server = nil
327
- server_results = @servers_interface.get({name: args[0]})
328
- if server_results['servers'].nil? || server_results['servers'].empty?
329
- server_results = @servers_interface.get(args[0].to_i)
330
- server = server_results['server']
331
- else
332
- if !server_results['servers'].empty? && server_results['servers'].count > 1
333
- puts "Multiple Servers exist with the same name. Try scoping by cloud or using id to confirm"
334
- exit 1
335
- end
336
- server = server_results['servers'][0] unless server_results['servers'].empty?
337
- end
338
-
339
- if server.nil?
340
- puts "Server not found by name #{args[0]}"
341
- exit 1
342
- else
343
-
344
- end
343
+ server = find_host_by_name_or_id(args[0])
345
344
 
346
- unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove this server?", options)
345
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the server '#{server['name']}'?", options)
347
346
  exit 1
348
347
  end
349
348
 
@@ -366,8 +365,8 @@ class Morpheus::Cli::Hosts
366
365
  params = {}
367
366
  optparse = OptionParser.new do|opts|
368
367
  opts.banner = "Usage: morpheus hosts list"
369
- opts.on( '-g', '--group GROUP', "Group Name" ) do |group|
370
- options[:group] = group
368
+ opts.on( '-g', '--group GROUP', "Group Name" ) do |val|
369
+ options[:group_name] = val
371
370
  end
372
371
 
373
372
  build_common_options(opts, options, [:list, :json, :remote])
@@ -376,11 +375,9 @@ class Morpheus::Cli::Hosts
376
375
  connect(options)
377
376
  begin
378
377
 
379
- if !options[:group].nil?
380
- group = find_group_by_name(options[:group])
381
- if !group.nil?
382
- params['site'] = group['id']
383
- end
378
+ group = find_group_from_options(options)
379
+ if group
380
+ params['site'] = group['id']
384
381
  end
385
382
 
386
383
  [:phrase, :offset, :max, :sort, :direction].each do |k|
@@ -436,7 +433,7 @@ class Morpheus::Cli::Hosts
436
433
  optparse.parse(args)
437
434
  connect(options)
438
435
  begin
439
- host = find_host_by_name(args[0])
436
+ host = find_host_by_name_or_id(args[0])
440
437
  json_response = @servers_interface.start(host['id'])
441
438
  if options[:json]
442
439
  print JSON.pretty_generate(json_response)
@@ -464,7 +461,7 @@ class Morpheus::Cli::Hosts
464
461
  optparse.parse(args)
465
462
  connect(options)
466
463
  begin
467
- host = find_host_by_name(args[0])
464
+ host = find_host_by_name_or_id(args[0])
468
465
  json_response = @servers_interface.stop(host['id'])
469
466
  if options[:json]
470
467
  print JSON.pretty_generate(json_response)
@@ -492,7 +489,7 @@ class Morpheus::Cli::Hosts
492
489
  optparse.parse(args)
493
490
  connect(options)
494
491
  begin
495
- host = find_host_by_name(args[0])
492
+ host = find_host_by_name_or_id(args[0])
496
493
  json_response = @servers_interface.upgrade(host['id'])
497
494
  if options[:json]
498
495
  print JSON.pretty_generate(json_response)
@@ -511,7 +508,7 @@ class Morpheus::Cli::Hosts
511
508
  options = {}
512
509
 
513
510
  optparse = OptionParser.new do|opts|
514
- opts.banner = "Usage: morpheus hosts run-workflow [HOST] [name] [options]"
511
+ opts.banner = "Usage: morpheus hosts run-workflow [HOST] [name]"
515
512
  build_common_options(opts, options, [:json, :remote])
516
513
  end
517
514
  if args.count < 2
@@ -521,7 +518,7 @@ class Morpheus::Cli::Hosts
521
518
 
522
519
  optparse.parse(args)
523
520
  connect(options)
524
- host = find_host_by_name(args[0])
521
+ host = find_host_by_name_or_id(args[0])
525
522
  workflow = find_workflow_by_name(args[1])
526
523
  task_types = @tasks_interface.task_types()
527
524
  editable_options = []
@@ -563,40 +560,40 @@ class Morpheus::Cli::Hosts
563
560
 
564
561
  private
565
562
 
566
- def find_host_by_name(name)
567
- server = nil
568
- server_results = @servers_interface.get({name: name})
569
- if server_results['servers'].nil? || server_results['servers'].empty?
570
- server_results = @servers_interface.get(name.to_i)
571
- server = server_results['server']
572
- else
573
- if !server_results['servers'].empty? && server_results['servers'].count > 1
574
- puts "Multiple Servers exist with the same name. Try using id to confirm"
575
- exit 1
576
- end
577
- server = server_results['servers'][0] unless server_results['servers'].empty?
563
+ def find_host_by_id(id)
564
+ results = @servers_interface.get(id.to_i)
565
+ if results['server'].empty?
566
+ print_red_alert "Server not found by id #{id}"
567
+ exit 1
578
568
  end
569
+ return results['server']
570
+ end
579
571
 
580
- if server.nil?
581
- puts "Server not found by name #{args[0]}"
572
+ def find_host_by_name(name)
573
+ results = @servers_interface.get({name: name})
574
+ if results['servers'].empty?
575
+ print_red_alert "Server not found by name #{name}"
576
+ exit 1
577
+ elsif results['servers'].size > 1
578
+ print_red_alert "Multiple Servers exist with the name #{name}. Try using id instead"
582
579
  exit 1
583
580
  end
584
- return server
581
+ return results['servers'][0]
585
582
  end
586
- def find_group_by_name(name)
587
- group_results = @groups_interface.get(name)
588
- if group_results['groups'].empty?
589
- puts "Group not found by name #{name}"
590
- return nil
583
+
584
+ def find_host_by_name_or_id(val)
585
+ if val.to_s =~ /\A\d{1,}\Z/
586
+ return find_host_by_id(val)
587
+ else
588
+ return find_host_by_name(val)
591
589
  end
592
- return group_results['groups'][0]
593
590
  end
594
591
 
595
592
  def find_zone_by_name(group_id, name)
596
593
  zone_results = @clouds_interface.get({groupId: group_id, name: name})
597
594
  if zone_results['zones'].empty?
598
- puts "Zone not found by name #{name}"
599
- return nil
595
+ print_red_alert "Cloud not found by name #{name}"
596
+ exit 1
600
597
  end
601
598
  return zone_results['zones'][0]
602
599
  end
@@ -606,19 +603,19 @@ private
606
603
  (sv_type['name'].downcase == name.downcase || sv_type['code'].downcase == name.downcase) && sv_type['creatable'] == true
607
604
  end
608
605
  if server_type.nil?
609
- puts "Server Type Not Selectable"
606
+ print_red_alert "Server Type Not Selectable"
610
607
  end
611
608
  return server_type
612
609
  end
613
610
 
614
611
  def cloud_type_for_id(id)
615
- if !@cloud_types.empty?
616
- zone_type = @cloud_types.find { |z| z['id'].to_i == id.to_i}
617
- if !zone_type.nil?
618
- return zone_type
619
- end
612
+ cloud_types = @clouds_interface.cloud_types['zoneTypes']
613
+ cloud_type = cloud_types.find { |z| z['id'].to_i == id.to_i}
614
+ if cloud_type.nil?
615
+ print_red_alert "Cloud Type not found by id #{id}"
616
+ exit 1
620
617
  end
621
- return nil
618
+ return cloud_type
622
619
  end
623
620
 
624
621
  def find_workflow_by_name(name)
@@ -626,17 +623,9 @@ private
626
623
  if !task_set_results['taskSets'].nil? && !task_set_results['taskSets'].empty?
627
624
  return task_set_results['taskSets'][0]
628
625
  else
629
- puts "Workflow not found by name #{name}"
626
+ print_red_alert "Workflow not found by name #{name}"
630
627
  exit 1
631
628
  end
632
629
  end
633
630
 
634
- def find_group_by_id(id)
635
- group_results = @groups_interface.get(id)
636
- if group_results['groups'].empty?
637
- puts "Group not found by id #{id}"
638
- return nil
639
- end
640
- return group_results['groups'][0]
641
- end
642
631
  end