morpheus-cli 4.2.20 → 5.0.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 +26 -0
- data/lib/morpheus/api/billing_interface.rb +34 -0
- data/lib/morpheus/api/catalog_item_types_interface.rb +9 -0
- data/lib/morpheus/api/deploy_interface.rb +1 -1
- data/lib/morpheus/api/deployments_interface.rb +20 -1
- data/lib/morpheus/api/forgot_password_interface.rb +17 -0
- data/lib/morpheus/api/instances_interface.rb +7 -0
- data/lib/morpheus/api/rest_interface.rb +0 -6
- data/lib/morpheus/api/roles_interface.rb +14 -0
- data/lib/morpheus/api/search_interface.rb +13 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/usage_interface.rb +18 -0
- data/lib/morpheus/cli.rb +6 -3
- data/lib/morpheus/cli/apps.rb +3 -4
- data/lib/morpheus/cli/backup_jobs_command.rb +3 -0
- data/lib/morpheus/cli/backups_command.rb +3 -0
- data/lib/morpheus/cli/budgets_command.rb +4 -4
- data/lib/morpheus/cli/catalog_command.rb +507 -0
- data/lib/morpheus/cli/cli_command.rb +45 -20
- data/lib/morpheus/cli/commands/standard/curl_command.rb +26 -12
- data/lib/morpheus/cli/commands/standard/history_command.rb +3 -1
- data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
- data/lib/morpheus/cli/commands/standard/source_command.rb +1 -1
- data/lib/morpheus/cli/commands/standard/update_command.rb +76 -0
- data/lib/morpheus/cli/containers_command.rb +14 -0
- data/lib/morpheus/cli/deploy.rb +199 -90
- data/lib/morpheus/cli/deployments.rb +342 -29
- data/lib/morpheus/cli/deploys.rb +206 -41
- data/lib/morpheus/cli/error_handler.rb +7 -0
- data/lib/morpheus/cli/forgot_password.rb +133 -0
- data/lib/morpheus/cli/groups.rb +1 -1
- data/lib/morpheus/cli/health_command.rb +2 -2
- data/lib/morpheus/cli/hosts.rb +181 -26
- data/lib/morpheus/cli/instances.rb +102 -33
- data/lib/morpheus/cli/invoices_command.rb +33 -16
- data/lib/morpheus/cli/jobs_command.rb +28 -6
- data/lib/morpheus/cli/library_option_lists_command.rb +14 -6
- data/lib/morpheus/cli/logs_command.rb +9 -6
- data/lib/morpheus/cli/mixins/accounts_helper.rb +7 -6
- data/lib/morpheus/cli/mixins/backups_helper.rb +2 -4
- data/lib/morpheus/cli/mixins/catalog_helper.rb +66 -0
- data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -3
- data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +46 -21
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +24 -4
- data/lib/morpheus/cli/network_pools_command.rb +14 -6
- data/lib/morpheus/cli/option_types.rb +266 -17
- data/lib/morpheus/cli/ping.rb +0 -1
- data/lib/morpheus/cli/provisioning_licenses_command.rb +2 -2
- data/lib/morpheus/cli/remote.rb +35 -12
- data/lib/morpheus/cli/reports_command.rb +99 -30
- data/lib/morpheus/cli/roles.rb +305 -3
- data/lib/morpheus/cli/search_command.rb +182 -0
- data/lib/morpheus/cli/service_plans_command.rb +2 -2
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +33 -11
- data/lib/morpheus/cli/storage_providers_command.rb +40 -56
- data/lib/morpheus/cli/tasks.rb +20 -21
- data/lib/morpheus/cli/tenants_command.rb +1 -1
- data/lib/morpheus/cli/usage_command.rb +203 -0
- data/lib/morpheus/cli/user_settings_command.rb +1 -0
- data/lib/morpheus/cli/users.rb +12 -1
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +280 -199
- data/lib/morpheus/cli/whoami.rb +6 -6
- data/lib/morpheus/cli/workflows.rb +34 -41
- data/lib/morpheus/formatters.rb +48 -5
- data/lib/morpheus/terminal.rb +6 -2
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25ca8fc7cabb51b4042eb212172b60191d6863cf9310ffce4e386d016692f7f1
|
4
|
+
data.tar.gz: d1183424bef986bb22123d60b45e97ed077c8ea30c5bfd249f8bf503c0a22d13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d006acc9447822675c3593de443679ac2eee514bf1ffe041ddfa5ddc44223e8edfbbeee9393056c59fb98c14d4beb240b0ce9725a3bcc56eb5e1095066d15d1c
|
7
|
+
data.tar.gz: ca41986fc3561f562b799971514b92dfe08027e06ad5443b0e116713fee9132d62b84905c929209be03a7dc0f3855e97adf7fe053e64832067addca692ef4268
|
data/Dockerfile
CHANGED
@@ -342,10 +342,18 @@ class Morpheus::APIClient
|
|
342
342
|
Morpheus::AuthInterface.new({url: @base_url, client_id: @client_id}).setopts(@options)
|
343
343
|
end
|
344
344
|
|
345
|
+
def forgot
|
346
|
+
Morpheus::ForgotPasswordInterface.new(common_interface_options).setopts(@options)
|
347
|
+
end
|
348
|
+
|
345
349
|
def whoami
|
346
350
|
Morpheus::WhoamiInterface.new(common_interface_options).setopts(@options)
|
347
351
|
end
|
348
352
|
|
353
|
+
def search
|
354
|
+
Morpheus::SearchInterface.new(common_interface_options).setopts(@options)
|
355
|
+
end
|
356
|
+
|
349
357
|
def user_settings
|
350
358
|
Morpheus::UserSettingsInterface.new(common_interface_options).setopts(@options)
|
351
359
|
end
|
@@ -764,6 +772,24 @@ class Morpheus::APIClient
|
|
764
772
|
Morpheus::BackupJobsInterface.new(common_interface_options).setopts(@options)
|
765
773
|
end
|
766
774
|
|
775
|
+
def catalog_item_types
|
776
|
+
Morpheus::CatalogItemTypesInterface.new(common_interface_options).setopts(@options)
|
777
|
+
end
|
778
|
+
|
779
|
+
def usage
|
780
|
+
Morpheus::UsageInterface.new(common_interface_options).setopts(@options)
|
781
|
+
end
|
782
|
+
|
783
|
+
def billing
|
784
|
+
Morpheus::BillingInterface.new(common_interface_options).setopts(@options)
|
785
|
+
end
|
786
|
+
|
767
787
|
# add new interfaces here
|
768
788
|
|
789
|
+
protected
|
790
|
+
|
791
|
+
def validate_id!(id)
|
792
|
+
raise "#{self.class} passed a blank id!" if id.to_s.strip.empty?
|
793
|
+
end
|
794
|
+
|
769
795
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
|
3
|
+
class Morpheus::BillingInterface < Morpheus::APIClient
|
4
|
+
|
5
|
+
def base_path
|
6
|
+
"/api/billing"
|
7
|
+
end
|
8
|
+
|
9
|
+
# this is an alias for /usage
|
10
|
+
def list(params={})
|
11
|
+
execute(method: :get, url: "#{base_path}", params: params)
|
12
|
+
end
|
13
|
+
|
14
|
+
def list_account(params={})
|
15
|
+
execute(method: :get, url: "#{base_path}/account", params: params)
|
16
|
+
end
|
17
|
+
|
18
|
+
def list_zones(params={})
|
19
|
+
execute(method: :get, url: "#{base_path}/zones", params: params)
|
20
|
+
end
|
21
|
+
|
22
|
+
def list_instances(params={})
|
23
|
+
execute(method: :get, url: "#{base_path}/instances", params: params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def list_servers(params={})
|
27
|
+
execute(method: :get, url: "#{base_path}/servers", params: params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def list_discovered_servers(params={})
|
31
|
+
execute(method: :get, url: "#{base_path}/discoveredServers", params: params)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -18,7 +18,7 @@ class Morpheus::DeployInterface < Morpheus::APIClient
|
|
18
18
|
execute(method: :get, url: "#{base_path}", params: params)
|
19
19
|
end
|
20
20
|
|
21
|
-
def get(
|
21
|
+
def get(id, params={})
|
22
22
|
validate_id!(id)
|
23
23
|
execute(method: :get, url: "#{base_path}/#{id}", params: params)
|
24
24
|
end
|
@@ -40,7 +40,8 @@ class Morpheus::DeploymentsInterface < Morpheus::RestInterface
|
|
40
40
|
if destination.empty? || destination == "/" || destination == "." || destination.include?("../")
|
41
41
|
raise "#{self.class}.upload_file() passed a bad destination: '#{destination}'"
|
42
42
|
end
|
43
|
-
url = "#{@base_url}/#{base_path}/#{deployment_id}/versions/#{id}/files"
|
43
|
+
# url = "#{@base_url}/#{base_path}/#{deployment_id}/versions/#{id}/files"
|
44
|
+
url = "#{base_path}/#{deployment_id}/versions/#{id}/files"
|
44
45
|
if !destination.to_s.empty?
|
45
46
|
url += "/#{destination}"
|
46
47
|
end
|
@@ -57,4 +58,22 @@ class Morpheus::DeploymentsInterface < Morpheus::RestInterface
|
|
57
58
|
execute(method: :post, url: url, headers: headers, payload: payload, params: params, timeout: 172800)
|
58
59
|
end
|
59
60
|
|
61
|
+
# upload a file without multipart
|
62
|
+
# local_file is the full absolute local filename
|
63
|
+
# destination should be the full remote file path, including the file name.
|
64
|
+
def destroy_file(deployment_id, id, destination, params={})
|
65
|
+
if destination.empty? || destination == "/" || destination == "." || destination.include?("../")
|
66
|
+
raise "#{self.class}.upload_file() passed a bad destination: '#{destination}'"
|
67
|
+
end
|
68
|
+
# url = "#{@base_url}/#{base_path}/#{deployment_id}/versions/#{id}/files"
|
69
|
+
url = "#{base_path}/#{deployment_id}/versions/#{id}/files"
|
70
|
+
if !destination.to_s.empty?
|
71
|
+
url += "/#{destination}"
|
72
|
+
end
|
73
|
+
# use URI to escape path
|
74
|
+
uri = URI.parse(url)
|
75
|
+
url = uri.path
|
76
|
+
execute(method: :delete, url: url, params: params)
|
77
|
+
end
|
78
|
+
|
60
79
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
# There is no Authorization required for this API.
|
3
|
+
class Morpheus::ForgotPasswordInterface < Morpheus::APIClient
|
4
|
+
|
5
|
+
def authorization_required?
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_email(payload, params={})
|
10
|
+
execute(method: :post, url: "/api/forgot/send-email", params: params, payload: payload.to_json)
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_password(payload, params={})
|
14
|
+
execute(method: :post, url: "/api/forgot/reset-password", params: params, payload: payload.to_json)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -218,6 +218,13 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
|
|
218
218
|
execute(opts)
|
219
219
|
end
|
220
220
|
|
221
|
+
def snapshots(instance_id, params={})
|
222
|
+
url = "#{@base_url}/api/instances/#{instance_id}/snapshots"
|
223
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
224
|
+
opts = {method: :get, url: url, headers: headers}
|
225
|
+
execute(opts)
|
226
|
+
end
|
227
|
+
|
221
228
|
def import_snapshot(id, params={}, payload={})
|
222
229
|
url = "#{@base_url}/api/instances/#{id}/import-snapshot"
|
223
230
|
headers = {:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
@@ -31,10 +31,4 @@ class Morpheus::RestInterface < Morpheus::APIClient
|
|
31
31
|
execute(method: :delete, url: "#{base_path}/#{id}", params: params)
|
32
32
|
end
|
33
33
|
|
34
|
-
protected
|
35
|
-
|
36
|
-
def validate_id!(id)
|
37
|
-
raise "#{self.class} passed a blank id!" if id.to_s.strip.empty?
|
38
|
-
end
|
39
|
-
|
40
34
|
end
|
@@ -77,6 +77,20 @@ class Morpheus::RolesInterface < Morpheus::APIClient
|
|
77
77
|
execute(method: :put, url: url, headers: headers, payload: payload.to_json)
|
78
78
|
end
|
79
79
|
|
80
|
+
def update_catalog_item_type(account_id, id, options)
|
81
|
+
url = build_url(account_id, id) + "/update-catalog-item-type"
|
82
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
83
|
+
payload = options
|
84
|
+
execute(method: :put, url: url, headers: headers, payload: payload.to_json)
|
85
|
+
end
|
86
|
+
|
87
|
+
def update_persona(account_id, id, options)
|
88
|
+
url = build_url(account_id, id) + "/update-persona"
|
89
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
90
|
+
payload = options
|
91
|
+
execute(method: :put, url: url, headers: headers, payload: payload.to_json)
|
92
|
+
end
|
93
|
+
|
80
94
|
private
|
81
95
|
|
82
96
|
def build_url(account_id=nil, role_id=nil)
|
@@ -169,4 +169,11 @@ class Morpheus::ServersInterface < Morpheus::APIClient
|
|
169
169
|
execute(opts)
|
170
170
|
end
|
171
171
|
|
172
|
+
def snapshots(id, params={})
|
173
|
+
url = "#{@base_url}/api/servers/#{id}/snapshots"
|
174
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
175
|
+
opts = {method: :get, url: url, headers: headers}
|
176
|
+
execute(opts)
|
177
|
+
end
|
178
|
+
|
172
179
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
|
3
|
+
class Morpheus::UsageInterface < Morpheus::APIClient
|
4
|
+
|
5
|
+
def base_path
|
6
|
+
"/api/usage" # not /usages ?
|
7
|
+
end
|
8
|
+
|
9
|
+
def list(params={})
|
10
|
+
execute(method: :get, url: "#{base_path}", params: params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(id, params={})
|
14
|
+
validate_id!(id)
|
15
|
+
execute(method: :get, url: "#{base_path}/#{id}", params: params)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/lib/morpheus/cli.rb
CHANGED
@@ -67,8 +67,6 @@ module Morpheus
|
|
67
67
|
# all standard commands
|
68
68
|
Dir[File.dirname(__FILE__) + "/cli/commands/standard/**/*.rb"].each {|file| load file }
|
69
69
|
|
70
|
-
# shell scripting commands
|
71
|
-
|
72
70
|
# all the known commands
|
73
71
|
load 'morpheus/cli/remote.rb'
|
74
72
|
load 'morpheus/cli/doc.rb'
|
@@ -76,9 +74,11 @@ module Morpheus
|
|
76
74
|
load 'morpheus/cli/setup.rb'
|
77
75
|
load 'morpheus/cli/login.rb'
|
78
76
|
load 'morpheus/cli/logout.rb'
|
77
|
+
load 'morpheus/cli/forgot_password.rb'
|
79
78
|
load 'morpheus/cli/whoami.rb'
|
80
79
|
load 'morpheus/cli/access_token_command.rb'
|
81
80
|
load 'morpheus/cli/user_settings_command.rb'
|
81
|
+
load 'morpheus/cli/search_command.rb'
|
82
82
|
load 'morpheus/cli/dashboard_command.rb'
|
83
83
|
load 'morpheus/cli/recent_activity_command.rb' # deprecated, removing soon
|
84
84
|
load 'morpheus/cli/activity_command.rb'
|
@@ -96,11 +96,12 @@ module Morpheus
|
|
96
96
|
load 'morpheus/cli/tasks.rb'
|
97
97
|
load 'morpheus/cli/workflows.rb'
|
98
98
|
load 'morpheus/cli/deployments.rb'
|
99
|
+
load 'morpheus/cli/deploy.rb'
|
100
|
+
load 'morpheus/cli/deploys.rb'
|
99
101
|
load 'morpheus/cli/instances.rb'
|
100
102
|
load 'morpheus/cli/containers_command.rb'
|
101
103
|
load 'morpheus/cli/apps.rb'
|
102
104
|
load 'morpheus/cli/blueprints_command.rb'
|
103
|
-
load 'morpheus/cli/deploys.rb'
|
104
105
|
load 'morpheus/cli/license.rb'
|
105
106
|
load 'morpheus/cli/instance_types.rb'
|
106
107
|
load 'morpheus/cli/jobs_command.rb'
|
@@ -174,6 +175,8 @@ module Morpheus
|
|
174
175
|
load 'morpheus/cli/projects_command.rb'
|
175
176
|
load 'morpheus/cli/backups_command.rb'
|
176
177
|
load 'morpheus/cli/backup_jobs_command.rb'
|
178
|
+
load 'morpheus/cli/catalog_command.rb'
|
179
|
+
load 'morpheus/cli/usage_command.rb'
|
177
180
|
# add new commands here...
|
178
181
|
|
179
182
|
end
|
data/lib/morpheus/cli/apps.rb
CHANGED
@@ -92,10 +92,9 @@ class Morpheus::Cli::Apps
|
|
92
92
|
opts.footer = "List apps."
|
93
93
|
end
|
94
94
|
optparse.parse!(args)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
return 1
|
95
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
96
|
+
if args.count > 0
|
97
|
+
options[:phrase] = args.join(" ")
|
99
98
|
end
|
100
99
|
connect(options)
|
101
100
|
begin
|
@@ -225,6 +225,9 @@ EOT
|
|
225
225
|
print_dry_run @backup_jobs_interface.dry.destroy(backup_job['id'], params)
|
226
226
|
return
|
227
227
|
end
|
228
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the backup #{backup['name']}?")
|
229
|
+
return 9, "aborted command"
|
230
|
+
end
|
228
231
|
json_response = @backup_jobs_interface.destroy(backup_job['id'], params)
|
229
232
|
render_response(json_response, options) do
|
230
233
|
print_green_success "Removed backup job #{backup_job['name']}"
|
@@ -215,6 +215,9 @@ EOT
|
|
215
215
|
print_dry_run @backups_interface.dry.destroy(backup['id'], params)
|
216
216
|
return
|
217
217
|
end
|
218
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the backup #{backup['name']}?")
|
219
|
+
return 9, "aborted command"
|
220
|
+
end
|
218
221
|
json_response = @backups_interface.destroy(backup['id'], params)
|
219
222
|
render_response(json_response, options) do
|
220
223
|
print_green_success "Removed backup #{backup['name']}"
|
@@ -570,16 +570,16 @@ class Morpheus::Cli::BudgetsCommand
|
|
570
570
|
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 1},
|
571
571
|
# {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'defaultValue' => true},
|
572
572
|
{'fieldName' => 'scope', 'fieldLabel' => 'Scope', 'code' => 'budget.scope', 'type' => 'select', 'selectOptions' => [{'name'=>'Account','value'=>'account'},{'name'=>'Tenant','value'=>'tenant'},{'name'=>'Cloud','value'=>'cloud'},{'name'=>'Group','value'=>'group'},{'name'=>'User','value'=>'user'}], 'defaultValue' => 'account', 'required' => true, 'displayOrder' => 3},
|
573
|
-
{'fieldName' => 'tenant', 'fieldLabel' => 'Tenant', 'type' => 'select', 'optionSource' => lambda {
|
573
|
+
{'fieldName' => 'tenant', 'fieldLabel' => 'Tenant', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
|
574
574
|
@options_interface.options_for_source("tenants", {})['data']
|
575
575
|
}, 'required' => true, 'dependsOnCode' => 'budget.scope:tenant', 'displayOrder' => 4},
|
576
|
-
{'fieldName' => 'user', 'fieldLabel' => 'User', 'type' => 'select', 'optionSource' => lambda {
|
576
|
+
{'fieldName' => 'user', 'fieldLabel' => 'User', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
|
577
577
|
@options_interface.options_for_source("users", {})['data']
|
578
578
|
}, 'required' => true, 'dependsOnCode' => 'budget.scope:user', 'displayOrder' => 5},
|
579
|
-
{'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'optionSource' => lambda {
|
579
|
+
{'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
|
580
580
|
@options_interface.options_for_source("groups", {})['data']
|
581
581
|
}, 'required' => true, 'dependsOnCode' => 'budget.scope:group', 'displayOrder' => 6},
|
582
|
-
{'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'optionSource' => lambda {
|
582
|
+
{'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
|
583
583
|
@options_interface.options_for_source("clouds", {})['data']
|
584
584
|
}, 'required' => true, 'dependsOnCode' => 'budget.scope:cloud', 'displayOrder' => 7},
|
585
585
|
{'fieldName' => 'year', 'fieldLabel' => 'Period', 'type' => 'text', 'required' => true, 'defaultValue' => Time.now.year, 'description' => "The period (year) the budget applies to. Default is the current year.", 'displayOrder' => 8},
|
@@ -0,0 +1,507 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
# CLI command self service
|
4
|
+
# UI is Tools: Self Service - Catalog Items
|
5
|
+
# API is /catalog-item-types and returns catalogItemTypes
|
6
|
+
class Morpheus::Cli::CatalogCommand
|
7
|
+
include Morpheus::Cli::CliCommand
|
8
|
+
include Morpheus::Cli::CatalogHelper
|
9
|
+
include Morpheus::Cli::LibraryHelper
|
10
|
+
include Morpheus::Cli::OptionSourceHelper
|
11
|
+
|
12
|
+
# hide until 5.1 when update api is fixed and service-catalog endpoints are available
|
13
|
+
set_command_hidden
|
14
|
+
set_command_name :'catalog'
|
15
|
+
|
16
|
+
register_subcommands :list, :get, :add, :update, :remove
|
17
|
+
|
18
|
+
def connect(opts)
|
19
|
+
@api_client = establish_remote_appliance_connection(opts)
|
20
|
+
@catalog_item_types_interface = @api_client.catalog_item_types
|
21
|
+
@option_types_interface = @api_client.option_types
|
22
|
+
end
|
23
|
+
|
24
|
+
def handle(args)
|
25
|
+
handle_subcommand(args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def list(args)
|
29
|
+
options = {}
|
30
|
+
params = {}
|
31
|
+
ref_ids = []
|
32
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
33
|
+
opts.banner = subcommand_usage("[search]")
|
34
|
+
opts.on( '--enabled [on|off]', String, "Filter by enabled" ) do |val|
|
35
|
+
params['enabled'] = (val.to_s != 'false' && val.to_s != 'off')
|
36
|
+
end
|
37
|
+
opts.on( '--featured [on|off]', String, "Filter by featured" ) do |val|
|
38
|
+
params['featured'] = (val.to_s != 'false' && val.to_s != 'off')
|
39
|
+
end
|
40
|
+
build_standard_list_options(opts, options)
|
41
|
+
opts.footer = "List catalog items."
|
42
|
+
end
|
43
|
+
optparse.parse!(args)
|
44
|
+
connect(options)
|
45
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
46
|
+
if args.count > 0
|
47
|
+
options[:phrase] = args.join(" ")
|
48
|
+
end
|
49
|
+
params.merge!(parse_list_options(options))
|
50
|
+
@catalog_item_types_interface.setopts(options)
|
51
|
+
if options[:dry_run]
|
52
|
+
print_dry_run @catalog_item_types_interface.dry.list(params)
|
53
|
+
return
|
54
|
+
end
|
55
|
+
json_response = @catalog_item_types_interface.list(params)
|
56
|
+
catalog_item_types = json_response[catalog_item_type_list_key]
|
57
|
+
render_response(json_response, options, catalog_item_type_list_key) do
|
58
|
+
print_h1 "Morpheus Catalog Items", parse_list_subtitles(options), options
|
59
|
+
if catalog_item_types.empty?
|
60
|
+
print cyan,"No catalog items found.",reset,"\n"
|
61
|
+
else
|
62
|
+
list_columns = catalog_item_type_column_definitions.upcase_keys!
|
63
|
+
#list_columns["Config"] = lambda {|it| truncate_string(it['config'], 100) }
|
64
|
+
print as_pretty_table(catalog_item_types, list_columns.upcase_keys!, options)
|
65
|
+
print_results_pagination(json_response)
|
66
|
+
end
|
67
|
+
print reset,"\n"
|
68
|
+
end
|
69
|
+
if catalog_item_types.empty?
|
70
|
+
return 1, "no catalog items found"
|
71
|
+
else
|
72
|
+
return 0, nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def get(args)
|
77
|
+
params = {}
|
78
|
+
options = {}
|
79
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
80
|
+
opts.banner = subcommand_usage("[catalog item type]")
|
81
|
+
opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
|
82
|
+
options[:show_config] = true
|
83
|
+
end
|
84
|
+
# opts.on('--no-config', "Do not display config content." ) do
|
85
|
+
# options[:no_config] = true
|
86
|
+
# end
|
87
|
+
build_standard_get_options(opts, options)
|
88
|
+
opts.footer = <<-EOT
|
89
|
+
Get details about a specific catalog item type.
|
90
|
+
[catalog item type] is required. This is the name or id of a catalog item type.
|
91
|
+
EOT
|
92
|
+
end
|
93
|
+
optparse.parse!(args)
|
94
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
95
|
+
connect(options)
|
96
|
+
id_list = parse_id_list(args)
|
97
|
+
return run_command_for_each_arg(id_list) do |arg|
|
98
|
+
_get(arg, params, options)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def _get(id, params, options)
|
103
|
+
catalog_item_type = nil
|
104
|
+
if id.to_s !~ /\A\d{1,}\Z/
|
105
|
+
catalog_item_type = find_catalog_item_type_by_name(id)
|
106
|
+
return 1, "catalog item type not found for #{id}" if catalog_item_type.nil?
|
107
|
+
id = catalog_item_type['id']
|
108
|
+
end
|
109
|
+
@catalog_item_types_interface.setopts(options)
|
110
|
+
if options[:dry_run]
|
111
|
+
print_dry_run @catalog_item_types_interface.dry.get(id, params)
|
112
|
+
return
|
113
|
+
end
|
114
|
+
# skip extra query, list has same data as show right now
|
115
|
+
if catalog_item_type
|
116
|
+
json_response = {catalog_item_type_object_key => catalog_item_type}
|
117
|
+
else
|
118
|
+
json_response = @catalog_item_types_interface.get(id, params)
|
119
|
+
end
|
120
|
+
catalog_item_type = json_response[catalog_item_type_object_key]
|
121
|
+
config = catalog_item_type['config'] || {}
|
122
|
+
# export just the config as json or yaml (default)
|
123
|
+
if options[:show_config]
|
124
|
+
unless options[:json] || options[:yaml] || options[:csv]
|
125
|
+
options[:yaml] = true
|
126
|
+
end
|
127
|
+
return render_with_format(config, options)
|
128
|
+
end
|
129
|
+
render_response(json_response, options, catalog_item_type_object_key) do
|
130
|
+
print_h1 "Catalog Item Type Details", [], options
|
131
|
+
print cyan
|
132
|
+
show_columns = catalog_item_type_column_definitions
|
133
|
+
show_columns.delete("Blueprint") unless catalog_item_type['blueprint']
|
134
|
+
print_description_list(show_columns, catalog_item_type)
|
135
|
+
|
136
|
+
if catalog_item_type['optionTypes'] && catalog_item_type['optionTypes'].size > 0
|
137
|
+
print_h2 "Option Types"
|
138
|
+
opt_columns = [
|
139
|
+
{"ID" => lambda {|it| it['id'] } },
|
140
|
+
{"NAME" => lambda {|it| it['name'] } },
|
141
|
+
{"TYPE" => lambda {|it| it['type'] } },
|
142
|
+
{"FIELD NAME" => lambda {|it| it['fieldName'] } },
|
143
|
+
{"FIELD LABEL" => lambda {|it| it['fieldLabel'] } },
|
144
|
+
{"DEFAULT" => lambda {|it| it['defaultValue'] } },
|
145
|
+
{"REQUIRED" => lambda {|it| format_boolean it['required'] } },
|
146
|
+
]
|
147
|
+
print as_pretty_table(catalog_item_type['optionTypes'], opt_columns)
|
148
|
+
else
|
149
|
+
# print cyan,"No option types found for this catalog item.","\n",reset
|
150
|
+
end
|
151
|
+
|
152
|
+
if config && options[:no_config] != true
|
153
|
+
print_h2 "Config YAML"
|
154
|
+
#print reset,(JSON.pretty_generate(config) rescue config),"\n",reset
|
155
|
+
#print reset,(as_yaml(config, options) rescue config),"\n",reset
|
156
|
+
config_string = as_yaml(config, options) rescue config
|
157
|
+
config_lines = config_string.split("\n")
|
158
|
+
config_line_count = config_lines.size
|
159
|
+
max_lines = 10
|
160
|
+
if config_lines.size > max_lines
|
161
|
+
config_string = config_lines.first(max_lines).join("\n")
|
162
|
+
config_string << "\n\n"
|
163
|
+
config_string << "(#{(config_line_count - max_lines)} more lines were not shown, use -c to show the config)"
|
164
|
+
#config_string << "\n"
|
165
|
+
end
|
166
|
+
# strip --- yaml header
|
167
|
+
if config_string[0..3] == "---\n"
|
168
|
+
config_string = config_string[4..-1]
|
169
|
+
end
|
170
|
+
print reset,config_string.chomp("\n"),"\n",reset
|
171
|
+
end
|
172
|
+
|
173
|
+
print reset,"\n"
|
174
|
+
end
|
175
|
+
return 0, nil
|
176
|
+
end
|
177
|
+
|
178
|
+
def add(args)
|
179
|
+
options = {}
|
180
|
+
params = {}
|
181
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
182
|
+
opts.banner = subcommand_usage("[name] [options]")
|
183
|
+
build_option_type_options(opts, options, add_catalog_item_type_option_types)
|
184
|
+
opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
|
185
|
+
options[:config_file] = val.to_s
|
186
|
+
file_content = nil
|
187
|
+
full_filename = File.expand_path(options[:config_file])
|
188
|
+
if File.exists?(full_filename)
|
189
|
+
file_content = File.read(full_filename)
|
190
|
+
else
|
191
|
+
print_red_alert "File not found: #{full_filename}"
|
192
|
+
return 1
|
193
|
+
end
|
194
|
+
parse_result = parse_json_or_yaml(file_content)
|
195
|
+
config_map = parse_result[:data]
|
196
|
+
if config_map.nil?
|
197
|
+
# todo: bubble up JSON.parse error message
|
198
|
+
raise_command_error "Failed to parse config as YAML or JSON. Error: #{parse_result[:err]}"
|
199
|
+
#raise_command_error "Failed to parse config as valid YAML or JSON."
|
200
|
+
else
|
201
|
+
params['config'] = config_map
|
202
|
+
options[:options]['config'] = params['config'] # or file_content
|
203
|
+
end
|
204
|
+
end
|
205
|
+
opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
|
206
|
+
if list.nil?
|
207
|
+
params['optionTypes'] = []
|
208
|
+
else
|
209
|
+
params['optionTypes'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
210
|
+
end
|
211
|
+
end
|
212
|
+
opts.on('--optionTypes [x,y,z]', Array, "List of Option Type IDs") do |list|
|
213
|
+
if list.nil?
|
214
|
+
params['optionTypes'] = []
|
215
|
+
else
|
216
|
+
params['optionTypes'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
217
|
+
end
|
218
|
+
end
|
219
|
+
opts.add_hidden_option('--optionTypes')
|
220
|
+
build_option_type_options(opts, options, add_catalog_item_type_advanced_option_types)
|
221
|
+
build_standard_add_options(opts, options)
|
222
|
+
opts.footer = <<-EOT
|
223
|
+
Create a new catalog item type.
|
224
|
+
EOT
|
225
|
+
end
|
226
|
+
optparse.parse!(args)
|
227
|
+
verify_args!(args:args, optparse:optparse, min:0, max:1)
|
228
|
+
options[:options]['name'] = args[0] if args[0]
|
229
|
+
connect(options)
|
230
|
+
payload = {}
|
231
|
+
if options[:payload]
|
232
|
+
payload = options[:payload]
|
233
|
+
payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
|
234
|
+
else
|
235
|
+
payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
|
236
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(add_catalog_item_type_option_types(), options[:options], @api_client, options[:params])
|
237
|
+
params.deep_merge!(v_prompt)
|
238
|
+
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_catalog_item_type_advanced_option_types, options[:options], @api_client, options[:params])
|
239
|
+
advanced_config.deep_compact!
|
240
|
+
params.deep_merge!(advanced_config)
|
241
|
+
# convert checkbox "on" and "off" to true and false
|
242
|
+
params.booleanize!
|
243
|
+
# convert type to refType until api accepts type
|
244
|
+
if params['type'] && !params['refType']
|
245
|
+
if params['type'].to_s.downcase == 'blueprint'
|
246
|
+
params['refType'] = 'AppTemplate'
|
247
|
+
else
|
248
|
+
params['refType'] = 'InstanceType'
|
249
|
+
end
|
250
|
+
end
|
251
|
+
# convert config string to a map
|
252
|
+
config = params['config']
|
253
|
+
if config && config.is_a?(String)
|
254
|
+
parse_result = parse_json_or_yaml(config)
|
255
|
+
config_map = parse_result[:data]
|
256
|
+
if config_map.nil?
|
257
|
+
# todo: bubble up JSON.parse error message
|
258
|
+
raise_command_error "Failed to parse config as YAML or JSON. Error: #{parse_result[:err]}"
|
259
|
+
#raise_command_error "Failed to parse config as valid YAML or JSON."
|
260
|
+
else
|
261
|
+
params['config'] = config_map
|
262
|
+
end
|
263
|
+
end
|
264
|
+
if params['optionTypes']
|
265
|
+
# todo: move to optionSource, so it will be /api/options/optionTypes lol
|
266
|
+
prompt_results = prompt_for_option_types(params, options, @api_client)
|
267
|
+
if prompt_results[:success]
|
268
|
+
params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
|
269
|
+
else
|
270
|
+
return 1
|
271
|
+
end
|
272
|
+
end
|
273
|
+
payload[catalog_item_type_object_key].deep_merge!(params)
|
274
|
+
end
|
275
|
+
@catalog_item_types_interface.setopts(options)
|
276
|
+
if options[:dry_run]
|
277
|
+
print_dry_run @catalog_item_types_interface.dry.create(payload)
|
278
|
+
return 0, nil
|
279
|
+
end
|
280
|
+
json_response = @catalog_item_types_interface.create(payload)
|
281
|
+
catalog_item_type = json_response[catalog_item_type_object_key]
|
282
|
+
render_response(json_response, options, catalog_item_type_object_key) do
|
283
|
+
print_green_success "Added catalog item #{catalog_item_type['name']}"
|
284
|
+
return _get(catalog_item_type["id"], {}, options)
|
285
|
+
end
|
286
|
+
return 0, nil
|
287
|
+
end
|
288
|
+
|
289
|
+
def update(args)
|
290
|
+
options = {}
|
291
|
+
params = {}
|
292
|
+
payload = {}
|
293
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
294
|
+
opts.banner = subcommand_usage("[catalog item type] [options]")
|
295
|
+
build_option_type_options(opts, options, update_catalog_item_type_option_types)
|
296
|
+
opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
|
297
|
+
options[:config_file] = val.to_s
|
298
|
+
file_content = nil
|
299
|
+
full_filename = File.expand_path(options[:config_file])
|
300
|
+
if File.exists?(full_filename)
|
301
|
+
file_content = File.read(full_filename)
|
302
|
+
else
|
303
|
+
print_red_alert "File not found: #{full_filename}"
|
304
|
+
return 1
|
305
|
+
end
|
306
|
+
parse_result = parse_json_or_yaml(file_content)
|
307
|
+
config_map = parse_result[:data]
|
308
|
+
if config_map.nil?
|
309
|
+
# todo: bubble up JSON.parse error message
|
310
|
+
raise_command_error "Failed to parse config as YAML or JSON. Error: #{parse_result[:err]}"
|
311
|
+
#raise_command_error "Failed to parse config as valid YAML or JSON."
|
312
|
+
else
|
313
|
+
params['config'] = config_map
|
314
|
+
options[:options]['config'] = params['config'] # or file_content
|
315
|
+
end
|
316
|
+
end
|
317
|
+
opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
|
318
|
+
if list.nil?
|
319
|
+
params['optionTypes'] = []
|
320
|
+
else
|
321
|
+
params['optionTypes'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
322
|
+
end
|
323
|
+
end
|
324
|
+
opts.on('--optionTypes [x,y,z]', Array, "List of Option Type IDs") do |list|
|
325
|
+
if list.nil?
|
326
|
+
params['optionTypes'] = []
|
327
|
+
else
|
328
|
+
params['optionTypes'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
329
|
+
end
|
330
|
+
end
|
331
|
+
opts.add_hidden_option('--optionTypes')
|
332
|
+
build_option_type_options(opts, options, update_catalog_item_type_advanced_option_types)
|
333
|
+
build_standard_update_options(opts, options)
|
334
|
+
opts.footer = <<-EOT
|
335
|
+
Update a catalog item type.
|
336
|
+
[catalog item type] is required. This is the name or id of a catalog item type.
|
337
|
+
EOT
|
338
|
+
end
|
339
|
+
optparse.parse!(args)
|
340
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
341
|
+
connect(options)
|
342
|
+
catalog_item_type = find_catalog_item_type_by_name_or_id(args[0])
|
343
|
+
return 1 if catalog_item_type.nil?
|
344
|
+
payload = {}
|
345
|
+
if options[:payload]
|
346
|
+
payload = options[:payload]
|
347
|
+
payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
|
348
|
+
else
|
349
|
+
payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
|
350
|
+
# do not prompt on update
|
351
|
+
v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_catalog_item_type_option_types, options[:options], @api_client, options[:params])
|
352
|
+
v_prompt.deep_compact!
|
353
|
+
params.deep_merge!(v_prompt)
|
354
|
+
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_catalog_item_type_advanced_option_types, options[:options], @api_client, options[:params])
|
355
|
+
advanced_config.deep_compact!
|
356
|
+
params.deep_merge!(advanced_config)
|
357
|
+
# convert checkbox "on" and "off" to true and false
|
358
|
+
params.booleanize!
|
359
|
+
# convert type to refType until api accepts type
|
360
|
+
if params['type'] && !params['refType']
|
361
|
+
if params['type'].to_s.downcase == 'blueprint'
|
362
|
+
params['refType'] = 'AppTemplate'
|
363
|
+
else
|
364
|
+
params['refType'] = 'InstanceType'
|
365
|
+
end
|
366
|
+
end
|
367
|
+
# convert config string to a map
|
368
|
+
config = params['config']
|
369
|
+
if config && config.is_a?(String)
|
370
|
+
parse_result = parse_json_or_yaml(config)
|
371
|
+
config_map = parse_result[:data]
|
372
|
+
if config_map.nil?
|
373
|
+
# todo: bubble up JSON.parse error message
|
374
|
+
raise_command_error "Failed to parse config as YAML or JSON. Error: #{parse_result[:err]}"
|
375
|
+
#raise_command_error "Failed to parse config as valid YAML or JSON."
|
376
|
+
else
|
377
|
+
params['config'] = config_map
|
378
|
+
end
|
379
|
+
end
|
380
|
+
payload.deep_merge!({catalog_item_type_object_key => params})
|
381
|
+
if payload[catalog_item_type_object_key].empty? # || options[:no_prompt]
|
382
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
383
|
+
end
|
384
|
+
end
|
385
|
+
@catalog_item_types_interface.setopts(options)
|
386
|
+
if options[:dry_run]
|
387
|
+
print_dry_run @catalog_item_types_interface.dry.update(catalog_item_type['id'], payload)
|
388
|
+
return
|
389
|
+
end
|
390
|
+
json_response = @catalog_item_types_interface.update(catalog_item_type['id'], payload)
|
391
|
+
catalog_item_type = json_response[catalog_item_type_object_key]
|
392
|
+
render_response(json_response, options, catalog_item_type_object_key) do
|
393
|
+
print_green_success "Updated catalog item #{catalog_item_type['name']}"
|
394
|
+
return _get(catalog_item_type["id"], {}, options)
|
395
|
+
end
|
396
|
+
return 0, nil
|
397
|
+
end
|
398
|
+
|
399
|
+
def remove(args)
|
400
|
+
options = {}
|
401
|
+
params = {}
|
402
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
403
|
+
opts.banner = subcommand_usage("[catalog item type] [options]")
|
404
|
+
build_standard_remove_options(opts, options)
|
405
|
+
opts.footer = <<-EOT
|
406
|
+
Delete a catalog_item_type.
|
407
|
+
[catalog item type] is required. This is the name or id of a catalog item type.
|
408
|
+
EOT
|
409
|
+
end
|
410
|
+
optparse.parse!(args)
|
411
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
412
|
+
connect(options)
|
413
|
+
catalog_item_type = find_catalog_item_type_by_name_or_id(args[0])
|
414
|
+
return 1 if catalog_item_type.nil?
|
415
|
+
@catalog_item_types_interface.setopts(options)
|
416
|
+
if options[:dry_run]
|
417
|
+
print_dry_run @catalog_item_types_interface.dry.destroy(catalog_item_type['id'], params)
|
418
|
+
return
|
419
|
+
end
|
420
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the catalog item #{catalog_item_type['name']}?")
|
421
|
+
return 9, "aborted command"
|
422
|
+
end
|
423
|
+
json_response = @catalog_item_types_interface.destroy(catalog_item_type['id'], params)
|
424
|
+
render_response(json_response, options) do
|
425
|
+
print_green_success "Removed catalog item #{catalog_item_type['name']}"
|
426
|
+
end
|
427
|
+
return 0, nil
|
428
|
+
end
|
429
|
+
|
430
|
+
private
|
431
|
+
|
432
|
+
def catalog_item_type_column_definitions()
|
433
|
+
{
|
434
|
+
"ID" => 'id',
|
435
|
+
"Name" => 'name',
|
436
|
+
"Description" => 'description',
|
437
|
+
"Type" => lambda {|it| format_catalog_type(it) },
|
438
|
+
"Blueprint" => lambda {|it| it['blueprint'] ? it['blueprint']['name'] : nil },
|
439
|
+
"Enabled" => lambda {|it| format_boolean(it['enabled']) },
|
440
|
+
"Featured" => lambda {|it| format_boolean(it['featured']) },
|
441
|
+
#"Config" => lambda {|it| it['config'] },
|
442
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
443
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
444
|
+
}
|
445
|
+
end
|
446
|
+
|
447
|
+
def format_catalog_type(catalog_item_type)
|
448
|
+
out = ""
|
449
|
+
# api "blueprint": {"name":my blueprint"} }
|
450
|
+
# instead of cryptic refType
|
451
|
+
if catalog_item_type['type']
|
452
|
+
if catalog_item_type['type'].is_a?(String)
|
453
|
+
out << catalog_item_type['type'].to_s.capitalize
|
454
|
+
else
|
455
|
+
out << (catalog_item_type['type']['name'] || catalog_item_type['type']['code']) rescue catalog_item_type['type'].to_s
|
456
|
+
end
|
457
|
+
else
|
458
|
+
ref_type = catalog_item_type['refType']
|
459
|
+
if ref_type == 'InstanceType'
|
460
|
+
out << "Instance"
|
461
|
+
elsif ref_type == 'AppTemplate'
|
462
|
+
out << "Blueprint"
|
463
|
+
elsif ref_type
|
464
|
+
out << ref_type
|
465
|
+
else
|
466
|
+
"(none)"
|
467
|
+
end
|
468
|
+
end
|
469
|
+
out
|
470
|
+
end
|
471
|
+
|
472
|
+
# this is not so simple, need to first choose select instance, host or provider
|
473
|
+
def add_catalog_item_type_option_types
|
474
|
+
[
|
475
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
|
476
|
+
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
|
477
|
+
{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}], 'defaultValue' => 'instance'},
|
478
|
+
{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'defaultValue' => true},
|
479
|
+
{'fieldName' => 'featured', 'fieldLabel' => 'Featured', 'type' => 'checkbox', 'defaultValue' => false},
|
480
|
+
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'required' => true},
|
481
|
+
{'fieldName' => 'iconPath', 'fieldLabel' => 'Logo', 'type' => 'select', 'optionSource' => 'iconList'},
|
482
|
+
#{'fieldName' => 'optionTypes', 'fieldLabel' => 'Option Types', 'type' => 'text', 'description' => 'Option Types to include, comma separated list of names or IDs.'},
|
483
|
+
{'fieldName' => 'config', 'fieldLabel' => 'Config', 'type' => 'code-editor', 'required' => true, 'description' => 'JSON or YAML'}
|
484
|
+
]
|
485
|
+
end
|
486
|
+
|
487
|
+
def add_catalog_item_type_advanced_option_types
|
488
|
+
[]
|
489
|
+
end
|
490
|
+
|
491
|
+
def update_catalog_item_type_option_types
|
492
|
+
add_catalog_item_type_option_types.collect {|it|
|
493
|
+
it.delete('required')
|
494
|
+
it.delete('defaultValue')
|
495
|
+
it
|
496
|
+
}
|
497
|
+
end
|
498
|
+
|
499
|
+
def update_catalog_item_type_advanced_option_types
|
500
|
+
add_catalog_item_type_advanced_option_types.collect {|it|
|
501
|
+
it.delete('required')
|
502
|
+
it.delete('defaultValue')
|
503
|
+
it
|
504
|
+
}
|
505
|
+
end
|
506
|
+
|
507
|
+
end
|