morpheus-cli 6.1.1 → 6.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|