morpheus-cli 6.1.0 → 6.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -210,6 +210,7 @@ class Morpheus::Cli::SecurityGroups
210
210
  params = {}
211
211
  options = {:options => {}}
212
212
  cloud_id = nil
213
+ resource_pool_id = nil
213
214
  tenants = nil
214
215
  group_access_all = nil
215
216
  group_access_list = nil
@@ -225,6 +226,9 @@ class Morpheus::Cli::SecurityGroups
225
226
  opts.on( '-c', '--cloud CLOUD', "Scoped Cloud Name or ID" ) do |val|
226
227
  cloud_id = val
227
228
  end
229
+ opts.on( '--resource-pool ID', String, "ID of the Resource Pool for Amazon VPC and Azure Resource Group" ) do |val|
230
+ resource_pool_id = val
231
+ end
228
232
  opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
229
233
  group_access_all = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
230
234
  end
@@ -321,17 +325,20 @@ class Morpheus::Cli::SecurityGroups
321
325
  if !v_prompt['zoneId'].to_s.empty? && v_prompt['zoneId'].to_s != 'all' && v_prompt['zoneId'].to_s != '-1'
322
326
  payload['securityGroup']['zoneId'] = v_prompt['zoneId']
323
327
 
324
- zone = find_cloud_by_id(payload['securityGroup']['zoneId'])
325
- # networkServer needed here too? err
326
- if zone['securityServer']
327
- sec_server = @network_security_servers.get(zone['securityServer']['id'])['networkSecurityServer']
328
-
329
- if sec_server['type']
330
- payload['securityGroup'].deep_merge!(Morpheus::Cli::OptionTypes.prompt(sec_server['type']['optionTypes'], options[:options], @api_client, {zoneId: zone['id']}))
331
- end
332
- end
328
+ cloud = find_cloud_by_id(payload['securityGroup']['zoneId'])
329
+
330
+ # parse --resource-pool
331
+ # if resource_pool_id
332
+ # resource_pool = find_resource_pool_by_name_or_id(cloud['id'], resource_pool_id)
333
+ # return 1 if resource_pool.nil?
334
+ # end
335
+
336
+ # prompt for zone specific settings that go under "securityGroup.customOptions" for some reason
337
+ custom_options_values = prompt_security_group_custom_options(options, cloud, resource_pool_id)
338
+ payload['securityGroup'].deep_merge!(custom_options_values)
333
339
  end
334
340
  rescue => ex
341
+ # raise ex
335
342
  print yellow,"Failed to determine the available scoped clouds.",reset,"\n"
336
343
  end
337
344
 
@@ -626,34 +633,8 @@ class Morpheus::Cli::SecurityGroups
626
633
  # return 1 if resource_pool.nil?
627
634
  # end
628
635
 
629
- # Custom Options prompt
630
- # securityServer is no longer used, it has been replaced by networkServer,
631
- # default to the cloud type code, since it's the same...
632
- # no optionTypes returned here, so hard coded by type
633
- network_server_type = cloud['networkServer'] ? cloud['networkServer']['type'] : (cloud['securityServer'] ? cloud['securityServer']['type'] : cloud["zoneType"]["code"])
634
- custom_options_values = {}
635
- if network_server_type == 'amazon'
636
- if cloud['config'] && !cloud['config']['vpc'].to_s.empty?
637
- custom_options_values.deep_merge!({'customOptions' => {'vpc' => cloud['config']['vpc']} })
638
- else
639
- options[:options].deep_merge!({'customOptions' => {'vpc' => resource_pool_id} }) if resource_pool_id
640
- custom_options_values = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'customOptions', 'fieldName' => 'vpc', 'fieldLabel' => 'VPC', 'type' => 'select', 'optionSource' => 'zonePools', 'required' => true, 'config' => {'valueField' => 'externalId'}}], options[:options], @api_client, {zoneId: cloud['id'], ignoreDefaultPool: true})
641
- end
642
- elsif network_server_type == 'azure' || network_server_type == 'azurestack'
643
- if cloud['config'] && !cloud['config']['resourceGroup'].to_s.empty?
644
- custom_options_values.deep_merge!({'customOptions' => {'resourceGroup' => cloud['config']['resourceGroup']} })
645
- else
646
- options[:options].deep_merge!({'customOptions' => {'resourceGroup' => resource_pool_id} }) if resource_pool_id
647
- custom_options_values = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'customOptions', 'fieldName' => 'resourceGroup', 'fieldLabel' => 'Resource Group', 'type' => 'select', 'optionSource' => 'zonePools', 'required' => true, 'config' => {'valueField' => 'externalId'}}], options[:options], @api_client, {zoneId: cloud['id'], ignoreDefaultPool: true})
648
- end
649
- elsif network_server_type == 'openstack' || network_server_type == 'opentelekom' || network_server_type == 'huawei'
650
- if cloud['config'] && !cloud['config']['resourcePoolId'].to_s.empty?
651
- custom_options_values.deep_merge!({'customOptions' => {'resourcePoolId' => cloud['config']['resourcePoolId']} })
652
- else
653
- options[:options].deep_merge!({'customOptions' => {'resourcePoolId' => resource_pool_id} }) if resource_pool_id
654
- custom_options_values = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'customOptions', 'fieldName' => 'resourcePoolId', 'fieldLabel' => 'Resource Pool', 'type' => 'select', 'optionSource' => 'zonePools', 'required' => true}], options[:options], @api_client, {zoneId: cloud['id'], ignoreDefaultPool: true})
655
- end
656
- end
636
+ # prompt for zone specific settings that go under "securityGroup.customOptions" for some reason
637
+ custom_options_values = prompt_security_group_custom_options(options, cloud, resource_pool_id)
657
638
  payload['securityGroupLocation'].deep_merge!(custom_options_values)
658
639
  end
659
640
  @security_groups_interface.setopts(options)
@@ -1270,4 +1251,44 @@ class Morpheus::Cli::SecurityGroups
1270
1251
  end
1271
1252
  end
1272
1253
 
1254
+ def prompt_security_group_custom_options(options, cloud, resource_pool_id=nil)
1255
+ custom_options_values = {}
1256
+ # Custom Options prompt
1257
+ # securityServer is no longer used, it has been replaced by networkServer,
1258
+ # default to the cloud type code, since it's the same...
1259
+ # no optionTypes returned here, so hard coded by type
1260
+ # The API used to return securityServer which could be fetched to get its optionTypes
1261
+ if cloud['securityServer']
1262
+ sec_server = @network_security_servers.get(cloud['securityServer']['id'])['networkSecurityServer']
1263
+ if sec_server['type']
1264
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(sec_server['type']['optionTypes'], options[:options], @api_client, {zoneId: cloud['id']})
1265
+ custom_options_values.deep_merge!(v_prompt)
1266
+ end
1267
+ else
1268
+ network_server_type = cloud['networkServer'] ? cloud['networkServer']['type'] : (cloud['securityServer'] ? cloud['securityServer']['type'] : cloud["zoneType"]["code"])
1269
+ if network_server_type == 'amazon'
1270
+ if cloud['config'] && !cloud['config']['vpc'].to_s.empty?
1271
+ custom_options_values.deep_merge!({'customOptions' => {'vpc' => cloud['config']['vpc']} })
1272
+ else
1273
+ options[:options].deep_merge!({'customOptions' => {'vpc' => resource_pool_id} }) if resource_pool_id
1274
+ custom_options_values = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'customOptions', 'fieldName' => 'vpc', 'fieldLabel' => 'VPC', 'type' => 'select', 'optionSource' => 'zonePools', 'required' => true, 'config' => {'valueField' => 'externalId'}}], options[:options], @api_client, {zoneId: cloud['id'], ignoreDefaultPool: true})
1275
+ end
1276
+ elsif network_server_type == 'azure' || network_server_type == 'azurestack'
1277
+ if cloud['config'] && !cloud['config']['resourceGroup'].to_s.empty?
1278
+ custom_options_values.deep_merge!({'customOptions' => {'resourceGroup' => cloud['config']['resourceGroup']} })
1279
+ else
1280
+ options[:options].deep_merge!({'customOptions' => {'resourceGroup' => resource_pool_id} }) if resource_pool_id
1281
+ custom_options_values = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'customOptions', 'fieldName' => 'resourceGroup', 'fieldLabel' => 'Resource Group', 'type' => 'select', 'optionSource' => 'zonePools', 'required' => true, 'config' => {'valueField' => 'externalId'}}], options[:options], @api_client, {zoneId: cloud['id'], ignoreDefaultPool: true})
1282
+ end
1283
+ elsif network_server_type == 'openstack' || network_server_type == 'opentelekom' || network_server_type == 'huawei'
1284
+ if cloud['config'] && !cloud['config']['resourcePoolId'].to_s.empty?
1285
+ custom_options_values.deep_merge!({'customOptions' => {'resourcePoolId' => cloud['config']['resourcePoolId']} })
1286
+ else
1287
+ options[:options].deep_merge!({'customOptions' => {'resourcePoolId' => resource_pool_id} }) if resource_pool_id
1288
+ custom_options_values = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'customOptions', 'fieldName' => 'resourcePoolId', 'fieldLabel' => 'Resource Pool', 'type' => 'select', 'optionSource' => 'zonePools', 'required' => true}], options[:options], @api_client, {zoneId: cloud['id'], ignoreDefaultPool: true})
1289
+ end
1290
+ end
1291
+ end
1292
+ return custom_options_values
1293
+ end
1273
1294
  end
@@ -297,7 +297,29 @@ EOT
297
297
  if access.count > 0
298
298
  access.each {|it| it['access'] = format_access_string(it['access'], available_access_levels)}
299
299
 
300
- if ['features', 'instance_types'].include?(field)
300
+ if ['features'].include?(field)
301
+ if access.find {|it| !it['subCategory'].to_s.empty? }
302
+ rows = access.collect do |it|
303
+ {
304
+ code: it['code'],
305
+ name: it['name'],
306
+ category: it['subCategory'].to_s.titleize,
307
+ access: format_access_string(it['access']),
308
+ }
309
+ end
310
+ if options[:sort]
311
+ rows.sort! {|a,b| a[options[:sort]] <=> b[options[:sort]] }
312
+ else
313
+ rows.sort! {|a,b| [a[:category],a[:name],a[:code]] <=> [b[:category],b[:name],b[:code]] }
314
+ end
315
+ if options[:direction] == 'desc'
316
+ rows.reverse!
317
+ end
318
+ print as_pretty_table(rows, [:category, :name, :code, :access], options)
319
+ else
320
+ print as_pretty_table(access, [:name, :code, :access], options)
321
+ end
322
+ elsif ['instance_types','report_types'].include?(field)
301
323
  print as_pretty_table(access, [:name, :code, :access], options)
302
324
  else
303
325
  print as_pretty_table(access, [:name, :access], options)
@@ -422,7 +444,29 @@ EOT
422
444
  if access.count > 0
423
445
  access.each {|it| it['access'] = format_access_string(it['access'], available_access_levels)}
424
446
 
425
- if ['features', 'instance_types', 'report_types'].include?(field)
447
+ if ['features'].include?(field)
448
+ if access.find {|it| !it['subCategory'].to_s.empty? }
449
+ rows = access.collect do |it|
450
+ {
451
+ code: it['code'],
452
+ name: it['name'],
453
+ category: it['subCategory'].to_s.titleize,
454
+ access: format_access_string(it['access']),
455
+ }
456
+ end
457
+ if options[:sort]
458
+ rows.sort! {|a,b| a[options[:sort]] <=> b[options[:sort]] }
459
+ else
460
+ rows.sort! {|a,b| [a[:category],a[:name],a[:code]] <=> [b[:category],b[:name],b[:code]] }
461
+ end
462
+ if options[:direction] == 'desc'
463
+ rows.reverse!
464
+ end
465
+ print as_pretty_table(rows, [:category, :name, :code, :access], options)
466
+ else
467
+ print as_pretty_table(access, [:name, :code, :access], options)
468
+ end
469
+ elsif ['instance_types','report_types'].include?(field)
426
470
  print as_pretty_table(access, [:name, :code, :access], options)
427
471
  else
428
472
  print as_pretty_table(access, [:name, :access], options)
@@ -719,7 +719,7 @@ module Morpheus::Cli::ProvisioningHelper
719
719
  service_plan = nil
720
720
 
721
721
  prompt_service_plan = -> {
722
- service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id}.merge(resource_pool.nil? ? {} : {'resourcePoolId' => resource_pool['id']}))
722
+ service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id}.merge(resource_pool.nil? ? {} : {'poolId' => resource_pool['id'], 'resourcePoolId' => resource_pool['id']}))
723
723
  service_plans = service_plans_json["plans"]
724
724
  if locked_fields.include?('plan.id')
725
725
  plan_id = options[:options]['plan']['id'] rescue nil
@@ -773,8 +773,8 @@ module Morpheus::Cli::ProvisioningHelper
773
773
  has_zone_pools = provision_type && provision_type["id"] && provision_type["hasZonePools"]
774
774
  if has_zone_pools
775
775
  # pluck out the resourcePoolId option type to prompt for
776
- resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
777
- option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
776
+ resource_pool_option_type = option_type_list.find {|opt| ['poolId','resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
777
+ option_type_list = option_type_list.reject {|opt| ['poolId','resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
778
778
 
779
779
  resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], layoutId: layout["id"]}.merge(service_plan.nil? ? {} : {planId: service_plan["id"]}))['data']
780
780
  if options[:resource_pool]
@@ -836,7 +836,7 @@ module Morpheus::Cli::ProvisioningHelper
836
836
  # add selectable datastores for resource pool
837
837
  if options[:select_datastore]
838
838
  begin
839
- selectable_datastores = datastores_interface.list({'zoneId' => cloud_id, 'siteId' => group_id, 'resourcePoolId' => resource_pool['id']})
839
+ selectable_datastores = datastores_interface.list({'zoneId' => cloud_id, 'siteId' => group_id, 'poolId' => resource_pool['id'], 'resourcePoolId' => resource_pool['id']})
840
840
  service_plan['datastores'] = {'clusters' => [], 'datastores' => []}
841
841
  ['clusters', 'datastores'].each do |type|
842
842
  service_plan['datastores'][type] ||= []
@@ -1538,7 +1538,7 @@ module Morpheus::Cli::ProvisioningHelper
1538
1538
 
1539
1539
  if datastore_options.empty? && storage_type['hasDatastore'] != false
1540
1540
  begin
1541
- datastore_res = datastores_interface.list({'resourcePoolId' => current_root_volume['resourcePoolId'], 'zoneId' => options['zoneId'], 'siteId' => options['siteId']})['datastores']
1541
+ datastore_res = datastores_interface.list({'poolId' => current_root_volume['resourcePoolId'], 'resourcePoolId' => current_root_volume['resourcePoolId'], 'zoneId' => options['zoneId'], 'siteId' => options['siteId']})['datastores']
1542
1542
  datastore_res.each do |opt|
1543
1543
  datastore_options << {'name' => opt['name'], 'value' => opt['id']}
1544
1544
  end
@@ -1578,7 +1578,7 @@ module Morpheus::Cli::ProvisioningHelper
1578
1578
  no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
1579
1579
  network_interfaces = []
1580
1580
  api_params = {zoneId: zone_id, provisionTypeId: provision_type_id}.merge(options[:api_params] || {})
1581
- if pool_id.to_s =~ /\A\d{1,}\Z/
1581
+ if pool_id
1582
1582
  api_params[:poolId] = pool_id
1583
1583
  end
1584
1584
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "6.1.0"
4
+ VERSION = "6.1.2"
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2023-04-20 00:00:00.000000000 Z
14
+ date: 2023-06-21 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -226,7 +226,6 @@ files:
226
226
  - lib/morpheus/api/datastores_interface.rb
227
227
  - lib/morpheus/api/deploy_interface.rb
228
228
  - lib/morpheus/api/deployments_interface.rb
229
- - lib/morpheus/api/doc_interface.rb
230
229
  - lib/morpheus/api/environments_interface.rb
231
230
  - lib/morpheus/api/execute_schedules_interface.rb
232
231
  - lib/morpheus/api/execution_request_interface.rb
@@ -260,7 +259,9 @@ files:
260
259
  - lib/morpheus/api/library_spec_templates_interface.rb
261
260
  - lib/morpheus/api/license_interface.rb
262
261
  - lib/morpheus/api/load_balancer_monitors_interface.rb
262
+ - lib/morpheus/api/load_balancer_pool_nodes_interface.rb
263
263
  - lib/morpheus/api/load_balancer_pools_interface.rb
264
+ - lib/morpheus/api/load_balancer_pools_secondary_interface.rb
264
265
  - lib/morpheus/api/load_balancer_profiles_interface.rb
265
266
  - lib/morpheus/api/load_balancer_types_interface.rb
266
267
  - lib/morpheus/api/load_balancer_virtual_servers_interface.rb
@@ -398,7 +399,6 @@ files:
398
399
  - lib/morpheus/cli/commands/deploy.rb
399
400
  - lib/morpheus/cli/commands/deployments.rb
400
401
  - lib/morpheus/cli/commands/deploys.rb
401
- - lib/morpheus/cli/commands/doc.rb
402
402
  - lib/morpheus/cli/commands/echo_command.rb
403
403
  - lib/morpheus/cli/commands/edit_profile_command.rb
404
404
  - lib/morpheus/cli/commands/edit_rc_command.rb
@@ -434,6 +434,7 @@ files:
434
434
  - lib/morpheus/cli/commands/library_upgrades_command.rb
435
435
  - lib/morpheus/cli/commands/license.rb
436
436
  - lib/morpheus/cli/commands/load_balancer_monitors.rb
437
+ - lib/morpheus/cli/commands/load_balancer_pool_nodes.rb
437
438
  - lib/morpheus/cli/commands/load_balancer_pools.rb
438
439
  - lib/morpheus/cli/commands/load_balancer_profiles.rb
439
440
  - lib/morpheus/cli/commands/load_balancer_types.rb
@@ -575,14 +576,12 @@ files:
575
576
  - lib/morpheus/util.rb
576
577
  - morpheus-cli.gemspec
577
578
  - test/api/containers_interface_test.rb
578
- - test/api/doc_interface_test.rb
579
579
  - test/api/instances_interface_test.rb
580
580
  - test/api/whoami_interface_test.rb
581
581
  - test/cli/access_token_test.rb
582
582
  - test/cli/auth_test.rb
583
583
  - test/cli/cli_test.rb
584
584
  - test/cli/containers_test.rb
585
- - test/cli/doc_test.rb
586
585
  - test/cli/help_test.rb
587
586
  - test/cli/instances_test.rb
588
587
  - test/cli/man_test.rb
@@ -621,14 +620,12 @@ specification_version: 4
621
620
  summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance
622
621
  test_files:
623
622
  - test/api/containers_interface_test.rb
624
- - test/api/doc_interface_test.rb
625
623
  - test/api/instances_interface_test.rb
626
624
  - test/api/whoami_interface_test.rb
627
625
  - test/cli/access_token_test.rb
628
626
  - test/cli/auth_test.rb
629
627
  - test/cli/cli_test.rb
630
628
  - test/cli/containers_test.rb
631
- - test/cli/doc_test.rb
632
629
  - test/cli/help_test.rb
633
630
  - test/cli/instances_test.rb
634
631
  - test/cli/man_test.rb
@@ -1,50 +0,0 @@
1
- require 'morpheus/api/api_client'
2
-
3
- class Morpheus::DocInterface < Morpheus::APIClient
4
-
5
- def list(params={})
6
- url = "/api/doc"
7
- headers = {params: params}
8
- execute(method: :get, url: url, headers: headers)
9
- end
10
-
11
- def openapi(params={})
12
- url = "/api/doc/openapi"
13
- fmt = params.delete('format')
14
- if fmt
15
- url = url + "." + fmt
16
- end
17
- is_yaml = fmt == "yml" || fmt == "yaml"
18
- headers = {params: params}
19
- execute(method: :get, url: url, headers: headers, timeout: 172800, parse_json: !is_yaml)
20
- end
21
-
22
- def download_openapi(outfile, params={})
23
- # note that RestClient.execute still requires the full path with base_url
24
- url = "#{@base_url}/api/doc/openapi"
25
- fmt = params.delete('format')
26
- if fmt
27
- url = url + "." + fmt
28
- end
29
- headers = {params: params, authorization: "Bearer #{@access_token}"}
30
- opts = {method: :get, url: url, headers: headers, timeout: 172800, parse_json: false}
31
-
32
- if @dry_run
33
- return opts
34
- end
35
-
36
- http_response = nil
37
- File.open(File.expand_path(outfile), 'w') {|f|
38
- block = proc { |response|
39
- response.read_body do |chunk|
40
- # writing to #{outfile} ..."
41
- f.write chunk
42
- end
43
- }
44
- opts[:block_response] = block
45
- http_response = Morpheus::RestClient.execute(opts)
46
- }
47
- http_response
48
- end
49
-
50
- end
@@ -1,182 +0,0 @@
1
- require 'morpheus/cli/cli_command'
2
-
3
- # This provides commands for authentication
4
- # This also includes credential management.
5
- class Morpheus::Cli::Doc
6
- include Morpheus::Cli::CliCommand
7
-
8
- set_command_name :'doc'
9
- register_subcommands :list
10
- register_subcommands :get => :openapi
11
- register_subcommands :download => :download_openapi
12
-
13
- # hidden until doc complete (or close to it)
14
- set_command_hidden
15
-
16
- def initialize()
17
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
18
- end
19
-
20
- def handle(args)
21
- handle_subcommand(args)
22
- end
23
-
24
- def connect(options)
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)
27
- @doc_interface = @api_client.doc
28
- end
29
-
30
- def list(args)
31
- exit_code, err = 0, nil
32
- params, options = {}, {}
33
- optparse = Morpheus::Cli::OptionParser.new do |opts|
34
- opts.banner = subcommand_usage()
35
- build_standard_get_options(opts, options)
36
- opts.footer = <<-EOT
37
- List documentation links.
38
- EOT
39
- end
40
- optparse.parse!(args)
41
- verify_args!(args:args, optparse:optparse, count:0)
42
- connect(options)
43
- # construct the api request
44
- params.merge!(parse_list_options(options))
45
- # execute the api request
46
- @doc_interface.setopts(options)
47
- if options[:dry_run]
48
- print_dry_run @doc_interface.dry.list(params)
49
- return 0, nil
50
- end
51
- json_response = @doc_interface.list(params)
52
- render_response(json_response, options, "links") do
53
- title = "Morpheus Documentation"
54
- print_h1 title, options
55
- if json_response['links'].empty?
56
- print yellow, "No help links found.",reset,"\n"
57
- else
58
- columns = {
59
- "Link Name" => 'name',
60
- "URL" => 'url',
61
- "Description" => {display_method:'description', max_width: (options[:wrap] ? nil : 50)},
62
- }
63
- print as_pretty_table(json_response['links'], columns.upcase_keys!, options)
64
- # print_results_pagination(json_response)
65
- end
66
- print reset,"\n"
67
- end
68
- return exit_code, err
69
- end
70
-
71
- def openapi(args)
72
- exit_code, err = 0, nil
73
- params, options = {}, {}
74
- optparse = Morpheus::Cli::OptionParser.new do |opts|
75
- opts.banner = subcommand_usage()
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
82
- build_standard_get_options(opts, options, [], [:csv])
83
- opts.footer = <<-EOT
84
- Print the Morpheus API OpenAPI Documentation (swagger).
85
- The default format is JSON. Supports json or yaml.
86
- EOT
87
- end
88
- optparse.parse!(args)
89
- verify_args!(args:args, optparse:optparse, count:0)
90
- connect(options)
91
- # construct the api request
92
- params.merge!(parse_list_options(options))
93
- # for now, always use .json, and just convert to yaml for display on cli side
94
- openapi_format = options[:yaml] ? "yaml" : "json"
95
- # params['format'] = openapi_format
96
- # execute the api request
97
- @doc_interface.setopts(options)
98
- if options[:dry_run]
99
- params['format'] = openapi_format
100
- print_dry_run @doc_interface.dry.openapi(params)
101
- return 0, nil
102
- end
103
- json_response = @doc_interface.openapi(params)
104
- # default format is to print header and json
105
- render_response(json_response, options) do
106
- title = "Morpheus API openapi.#{openapi_format}"
107
- print_h1 title, options
108
- print cyan
109
- print as_json(json_response, options)
110
- print reset,"\n"
111
- end
112
- return exit_code, err
113
- end
114
-
115
- def download_openapi(args)
116
- exit_code, err = 0, nil
117
- params, options = {}, {}
118
- optparse = Morpheus::Cli::OptionParser.new do |opts|
119
- opts.banner = subcommand_usage("[local-file]")
120
- # build_standard_get_options(opts, options, [], [:csv,:out])
121
- opts.on(nil, '--yaml', "YAML Output") do
122
- options[:yaml] = true
123
- options[:format] = :yaml
124
- 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
131
- opts.on( '-f', '--force', "Overwrite existing [local-file] if it exists." ) do
132
- options[:overwrite] = true
133
- end
134
- opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
135
- options[:mkdir] = true
136
- end
137
- build_common_options(opts, options, [:dry_run, :quiet, :remote])
138
- opts.footer = <<-EOT
139
- Download the Morpheus API OpenAPI Documentation (swagger).
140
- [local-file] is required. This is the full local filepath for the downloaded file.
141
- The default format is JSON. Supports json or yaml.
142
- EOT
143
- end
144
- optparse.parse!(args)
145
- verify_args!(args:args, optparse:optparse, count:1)
146
- connect(options)
147
- # parse args
148
- outfile = args[0]
149
- if !validate_outfile(outfile, options)
150
- return 1, "Failed to validate outfile"
151
- end
152
- # construct the api request
153
- params.merge!(parse_list_options(options))
154
- if outfile.include?(".yml") || outfile.include?(".yaml")
155
- options[:yaml] = true
156
- end
157
- openapi_format = options[:yaml] ? "yaml" : "json"
158
- params['format'] = openapi_format
159
- # execute the api request
160
- @doc_interface.setopts(options)
161
- if options[:dry_run]
162
- print_dry_run @doc_interface.dry.download_openapi(outfile, params)
163
- return 0, nil
164
- end
165
- print cyan + "Downloading openapi.#{openapi_format} to #{outfile} ... " if !options[:quiet]
166
- http_response = @doc_interface.download_openapi(outfile, params)
167
- if http_response.code.to_i == 200
168
- print green + "SUCCESS" + reset + "\n" if !options[:quiet]
169
- return 0, nil
170
- else
171
- print red + "ERROR" + reset + " HTTP #{http_response.code}" + "\n" if !options[:quiet]
172
- if File.exist?(outfile) && File.file?(outfile)
173
- Morpheus::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if Morpheus::Logging.debug?
174
- File.delete(outfile)
175
- end
176
- return 1, "HTTP #{http_response.code}"
177
- end
178
- end
179
-
180
- protected
181
-
182
- end
@@ -1,35 +0,0 @@
1
- require 'morpheus_test'
2
-
3
- # Tests for Morpheus::DocInterface
4
- class MorpheusTest::DocInterfaceTest < MorpheusTest::TestCase
5
-
6
- def test_doc_list
7
- @doc_interface = client.doc
8
- response = @doc_interface.list()
9
- assert_equal response['links'].class, Array
10
- end
11
-
12
- def test_doc_get
13
- @doc_interface = client.doc
14
- response = @doc_interface.openapi()
15
- assert_equal response['openapi'], '3.0.3'
16
- # todo: fix this, can be cached and fail
17
- #assert_equal response['version'], Morpheus::Cli::Remote.load_remote(@config.remote_name)[:build_version]
18
- end
19
-
20
- def test_doc_get_yaml
21
- @doc_interface = client.doc
22
- response = @doc_interface.openapi({'format' => "yaml"})
23
- assert response.body
24
- assert YAML.load(response.body)
25
- end
26
-
27
- # def test_doc_download
28
- # @doc_interface = client.doc
29
- # response = @doc_interface.download_openapi('/path/to/openapi.json')
30
- # yaml_content = response.body
31
- # yaml_data = YAML.load(yaml_content)
32
- # assert_not_nil yaml_data
33
- # end
34
-
35
- end
data/test/cli/doc_test.rb DELETED
@@ -1,35 +0,0 @@
1
- require 'morpheus_test'
2
-
3
- # Tests for Morpheus::Cli::Doc
4
- class MorpheusTest::DocTest < MorpheusTest::TestCase
5
-
6
- def test_doc_list
7
- assert_execute("doc list")
8
- end
9
-
10
- def test_doc_get
11
- # using --quiet because the output is massive
12
- assert_execute("doc get --quiet")
13
- end
14
-
15
- def test_doc_get_yaml
16
- # using --quiet because the output is massive
17
- assert_execute("doc get --yaml --quiet")
18
- end
19
-
20
- # def test_doc_download
21
- # assert_execute("doc download '/path/to/openapi.json')
22
- # end
23
-
24
- # def test_doc_download_yaml
25
- # assert_execute("doc download '/path/to/openapi.yaml' --yaml")
26
- # end
27
-
28
- def test_doc_get_unauthorized
29
- # authentication is NOT required for this api
30
- without_authentication do
31
- assert_error("doc get -q")
32
- end
33
- end
34
-
35
- end