morpheus-cli 5.5.3.1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +8 -0
  4. data/lib/morpheus/api/cloud_resource_pools_interface.rb +28 -3
  5. data/lib/morpheus/api/containers_interface.rb +10 -0
  6. data/lib/morpheus/api/doc_interface.rb +1 -10
  7. data/lib/morpheus/api/key_pairs_interface.rb +9 -0
  8. data/lib/morpheus/api/network_floating_ips_interface.rb +37 -0
  9. data/lib/morpheus/api/resource_pool_groups_interface.rb +51 -0
  10. data/lib/morpheus/cli/cli_command.rb +17 -11
  11. data/lib/morpheus/cli/commands/appliance_settings_command.rb +5 -0
  12. data/lib/morpheus/cli/commands/apps.rb +11 -5
  13. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +42 -12
  14. data/lib/morpheus/cli/commands/clusters.rb +23 -2
  15. data/lib/morpheus/cli/commands/containers_command.rb +129 -4
  16. data/lib/morpheus/cli/commands/doc.rb +14 -13
  17. data/lib/morpheus/cli/commands/hosts.rb +2 -0
  18. data/lib/morpheus/cli/commands/instances.rb +8 -2
  19. data/lib/morpheus/cli/commands/key_pairs.rb +94 -33
  20. data/lib/morpheus/cli/commands/network_floating_ips.rb +109 -0
  21. data/lib/morpheus/cli/commands/reports_command.rb +8 -1
  22. data/lib/morpheus/cli/commands/resource_pool_groups_command.rb +586 -0
  23. data/lib/morpheus/cli/commands/roles.rb +10 -10
  24. data/lib/morpheus/cli/commands/service_catalog_command.rb +44 -2
  25. data/lib/morpheus/cli/commands/tasks.rb +1 -1
  26. data/lib/morpheus/cli/commands/workflows.rb +1 -1
  27. data/lib/morpheus/cli/credentials.rb +2 -1
  28. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +148 -0
  29. data/lib/morpheus/cli/option_types.rb +15 -8
  30. data/lib/morpheus/cli/version.rb +1 -1
  31. data/lib/morpheus/cli.rb +13 -0
  32. data/test/cli/doc_test.rb +1 -1
  33. data/test/test_case.rb +3 -0
  34. metadata +6 -2
@@ -8,7 +8,7 @@ class Morpheus::Cli::ContainersCommand
8
8
  set_command_name :containers
9
9
  set_command_description "View and manage containers (nodes)."
10
10
  register_subcommands :get, :stop, :start, :restart, :suspend, :eject, :action, :actions, :logs,
11
- {:exec => :execution_request}, :clone_image, :import
11
+ {:exec => :execution_request}, :clone_image, :import, :attach_floating_ip, :detach_floating_ip
12
12
 
13
13
  def connect(opts)
14
14
  @api_client = establish_remote_appliance_connection(opts)
@@ -17,6 +17,7 @@ class Morpheus::Cli::ContainersCommand
17
17
  @provision_types_interface = @api_client.provision_types
18
18
  @logs_interface = @api_client.logs
19
19
  @execution_request_interface = @api_client.execution_request
20
+ @clouds_interface = @api_client.clouds
20
21
  end
21
22
 
22
23
  def handle(args)
@@ -696,7 +697,7 @@ EOT
696
697
  end
697
698
  json_response = @containers_interface.import(container['id'], payload)
698
699
  render_response(json_response, options) do
699
- print_green_success "Import initiated for container [#{container['id']}] #{container['name']}"
700
+ print_green_success "Import initiated for container #{container['id']}"
700
701
  end
701
702
  return 0, nil
702
703
  end
@@ -768,12 +769,121 @@ EOT
768
769
  end
769
770
  json_response = @containers_interface.clone_image(container['id'], payload)
770
771
  render_response(json_response, options) do
771
- print_green_success "Clone Image initiated for container [#{container['id']}] #{container['name']}"
772
+ print_green_success "Clone Image initiated for container #{container['id']}"
772
773
  end
773
774
  return 0, nil
774
775
  end
775
776
 
776
- private
777
+ def attach_floating_ip(args)
778
+ options = {}
779
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
780
+ opts.banner = subcommand_usage("[id]")
781
+ opts.on('--ip ID', String, "Floating IP Address, in the format 'ip-ID'.") do |val|
782
+ options[:ip] = val
783
+ end
784
+ opts.on('--pool ID', String, "Floating IP Pool Identifier, in the format 'pool-ID'.") do |val|
785
+ options[:pool] = val
786
+ end
787
+ opts.on('--bandwidth VALUE', String, "Floating IP Bandidth (Mbit/s). Only cloud types Huawei and OpenTelekom support this option.") do |val|
788
+ options[:bandwidth] = val
789
+ end
790
+ build_standard_update_options(opts, options, [:auto_confirm])
791
+ opts.footer = <<-EOT
792
+ Attach a floating IP to a container.
793
+ [id] is required. This is the id of a container.
794
+ Only the following cloud types support this command: OpenStack, Huawei and OpenTelekom
795
+ EOT
796
+ end
797
+ optparse.parse!(args)
798
+ verify_args!(args:args, optparse:optparse, count:1)
799
+ connect(options)
800
+ container = find_container_by_id(args[0])
801
+ return 1 if container.nil?
802
+ cloud_type = load_container_cloud_type(container)
803
+ if !cloud_type['hasFloatingIps']
804
+ raise_command_error "Cloud Type #{cloud_type['name']} does support floating IPs."
805
+ end
806
+ payload = parse_payload(options)
807
+ if payload.nil?
808
+ payload = parse_passed_options(options)
809
+ attach_floating_ip_option_types = cloud_type['floatingIpTypes']
810
+ if attach_floating_ip_option_types && !attach_floating_ip_option_types.empty?
811
+ if options[:ip]
812
+ floating_ip = options[:ip].to_s.sub(/\Aip\-/i, '')
813
+ floating_ip = (floating_ip =~ /\A\d{1,}\Z/) ? "ip-#{floating_ip.to_s}" : floating_ip
814
+ options[:options]['config'] ||= {}
815
+ options[:options]['config']['osExternalNetworkId'] = floating_ip
816
+ elsif options[:pool]
817
+ floating_ip = options[:pool].to_s.sub(/\Apool\-/i, '')
818
+ floating_ip = (floating_ip =~ /\A\d{1,}\Z/) ? "pool-#{floating_ip.to_s}" : floating_ip
819
+ options[:options]['config'] ||= {}
820
+ options[:options]['config']['osExternalNetworkId'] = floating_ip
821
+ end
822
+ if options[:bandwidth]
823
+ options[:options]['config'] ||= {}
824
+ options[:options]['config']['floatingIpBandwidth'] = options[:bandwidth].to_i
825
+ end
826
+ #api_params = {zoneId: container['cloud'] ? container['cloud']['id'] : nil, resourcePoolId: container['resourcePool'] ? container['resourcePool']['id'] : nil}
827
+ api_params = {containerId: container['id']}
828
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(attach_floating_ip_option_types, options[:options], @api_client, api_params)
829
+ # payload.deep_merge!({'container' => v_prompt})
830
+ payload.deep_merge!(v_prompt)
831
+ else
832
+ # raise_command_error "Cloud Type #{cloud_type['name']} does not defined any floating IP inputs."
833
+ end
834
+ end
835
+ confirm!("Are you sure you would like to attach this floating IP to container #{container['id']}?", options)
836
+ @containers_interface.setopts(options)
837
+ if options[:dry_run]
838
+ print_dry_run @containers_interface.dry.attach_floating_ip(container['id'], payload)
839
+ return
840
+ end
841
+ json_response = @containers_interface.attach_floating_ip(container['id'], payload)
842
+ render_response(json_response, options) do
843
+ print_green_success "Attaching floating IP to container #{container['id']}"
844
+ end
845
+ return 0, nil
846
+ end
847
+
848
+ def detach_floating_ip(args)
849
+ options = {}
850
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
851
+ opts.banner = subcommand_usage("[id]")
852
+ build_standard_update_options(opts, options, [:auto_confirm])
853
+ opts.footer = <<-EOT
854
+ Detach a floating IP from a container.
855
+ [id] is required. This is the id of a container.
856
+ Only the following cloud types support this command: OpenStack, Huawei and OpenTelekom
857
+ EOT
858
+ end
859
+ optparse.parse!(args)
860
+ verify_args!(args:args, optparse:optparse, count:1)
861
+ connect(options)
862
+ container = find_container_by_id(args[0])
863
+ return 1 if container.nil?
864
+ cloud_type = load_container_cloud_type(container)
865
+ if !cloud_type['hasFloatingIps']
866
+ raise_command_error "Cloud Type #{cloud_type['name']} does support floating IPs."
867
+ end
868
+ payload = parse_payload(options)
869
+ if payload.nil?
870
+ payload = parse_passed_options(options)
871
+ # prompt
872
+ end
873
+ confirm!("Are you sure you would like to detach the floating IP from container #{container['id']}?", options)
874
+ @containers_interface.setopts(options)
875
+ if options[:dry_run]
876
+ print_dry_run @containers_interface.dry.detach_floating_ip(container['id'], payload)
877
+ return
878
+ end
879
+ json_response = @containers_interface.detach_floating_ip(container['id'], payload)
880
+ render_response(json_response, options) do
881
+ print_green_success "Detaching floating IP from container #{container['id']}"
882
+ end
883
+ return 0, nil
884
+ end
885
+
886
+ private
777
887
 
778
888
  def find_container_by_id(id)
779
889
  begin
@@ -837,4 +947,19 @@ private
837
947
  end
838
948
  return provision_type
839
949
  end
950
+
951
+ def load_container_cloud_type(container)
952
+ cloud_type_code = container['cloud']['type'] rescue nil
953
+ cloud_type = nil
954
+ if cloud_type_code
955
+ cloud_type = @clouds_interface.cloud_types({code:cloud_type_code})['zoneTypes'][0]
956
+ if cloud_type.nil?
957
+ raise_command_error "Cloud Type not found by code #{cloud_type_code}"
958
+ end
959
+ else
960
+ raise_command_error "Unable to determine cloud type for container #{container['id']}"
961
+ end
962
+ return cloud_type
963
+ end
964
+
840
965
  end
@@ -22,7 +22,8 @@ class Morpheus::Cli::Doc
22
22
  end
23
23
 
24
24
  def connect(options)
25
- @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
25
+ # @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
26
+ @api_client = establish_remote_appliance_connection(options)
26
27
  @doc_interface = @api_client.doc
27
28
  end
28
29
 
@@ -72,12 +73,12 @@ EOT
72
73
  params, options = {}, {}
73
74
  optparse = Morpheus::Cli::OptionParser.new do |opts|
74
75
  opts.banner = subcommand_usage()
75
- opts.on(nil, "--refresh", "Refresh the document. By default the openapi.yml and openapi.json are cached by the server.") do
76
- params['refresh'] = true
77
- end
78
- opts.on('-g', '--generate', "Alias for --refresh") do
79
- params['refresh'] = true
80
- end
76
+ # opts.on(nil, "--refresh", "Refresh the document. By default the openapi.yml and openapi.json are cached by the server.") do
77
+ # params['refresh'] = true
78
+ # end
79
+ # opts.on('-g', '--generate', "Alias for --refresh") do
80
+ # params['refresh'] = true
81
+ # end
81
82
  build_standard_get_options(opts, options, [], [:csv])
82
83
  opts.footer = <<-EOT
83
84
  Print the Morpheus API OpenAPI Documentation (swagger).
@@ -121,12 +122,12 @@ EOT
121
122
  options[:yaml] = true
122
123
  options[:format] = :yaml
123
124
  end
124
- opts.on(nil, "--refresh", "Refresh the document. By default the openapi.yml and openapi.json are cached by the server.") do
125
- params['refresh'] = true
126
- end
127
- opts.on('-g', '--generate', "Alias for --refresh") do
128
- params['refresh'] = true
129
- end
125
+ # opts.on(nil, "--refresh", "Refresh the document. By default the openapi.yml and openapi.json are cached by the server.") do
126
+ # params['refresh'] = true
127
+ # end
128
+ # opts.on('-g', '--generate', "Alias for --refresh") do
129
+ # params['refresh'] = true
130
+ # end
130
131
  opts.on( '-f', '--force', "Overwrite existing [local-file] if it exists." ) do
131
132
  options[:overwrite] = true
132
133
  end
@@ -943,6 +943,8 @@ class Morpheus::Cli::Hosts
943
943
  end
944
944
  end
945
945
  end
946
+
947
+ metadata_option_type = option_type_list.find {|type| type['fieldName'] == 'metadata' }
946
948
 
947
949
  # Metadata Tags
948
950
  if metadata_option_type
@@ -2936,9 +2936,15 @@ EOT
2936
2936
  opts.on('--preserve-volumes [on|off]', ['on','off'], "Preserve Volumes. Default is off. Applies to certain types only.") do |val|
2937
2937
  query_params[:preserveVolumes] = val.nil? ? 'on' : val
2938
2938
  end
2939
- opts.on('--releaseEIPs [on|off]', ['on','off'], "Release EIPs. Default is on. Applies to Amazon only.") do |val|
2940
- query_params[:releaseEIPs] = val.nil? ? 'on' : val
2939
+ opts.on('--release-ips [on|off]', ['on','off'], "Release Floating IPs. Default is on. Applies to certain types only.") do |val|
2940
+ query_params[:releaseFloatingIps] = val.nil? ? 'on' : val
2941
+ query_params[:releaseEIPs] = query_params[:releaseFloatingIps] # old parameter before 6.0
2941
2942
  end
2943
+ opts.on('--releaseEIPs [on|off]', ['on','off'], "Alias for Release Floating IPs") do |val|
2944
+ query_params[:releaseFloatingIps] = val.nil? ? 'on' : val
2945
+ query_params[:releaseEIPs] = query_params[:releaseFloatingIps] # old parameter before 6.0
2946
+ end
2947
+ opts.add_hidden_option('--releaseEIPs')
2942
2948
  opts.on( '-f', '--force', "Force Delete" ) do
2943
2949
  query_params[:force] = 'on'
2944
2950
  end
@@ -3,7 +3,7 @@ require 'morpheus/cli/cli_command'
3
3
  class Morpheus::Cli::KeyPairs
4
4
  include Morpheus::Cli::CliCommand
5
5
  include Morpheus::Cli::AccountsHelper
6
- register_subcommands :list, :get, :add, :update, :remove
6
+ register_subcommands :list, :get, :add, :update, :remove, :generate
7
7
  alias_subcommand :details, :get
8
8
 
9
9
  def initialize()
@@ -102,38 +102,7 @@ class Morpheus::Cli::KeyPairs
102
102
  return 0 if render_result
103
103
 
104
104
  unless options[:quiet]
105
- print_h1 "Key Pair Details"
106
- print cyan
107
- if account
108
- # print_description_list({"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' } }, key_pair)
109
- print_description_list({"Account" => lambda {|it| account['name'] } }, key_pair)
110
- end
111
- print_description_list({
112
- "ID" => 'id',
113
- "Name" => 'name',
114
- "Fingerprint" => 'fingerprint',
115
- #"MD5" => 'md5',
116
- # "Has Private Key" => lambda {|it| format_boolean(it['hasPrivateKey']) },
117
- # "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
118
- "Created" => lambda {|it| format_local_dt(it['dateCreated']) }
119
- #"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
120
- }, key_pair)
121
-
122
- print_h2 "Public Key"
123
- print cyan
124
- puts "#{key_pair['publicKey']}"
125
-
126
- if key_pair['hasPrivateKey']
127
- # print_h2 "Private Key"
128
- # print cyan
129
- # puts "(hidden)"
130
- else
131
- # print_h2 "Private Key"
132
- print cyan, "\n"
133
- puts "This is only a public key. It does not include a private key."
134
- end
135
-
136
- print reset,"\n"
105
+ print_key_pair_details(account, key_pair)
137
106
  end
138
107
  rescue RestClient::Exception => e
139
108
  print_rest_exception(e, options)
@@ -180,6 +149,9 @@ class Morpheus::Cli::KeyPairs
180
149
  end
181
150
 
182
151
  build_common_options(opts, options, [:account, :options, :json, :dry_run, :remote])
152
+ opts.footer = <<-EOT
153
+ Add a key pair.
154
+ EOT
183
155
  end
184
156
  optparse.parse!(args)
185
157
  # if args.count < 1
@@ -237,6 +209,10 @@ class Morpheus::Cli::KeyPairs
237
209
  opts.banner = subcommand_usage("[name] [options]")
238
210
  build_option_type_options(opts, options, update_key_pair_option_types)
239
211
  build_common_options(opts, options, [:account, :options, :json, :dry_run, :remote])
212
+ opts.footer = <<-EOT
213
+ Update a key pair.
214
+ [name] is required. This is the name or id of a key pair.
215
+ EOT
240
216
  end
241
217
  optparse.parse!(args)
242
218
 
@@ -290,6 +266,10 @@ class Morpheus::Cli::KeyPairs
290
266
  optparse = Morpheus::Cli::OptionParser.new do |opts|
291
267
  opts.banner = subcommand_usage("[name]")
292
268
  build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
269
+ opts.footer = <<-EOT
270
+ Delete a key pair.
271
+ [name] is required. This is the name or id of a key pair.
272
+ EOT
293
273
  end
294
274
  optparse.parse!(args)
295
275
 
@@ -329,6 +309,50 @@ class Morpheus::Cli::KeyPairs
329
309
  end
330
310
  end
331
311
 
312
+ def generate(args)
313
+ options = {}
314
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
315
+ opts.banner = subcommand_usage("[name]")
316
+ build_common_options(opts, options, [:account, :options, :json, :dry_run, :remote])
317
+ opts.footer = <<-EOT
318
+ Generate a key pair.
319
+ EOT
320
+ end
321
+ optparse.parse!(args)
322
+ # if args.count < 1
323
+ # puts optparse
324
+ # exit 1
325
+ # end
326
+ if args[0]
327
+ options[:options] ||= {}
328
+ options[:options]['name'] ||= args[0]
329
+ end
330
+ connect(options)
331
+ begin
332
+ account = find_account_from_options(options)
333
+ account_id = account ? account['id'] : nil
334
+ params = Morpheus::Cli::OptionTypes.prompt(add_key_pair_option_types.select {|it| ['name'].include?(it['fieldName'])}, options[:options], @api_client, options[:params])
335
+ key_pair_payload = params.select {|k,v| ['name'].include?(k) }
336
+ payload = {keyPair: key_pair_payload}
337
+ @key_pairs_interface.setopts(options)
338
+ if options[:dry_run]
339
+ print_dry_run @key_pairs_interface.dry.generate(account_id, payload)
340
+ return
341
+ end
342
+ json_response = @key_pairs_interface.generate(account_id, payload)
343
+ if options[:json]
344
+ print JSON.pretty_generate(json_response)
345
+ print "\n"
346
+ else
347
+ print_green_success "Key Pair #{key_pair_payload['name']} added"
348
+ print_key_pair_details(account, json_response['keyPair'])
349
+ end
350
+ rescue RestClient::Exception => e
351
+ print_rest_exception(e, options)
352
+ exit 1
353
+ end
354
+ end
355
+
332
356
  private
333
357
  def find_key_pair_by_name_or_id(account_id, val)
334
358
  if val.to_s =~ /\A\d{1,}\Z/
@@ -390,6 +414,43 @@ class Morpheus::Cli::KeyPairs
390
414
  print reset
391
415
  end
392
416
 
417
+ def print_key_pair_details(account, key_pair)
418
+ print_h1 "Key Pair Details"
419
+ print cyan
420
+ if account
421
+ # print_description_list({"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' } }, key_pair)
422
+ print_description_list({"Account" => lambda {|it| account['name'] } }, key_pair)
423
+ end
424
+ print_description_list({
425
+ "ID" => 'id',
426
+ "Name" => 'name',
427
+ "Fingerprint" => 'fingerprint',
428
+ #"MD5" => 'md5',
429
+ # "Has Private Key" => lambda {|it| format_boolean(it['hasPrivateKey']) },
430
+ # "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
431
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) }
432
+ #"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
433
+ }, key_pair)
434
+
435
+ print_h2 "Public Key"
436
+ print cyan
437
+ puts "#{key_pair['publicKey']}"
438
+
439
+ # only happens after generate
440
+ if key_pair['hasPrivateKey']
441
+ if key_pair['privateKey']
442
+ print_h2 "Private Key"
443
+ print cyan
444
+ puts "#{key_pair['privateKey']}"
445
+ end
446
+ else
447
+ # print_h2 "Private Key"
448
+ print cyan, "\n"
449
+ puts "This is only a public key. It does not include a private key."
450
+ end
451
+
452
+ print reset,"\n"
453
+ end
393
454
 
394
455
  def add_key_pair_option_types
395
456
  [
@@ -0,0 +1,109 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::NetworkFloatingIps
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::RestCommand
6
+
7
+ set_command_name :'network-floating-ips'
8
+ set_command_description "View and manage network floating IPs."
9
+ register_subcommands :list, :get, :release
10
+
11
+ # RestCommand settings
12
+ register_interfaces :network_floating_ips
13
+ set_rest_has_name false
14
+ set_rest_arg "id"
15
+
16
+ def release(args)
17
+ params = {}
18
+ options = {}
19
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
20
+ opts.banner = subcommand_usage("[#{rest_arg}]")
21
+ build_standard_remove_options(opts, options)
22
+ opts.footer = <<-EOT
23
+ Release an existing #{rest_label.downcase}.
24
+ [#{rest_arg}] is required. This is the #{rest_has_name ? 'name or id' : 'id'} of #{a_or_an(rest_label)} #{rest_label.downcase}.
25
+ Only the following cloud types support this command: OpenStack, Huawei and OpenTelekom
26
+ EOT
27
+ end
28
+ optparse.parse!(args)
29
+ verify_args!(args:args, optparse:optparse, count:1)
30
+ connect(options)
31
+ params.merge!(parse_query_options(options))
32
+ id = args[0]
33
+ record = rest_find_by_name_or_id(id)
34
+ if record.nil?
35
+ return 1, "#{rest_name} not found for '#{id}'"
36
+ end
37
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to release the #{rest_label.downcase} #{record['name'] || record['id']}?")
38
+ return 9, "aborted"
39
+ end
40
+ rest_interface.setopts(options)
41
+ if options[:dry_run]
42
+ print_dry_run rest_interface.dry.release(record['id'], params)
43
+ return 0, nil
44
+ end
45
+ json_response = rest_interface.release(record['id'], params)
46
+ render_response(json_response, options) do
47
+ print_green_success "Releasing #{rest_label.downcase} #{record['ipAddress'] || record['id']}"
48
+ end
49
+ return 0, nil
50
+ end
51
+
52
+ protected
53
+
54
+ def build_list_options(opts, options, params)
55
+ opts.on('--cloud CLOUD', String, "Cloud Name or ID") do |val|
56
+ options[:cloud] = val
57
+ end
58
+ opts.on('--server SERVER', String, "Server Name or ID") do |val|
59
+ options[:server] = val
60
+ end
61
+ opts.on('--vm VM', String, "Alias for --server") do |val|
62
+ options[:server] = val
63
+ end
64
+ opts.add_hidden_option('--vm')
65
+ opts.on('--ip-address VALUE', String, "Filter by IP Address") do |val|
66
+ add_query_parameter(params, 'ipAddress', val)
67
+ end
68
+ opts.on('--status VALUE', String, "Filter by Status (free, assigned, pending)") do |val|
69
+ add_query_parameter(params, 'ipStatus', val)
70
+ end
71
+ # build_standard_list_options(opts, options)
72
+ super
73
+ end
74
+
75
+ def parse_list_options!(args, options, params)
76
+ parse_parameter_as_resource_id!(:cloud, options, params, 'zoneId')
77
+ parse_parameter_as_resource_id!(:server, options, params)
78
+ super
79
+ end
80
+
81
+ def network_floating_ip_list_column_definitions(options)
82
+ {
83
+ "ID" => 'id',
84
+ "IP Address" => 'ipAddress',
85
+ "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
86
+ "Status" => lambda {|it| it['ipStatus'].to_s.capitalize },
87
+ "VM" => lambda {|it| it['server'] ? it['server']['name'] : '' },
88
+ }
89
+ end
90
+
91
+ def network_floating_ip_column_definitions(options)
92
+ {
93
+ "ID" => 'id',
94
+ "IP Address" => 'ipAddress',
95
+ "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
96
+ "Status" => lambda {|it| it['ipStatus'].to_s.capitalize },
97
+ "VM" => lambda {|it| it['server'] ? it['server']['name'] : '' },
98
+ }
99
+ end
100
+
101
+ def add_network_floating_ip_option_types()
102
+ []
103
+ end
104
+
105
+ def update_network_floating_ip_option_types()
106
+ []
107
+ end
108
+
109
+ end
@@ -303,7 +303,8 @@ class Morpheus::Cli::ReportsCommand
303
303
 
304
304
  end
305
305
 
306
- if payload['report']['startMonth'].size > 7 || payload['report']['endMonth'].size > 7
306
+
307
+ if check_payload_dates(payload)
307
308
  print_green_success "The CLI generates a query that will use only month and year. However, the API does support yyyy-mm-dd from a previous version of Morpheus.\nReplace startMonth/endMonth keys with startDate,endDate ie:"
308
309
  payload['report'].delete('startMonth')
309
310
  payload['report'].delete('endMonth')
@@ -713,5 +714,11 @@ EOT
713
714
  return metadata_filter
714
715
  end
715
716
 
717
+ def check_payload_dates(payload)
718
+ if payload['report']['startMonth'] && payload['report']['endMonth']
719
+ return payload['report']['startMonth'].size > 7 || payload['report']['endMonth'].size > 7
720
+ end
721
+ return false
722
+ end
716
723
  end
717
724