morpheus-cli 6.1.1 → 6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +0 -4
- data/lib/morpheus/cli/commands/instances.rb +5 -0
- data/lib/morpheus/cli/commands/load_balancer_pools.rb +37 -1
- data/lib/morpheus/cli/commands/security_groups.rb +58 -37
- data/lib/morpheus/cli/version.rb +1 -1
- metadata +2 -8
- data/lib/morpheus/api/doc_interface.rb +0 -50
- data/lib/morpheus/cli/commands/doc.rb +0 -182
- data/test/api/doc_interface_test.rb +0 -35
- data/test/cli/doc_test.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 683efa948a958a0fb4a6def11cb94ae525bdde8cbde0ba1d1aa313adeef3387d
|
4
|
+
data.tar.gz: c19c0522892a7f96a8398811b89ea4324815f4494011bf6696be1fb362787304
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1b269a981ec0fcbeecbad62a91ba90f6e7429c26593579185a0a513d0ab5ea5e2394ab11d7bf138570314a418059b6a072e47fb04b0393010dc0f66a463db54
|
7
|
+
data.tar.gz: 3c211238b4a2dae07c4da54659be1c43e9f0cf7aaf25f7bbfcf53f0c6a0482b43b87b44db541287dfd7201228902902e80c0a1b4a5b538207f3303174940cff9
|
data/Dockerfile
CHANGED
@@ -599,6 +599,9 @@ class Morpheus::Cli::Instances
|
|
599
599
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
600
600
|
opts.banner = subcommand_usage("[instance]")
|
601
601
|
opts.on('--name VALUE', String, "Name") do |val|
|
602
|
+
params['name'] = val
|
603
|
+
end
|
604
|
+
opts.on('--displayName VALUE', String, "Name") do |val|
|
602
605
|
params['displayName'] = val
|
603
606
|
end
|
604
607
|
opts.on('--description VALUE', String, "Description") do |val|
|
@@ -1400,6 +1403,7 @@ class Morpheus::Cli::Instances
|
|
1400
1403
|
description_cols = {
|
1401
1404
|
"ID" => 'id',
|
1402
1405
|
"Name" => 'name',
|
1406
|
+
"Display Name" => 'displayName',
|
1403
1407
|
"Description" => 'description',
|
1404
1408
|
"Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
|
1405
1409
|
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
@@ -5423,6 +5427,7 @@ private
|
|
5423
5427
|
def add_instance_schedule_option_types()
|
5424
5428
|
[
|
5425
5429
|
{'code' => 'scheduleType', 'fieldName' => 'scheduleType', 'fieldLabel' => 'Schedule Type', 'type' => 'select', 'selectOptions' => [{'name'=>'Day Of Week', 'value'=>'dayOfWeek'},{'name'=>'Exact', 'value'=>'exact'}], 'description' => "Schedule type can be recurring day of the week str or exact start and end timestamp", 'required' => true, 'defaultValue' => 'dayOfWeek'},
|
5430
|
+
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'scheduleTimezone', 'fieldLabel' => 'Timezone', 'type' => 'select', 'optionSource' => 'timezones' , 'description' => "The timezone", 'defaultValue' => "UTC", 'required' => false},
|
5426
5431
|
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'startDayOfWeek', 'fieldLabel' => 'Start Day Of Week', 'type' => 'select', 'selectOptions' => day_of_week_dropdown, 'description' => "Start day of the week Sunday-Saturday (1-7)", 'defaultValue' => "Sunday", 'required' => true},
|
5427
5432
|
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'startTime', 'fieldLabel' => 'Start Time (HH:MM)', 'type' => 'text', 'description' => "Start time in HH:MM 24-hour format", 'placeHolder' => 'HH:MM', 'defaultValue' => "01:00", 'required' => true},
|
5428
5433
|
{'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'endDayOfWeek', 'fieldLabel' => 'End Day Of Week', 'type' => 'select', 'selectOptions' => day_of_week_dropdown, 'description' => "End day of the week Sunday-Saturday (1-7)", 'defaultValue' => "Sunday", 'required' => true},
|
@@ -13,7 +13,7 @@ class Morpheus::Cli::LoadBalancerPools
|
|
13
13
|
set_rest_parent_name :load_balancers
|
14
14
|
|
15
15
|
register_subcommands :list, :get, :add, :update, :remove
|
16
|
-
register_interfaces :load_balancers, :load_balancer_types
|
16
|
+
register_interfaces :load_balancer_pools_secondary, :load_balancers, :load_balancer_types
|
17
17
|
|
18
18
|
|
19
19
|
# set_rest_interface_name :load_balancer_pools
|
@@ -90,4 +90,40 @@ class Morpheus::Cli::LoadBalancerPools
|
|
90
90
|
|
91
91
|
## using CliCommand's generic find_by methods
|
92
92
|
|
93
|
+
def find_load_balancer_pool_by_name_or_id(load_balancer_pool_id, val)
|
94
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
95
|
+
return find_load_balancer_pool_by_id(load_balancer_pool_id, val)
|
96
|
+
else
|
97
|
+
return find_load_balancer_pool_by_name(load_balancer_pool_id, val)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_load_balancer_pool_by_id(load_balancer_pool_id, id)
|
102
|
+
begin
|
103
|
+
json_response = @load_balancer_pools_secondary_interface.get(load_balancer_pool_id, id.to_i)
|
104
|
+
return json_response[load_balancer_pool_object_key]
|
105
|
+
rescue RestClient::Exception => e
|
106
|
+
if e.response && e.response.code == 404
|
107
|
+
print_red_alert "Load Balancer Pool not found by id #{id}"
|
108
|
+
else
|
109
|
+
raise e
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def find_load_balancer_pool_by_name(load_balancer_pool_id, name)
|
115
|
+
lbs = @load_balancer_pools_secondary_interface.list(load_balancer_pool_id, {name: name.to_s})[load_balancer_pool_list_key]
|
116
|
+
if lbs.empty?
|
117
|
+
print_red_alert "Load Balancer Pool not found by name #{name}"
|
118
|
+
return nil
|
119
|
+
elsif lbs.size > 1
|
120
|
+
print_red_alert "#{lbs.size} load balancer pools found by name #{name}"
|
121
|
+
#print_lbs_table(lbs, {color: red})
|
122
|
+
print reset,"\n\n"
|
123
|
+
return nil
|
124
|
+
else
|
125
|
+
return lbs[0]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
93
129
|
end
|
@@ -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
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
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
|
-
#
|
630
|
-
|
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
|
data/lib/morpheus/cli/version.rb
CHANGED
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.
|
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-
|
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
|
@@ -400,7 +399,6 @@ files:
|
|
400
399
|
- lib/morpheus/cli/commands/deploy.rb
|
401
400
|
- lib/morpheus/cli/commands/deployments.rb
|
402
401
|
- lib/morpheus/cli/commands/deploys.rb
|
403
|
-
- lib/morpheus/cli/commands/doc.rb
|
404
402
|
- lib/morpheus/cli/commands/echo_command.rb
|
405
403
|
- lib/morpheus/cli/commands/edit_profile_command.rb
|
406
404
|
- lib/morpheus/cli/commands/edit_rc_command.rb
|
@@ -578,14 +576,12 @@ files:
|
|
578
576
|
- lib/morpheus/util.rb
|
579
577
|
- morpheus-cli.gemspec
|
580
578
|
- test/api/containers_interface_test.rb
|
581
|
-
- test/api/doc_interface_test.rb
|
582
579
|
- test/api/instances_interface_test.rb
|
583
580
|
- test/api/whoami_interface_test.rb
|
584
581
|
- test/cli/access_token_test.rb
|
585
582
|
- test/cli/auth_test.rb
|
586
583
|
- test/cli/cli_test.rb
|
587
584
|
- test/cli/containers_test.rb
|
588
|
-
- test/cli/doc_test.rb
|
589
585
|
- test/cli/help_test.rb
|
590
586
|
- test/cli/instances_test.rb
|
591
587
|
- test/cli/man_test.rb
|
@@ -624,14 +620,12 @@ specification_version: 4
|
|
624
620
|
summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance
|
625
621
|
test_files:
|
626
622
|
- test/api/containers_interface_test.rb
|
627
|
-
- test/api/doc_interface_test.rb
|
628
623
|
- test/api/instances_interface_test.rb
|
629
624
|
- test/api/whoami_interface_test.rb
|
630
625
|
- test/cli/access_token_test.rb
|
631
626
|
- test/cli/auth_test.rb
|
632
627
|
- test/cli/cli_test.rb
|
633
628
|
- test/cli/containers_test.rb
|
634
|
-
- test/cli/doc_test.rb
|
635
629
|
- test/cli/help_test.rb
|
636
630
|
- test/cli/instances_test.rb
|
637
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
|