morpheus-cli 5.0.2 → 5.2.0
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 +4 -0
- data/lib/morpheus/api/instances_interface.rb +9 -2
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/service_catalog_interface.rb +89 -0
- data/lib/morpheus/cli.rb +2 -1
- data/lib/morpheus/cli/apps.rb +3 -23
- data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
- data/lib/morpheus/cli/cli_command.rb +25 -1
- data/lib/morpheus/cli/containers_command.rb +0 -24
- data/lib/morpheus/cli/cypher_command.rb +6 -2
- data/lib/morpheus/cli/health_command.rb +57 -0
- data/lib/morpheus/cli/hosts.rb +85 -9
- data/lib/morpheus/cli/instances.rb +85 -68
- data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
- data/lib/morpheus/cli/library_option_types_command.rb +5 -2
- data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +76 -0
- data/lib/morpheus/cli/option_types.rb +10 -10
- data/lib/morpheus/cli/roles.rb +193 -155
- data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
- data/lib/morpheus/cli/tasks.rb +9 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +162 -68
- data/lib/morpheus/formatters.rb +34 -9
- metadata +5 -4
- data/lib/morpheus/cli/mixins/catalog_helper.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f4b5a29dcfa1a915ab2d3fed9ad07197d2a760758b2bc3b76e72cf6899c4372
|
4
|
+
data.tar.gz: 59c981a5aede057b69e08f5c717d27c884bdd64aed84fb81361b35291b3aaf72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 678ff7f73923c9883968ee8bba29b8d75d5464a4899ca812477ce943b25f758c74f187a481c781500928206c4d540d5153f858ee4e2242cfb24cc2604be1602d
|
7
|
+
data.tar.gz: c27881081abb71b05eceb4857280f51a4f838e9a568658baa34385afe7fc2b86be61eb31a070a4e3a9381000337ceb9b11f58fe8572fff8066882225133742ba
|
data/Dockerfile
CHANGED
@@ -776,6 +776,10 @@ class Morpheus::APIClient
|
|
776
776
|
Morpheus::CatalogItemTypesInterface.new(common_interface_options).setopts(@options)
|
777
777
|
end
|
778
778
|
|
779
|
+
def catalog
|
780
|
+
Morpheus::ServiceCatalogInterface.new(common_interface_options).setopts(@options)
|
781
|
+
end
|
782
|
+
|
779
783
|
def usage
|
780
784
|
Morpheus::UsageInterface.new(common_interface_options).setopts(@options)
|
781
785
|
end
|
@@ -169,10 +169,10 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
|
|
169
169
|
execute(opts)
|
170
170
|
end
|
171
171
|
|
172
|
-
def backup(id,
|
172
|
+
def backup(id, payload={})
|
173
173
|
url = "#{@base_url}/api/instances/#{id}/backup"
|
174
174
|
headers = {:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
175
|
-
opts = {method: :put, url: url, headers: headers}
|
175
|
+
opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
|
176
176
|
execute(opts)
|
177
177
|
end
|
178
178
|
|
@@ -218,6 +218,13 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
|
|
218
218
|
execute(opts)
|
219
219
|
end
|
220
220
|
|
221
|
+
def snapshot(id, payload={})
|
222
|
+
url = "#{@base_url}/api/instances/#{id}/snapshot"
|
223
|
+
headers = {:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
224
|
+
opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
|
225
|
+
execute(opts)
|
226
|
+
end
|
227
|
+
|
221
228
|
def snapshots(instance_id, params={})
|
222
229
|
url = "#{@base_url}/api/instances/#{instance_id}/snapshots"
|
223
230
|
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
@@ -176,4 +176,11 @@ class Morpheus::ServersInterface < Morpheus::APIClient
|
|
176
176
|
execute(opts)
|
177
177
|
end
|
178
178
|
|
179
|
+
def software(id, params={})
|
180
|
+
url = "#{@base_url}/api/servers/#{id}/software"
|
181
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
182
|
+
opts = {method: :get, url: url, headers: headers}
|
183
|
+
execute(opts)
|
184
|
+
end
|
185
|
+
|
179
186
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
# Service Catalog Persona interface
|
3
|
+
class Morpheus::ServiceCatalogInterface < Morpheus::APIClient
|
4
|
+
|
5
|
+
def base_path
|
6
|
+
# "/api/service-catalog"
|
7
|
+
"/api/catalog"
|
8
|
+
end
|
9
|
+
|
10
|
+
# dashboard
|
11
|
+
def dashboard(params={})
|
12
|
+
execute(method: :get, url: "#{base_path}/dashboard", params: params)
|
13
|
+
end
|
14
|
+
|
15
|
+
# list catalog types available for ordering
|
16
|
+
def list_types(params={})
|
17
|
+
execute(method: :get, url: "#{base_path}/types", params: params)
|
18
|
+
end
|
19
|
+
|
20
|
+
# get specific catalog type
|
21
|
+
def get_type(id, params={})
|
22
|
+
validate_id!(id)
|
23
|
+
execute(method: :get, url: "#{base_path}/types/#{id}", params: params)
|
24
|
+
end
|
25
|
+
|
26
|
+
# list catalog inventory (items)
|
27
|
+
def list_inventory(params={})
|
28
|
+
execute(method: :get, url: "#{base_path}/items", params: params)
|
29
|
+
end
|
30
|
+
|
31
|
+
# get catalog inventory item
|
32
|
+
def get_inventory(id, params={})
|
33
|
+
validate_id!(id)
|
34
|
+
execute(method: :get, url: "#{base_path}/items/#{id}", params: params)
|
35
|
+
end
|
36
|
+
|
37
|
+
# delete a catalog inventory item
|
38
|
+
def destroy_inventory(id, params = {})
|
39
|
+
validate_id!(id)
|
40
|
+
execute(method: :delete, url: "#{base_path}/items/#{id}", params: params)
|
41
|
+
end
|
42
|
+
|
43
|
+
# get cart (one per user)
|
44
|
+
def get_cart(params={})
|
45
|
+
execute(method: :get, url: "#{base_path}/cart", params: params)
|
46
|
+
end
|
47
|
+
|
48
|
+
# update cart (set cart name)
|
49
|
+
def update_cart(payload, params={})
|
50
|
+
execute(method: :put, url: "#{base_path}/cart", params: params, payload: payload.to_json)
|
51
|
+
end
|
52
|
+
|
53
|
+
# validate a new item, can be used before before adding it
|
54
|
+
def validate_cart_item(payload, params={})
|
55
|
+
execute(method: :post, url: "#{base_path}/cart/items/validate", params: params, payload: payload.to_json)
|
56
|
+
end
|
57
|
+
|
58
|
+
# add item to cart
|
59
|
+
def create_cart_item(payload, params={})
|
60
|
+
execute(method: :post, url: "#{base_path}/cart/items", params: params, payload: payload.to_json)
|
61
|
+
end
|
62
|
+
|
63
|
+
# update item in the cart
|
64
|
+
def update_cart_item(id, payload, params={})
|
65
|
+
validate_id!(id)
|
66
|
+
execute(method: :put, url: "#{base_path}/cart/items/#{id}", params: params, payload: payload.to_json)
|
67
|
+
end
|
68
|
+
|
69
|
+
# remove item from the cart
|
70
|
+
def destroy_cart_item(id, params={})
|
71
|
+
validate_id!(id)
|
72
|
+
execute(method: :delete, url: "#{base_path}/cart/items/#{id}", params: params)
|
73
|
+
end
|
74
|
+
|
75
|
+
# place order with cart
|
76
|
+
def checkout(payload, params={})
|
77
|
+
execute(method: :post, url: "#{base_path}/checkout", params: params, payload: payload.to_json)
|
78
|
+
end
|
79
|
+
|
80
|
+
# remove all items from cart and reset name
|
81
|
+
def clear_cart(params={})
|
82
|
+
execute(method: :delete, url: "#{base_path}/cart", params: params)
|
83
|
+
end
|
84
|
+
|
85
|
+
# create an order from scratch, without using a cart
|
86
|
+
def create_order(payload, params={})
|
87
|
+
execute(method: :post, url: "#{base_path}/orders", params: params, payload: payload.to_json)
|
88
|
+
end
|
89
|
+
end
|
data/lib/morpheus/cli.rb
CHANGED
@@ -175,7 +175,8 @@ module Morpheus
|
|
175
175
|
load 'morpheus/cli/projects_command.rb'
|
176
176
|
load 'morpheus/cli/backups_command.rb'
|
177
177
|
load 'morpheus/cli/backup_jobs_command.rb'
|
178
|
-
load 'morpheus/cli/
|
178
|
+
load 'morpheus/cli/catalog_item_types_command.rb' # catalog-types
|
179
|
+
load 'morpheus/cli/service_catalog_command.rb' # catalog
|
179
180
|
load 'morpheus/cli/usage_command.rb'
|
180
181
|
# add new commands here...
|
181
182
|
|
data/lib/morpheus/cli/apps.rb
CHANGED
@@ -72,9 +72,6 @@ class Morpheus::Cli::Apps
|
|
72
72
|
options[:owner] = val
|
73
73
|
end
|
74
74
|
opts.add_hidden_option('--created-by')
|
75
|
-
opts.on('--details', "Display more details: memory and storage usage used / max values." ) do
|
76
|
-
options[:details] = true
|
77
|
-
end
|
78
75
|
opts.on('--pending-removal', "Include apps pending removal.") do
|
79
76
|
options[:showDeleted] = true
|
80
77
|
end
|
@@ -88,6 +85,9 @@ class Morpheus::Cli::Apps
|
|
88
85
|
opts.on('--status STATUS', "Filter by status.") do |val|
|
89
86
|
params['status'] = (params['status'] || []) + val.to_s.split(',').collect {|s| s.strip }.select {|s| s != "" }
|
90
87
|
end
|
88
|
+
opts.on('-a', '--details', "Display all details: memory and storage usage used / max values." ) do
|
89
|
+
options[:details] = true
|
90
|
+
end
|
91
91
|
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
92
92
|
opts.footer = "List apps."
|
93
93
|
end
|
@@ -2185,26 +2185,6 @@ EOT
|
|
2185
2185
|
print reset
|
2186
2186
|
end
|
2187
2187
|
|
2188
|
-
def format_app_status(app, return_color=cyan)
|
2189
|
-
out = ""
|
2190
|
-
status_string = app['status'] || app['appStatus'] || ''
|
2191
|
-
if status_string == 'running'
|
2192
|
-
out = "#{green}#{status_string.upcase}#{return_color}"
|
2193
|
-
elsif status_string == 'provisioning'
|
2194
|
-
out = "#{cyan}#{status_string.upcase}#{cyan}"
|
2195
|
-
elsif status_string == 'stopped' or status_string == 'failed'
|
2196
|
-
out = "#{red}#{status_string.upcase}#{return_color}"
|
2197
|
-
elsif status_string == 'unknown'
|
2198
|
-
out = "#{yellow}#{status_string.upcase}#{return_color}"
|
2199
|
-
elsif status_string == 'warning' && app['instanceCount'].to_i == 0
|
2200
|
-
# show this instead of WARNING
|
2201
|
-
out = "#{cyan}EMPTY#{return_color}"
|
2202
|
-
else
|
2203
|
-
out = "#{yellow}#{status_string.upcase}#{return_color}"
|
2204
|
-
end
|
2205
|
-
out
|
2206
|
-
end
|
2207
|
-
|
2208
2188
|
def format_app_tiers(app)
|
2209
2189
|
out = ""
|
2210
2190
|
begin
|
@@ -1,17 +1,16 @@
|
|
1
1
|
require 'morpheus/cli/cli_command'
|
2
2
|
|
3
3
|
# CLI command self service
|
4
|
-
# UI is Tools: Self Service - Catalog
|
4
|
+
# UI is Tools: Self Service - Catalog
|
5
5
|
# API is /catalog-item-types and returns catalogItemTypes
|
6
|
-
class Morpheus::Cli::
|
6
|
+
class Morpheus::Cli::CatalogItemTypesCommand
|
7
7
|
include Morpheus::Cli::CliCommand
|
8
|
-
include Morpheus::Cli::CatalogHelper
|
9
8
|
include Morpheus::Cli::LibraryHelper
|
10
9
|
include Morpheus::Cli::OptionSourceHelper
|
11
10
|
|
12
|
-
#
|
13
|
-
|
14
|
-
|
11
|
+
# set_command_name :'catalog-types'
|
12
|
+
set_command_name :'self-service'
|
13
|
+
set_command_description "Self Service: View and manage catalog item types"
|
15
14
|
|
16
15
|
register_subcommands :list, :get, :add, :update, :remove
|
17
16
|
|
@@ -38,7 +37,7 @@ class Morpheus::Cli::CatalogCommand
|
|
38
37
|
params['featured'] = (val.to_s != 'false' && val.to_s != 'off')
|
39
38
|
end
|
40
39
|
build_standard_list_options(opts, options)
|
41
|
-
opts.footer = "List catalog
|
40
|
+
opts.footer = "List catalog item types."
|
42
41
|
end
|
43
42
|
optparse.parse!(args)
|
44
43
|
connect(options)
|
@@ -55,11 +54,14 @@ class Morpheus::Cli::CatalogCommand
|
|
55
54
|
json_response = @catalog_item_types_interface.list(params)
|
56
55
|
catalog_item_types = json_response[catalog_item_type_list_key]
|
57
56
|
render_response(json_response, options, catalog_item_type_list_key) do
|
58
|
-
print_h1 "Morpheus Catalog
|
57
|
+
print_h1 "Morpheus Catalog Item Types", parse_list_subtitles(options), options
|
59
58
|
if catalog_item_types.empty?
|
60
|
-
print cyan,"No catalog
|
59
|
+
print cyan,"No catalog item types found.",reset,"\n"
|
61
60
|
else
|
62
61
|
list_columns = catalog_item_type_column_definitions.upcase_keys!
|
62
|
+
list_columns.delete("Blueprint")
|
63
|
+
list_columns.delete("Workflow")
|
64
|
+
list_columns.delete("Context")
|
63
65
|
#list_columns["Config"] = lambda {|it| truncate_string(it['config'], 100) }
|
64
66
|
print as_pretty_table(catalog_item_types, list_columns.upcase_keys!, options)
|
65
67
|
print_results_pagination(json_response)
|
@@ -67,7 +69,7 @@ class Morpheus::Cli::CatalogCommand
|
|
67
69
|
print reset,"\n"
|
68
70
|
end
|
69
71
|
if catalog_item_types.empty?
|
70
|
-
return 1, "no catalog
|
72
|
+
return 1, "no catalog item types found"
|
71
73
|
else
|
72
74
|
return 0, nil
|
73
75
|
end
|
@@ -77,17 +79,20 @@ class Morpheus::Cli::CatalogCommand
|
|
77
79
|
params = {}
|
78
80
|
options = {}
|
79
81
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
80
|
-
opts.banner = subcommand_usage("[
|
82
|
+
opts.banner = subcommand_usage("[type]")
|
81
83
|
opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
|
82
84
|
options[:show_config] = true
|
83
85
|
end
|
84
|
-
# opts.on('--no-config', "Do not display
|
86
|
+
# opts.on('--no-config', "Do not display Config YAML." ) do
|
85
87
|
# options[:no_config] = true
|
86
88
|
# end
|
89
|
+
opts.on('--no-content', "Do not display Content." ) do
|
90
|
+
options[:no_content] = true
|
91
|
+
end
|
87
92
|
build_standard_get_options(opts, options)
|
88
93
|
opts.footer = <<-EOT
|
89
94
|
Get details about a specific catalog item type.
|
90
|
-
[
|
95
|
+
[type] is required. This is the name or id of a catalog item type.
|
91
96
|
EOT
|
92
97
|
end
|
93
98
|
optparse.parse!(args)
|
@@ -131,6 +136,8 @@ EOT
|
|
131
136
|
print cyan
|
132
137
|
show_columns = catalog_item_type_column_definitions
|
133
138
|
show_columns.delete("Blueprint") unless catalog_item_type['blueprint']
|
139
|
+
show_columns.delete("Workflow") unless catalog_item_type['workflow']
|
140
|
+
show_columns.delete("Context") unless catalog_item_type['context'] # workflow context
|
134
141
|
print_description_list(show_columns, catalog_item_type)
|
135
142
|
|
136
143
|
if catalog_item_type['optionTypes'] && catalog_item_type['optionTypes'].size > 0
|
@@ -149,25 +156,62 @@ EOT
|
|
149
156
|
# print cyan,"No option types found for this catalog item.","\n",reset
|
150
157
|
end
|
151
158
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
159
|
+
item_type_code = catalog_item_type['type'].to_s.downcase
|
160
|
+
if options[:no_config] != true
|
161
|
+
if item_type_code == 'instance'
|
162
|
+
print_h2 "Config YAML"
|
163
|
+
if config
|
164
|
+
#print reset,(JSON.pretty_generate(config) rescue config),"\n",reset
|
165
|
+
#print reset,(as_yaml(config, options) rescue config),"\n",reset
|
166
|
+
config_string = as_yaml(config, options) rescue config
|
167
|
+
config_lines = config_string.split("\n")
|
168
|
+
config_line_count = config_lines.size
|
169
|
+
max_lines = 10
|
170
|
+
if config_lines.size > max_lines
|
171
|
+
config_string = config_lines.first(max_lines).join("\n")
|
172
|
+
config_string << "\n\n"
|
173
|
+
config_string << "#{dark}(#{(config_line_count - max_lines)} more lines were not shown, use -c to show the config)#{reset}"
|
174
|
+
#config_string << "\n"
|
175
|
+
end
|
176
|
+
# strip --- yaml header
|
177
|
+
if config_string[0..3] == "---\n"
|
178
|
+
config_string = config_string[4..-1]
|
179
|
+
end
|
180
|
+
print reset,config_string.chomp("\n"),"\n",reset
|
181
|
+
else
|
182
|
+
print reset,"(blank)","\n",reset
|
183
|
+
end
|
184
|
+
elsif item_type_code == 'blueprint' || item_type_code == 'apptemplate' || item_type_code == 'app'
|
185
|
+
print_h2 "App Spec"
|
186
|
+
if catalog_item_type['appSpec']
|
187
|
+
#print reset,(JSON.pretty_generate(config) rescue config),"\n",reset
|
188
|
+
#print reset,(as_yaml(config, options) rescue config),"\n",reset
|
189
|
+
config_string = catalog_item_type['appSpec'] || ""
|
190
|
+
config_lines = config_string.split("\n")
|
191
|
+
config_line_count = config_lines.size
|
192
|
+
max_lines = 10
|
193
|
+
if config_lines.size > max_lines
|
194
|
+
config_string = config_lines.first(max_lines).join("\n")
|
195
|
+
config_string << "\n\n"
|
196
|
+
config_string << "#{dark}(#{(config_line_count - max_lines)} more lines were not shown, use -c to show the config)#{reset}"
|
197
|
+
#config_string << "\n"
|
198
|
+
end
|
199
|
+
# strip --- yaml header
|
200
|
+
if config_string[0..3] == "---\n"
|
201
|
+
config_string = config_string[4..-1]
|
202
|
+
end
|
203
|
+
print reset,config_string.chomp("\n"),"\n",reset
|
204
|
+
else
|
205
|
+
print reset,"(blank)","\n",reset
|
206
|
+
end
|
207
|
+
elsif item_type_code == 'workflow' || item_type_code == 'operationalworkflow' || item_type_code == 'taskset'
|
169
208
|
end
|
170
|
-
|
209
|
+
end
|
210
|
+
|
211
|
+
# Content (Wiki Page)
|
212
|
+
if !catalog_item_type["content"].to_s.empty? && options[:no_content] != true
|
213
|
+
print_h2 "Content"
|
214
|
+
print reset,catalog_item_type["content"].chomp("\n"),"\n",reset
|
171
215
|
end
|
172
216
|
|
173
217
|
print reset,"\n"
|
@@ -180,6 +224,10 @@ EOT
|
|
180
224
|
params = {}
|
181
225
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
182
226
|
opts.banner = subcommand_usage("[name] [options]")
|
227
|
+
# opts.on('-t', '--type [instance|blueprint|workflow]', "Item Type, default is instance.") do |val|
|
228
|
+
# # params['type'] = val.to_s.downcase
|
229
|
+
# options[:options]['type'] = val.to_s.downcase
|
230
|
+
# end
|
183
231
|
build_option_type_options(opts, options, add_catalog_item_type_option_types)
|
184
232
|
opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
|
185
233
|
options[:config_file] = val.to_s
|
@@ -233,6 +281,8 @@ EOT
|
|
233
281
|
payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
|
234
282
|
else
|
235
283
|
payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
|
284
|
+
# Type prompt first
|
285
|
+
#params['type'] = Morpheus::Cli::OptionTypes.no_prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}, {'name' => 'Workflow', 'value' => 'workflow'}], 'defaultValue' => 'instance', 'required' => true}], options[:options], @api_client, options[:params])['type']
|
236
286
|
v_prompt = Morpheus::Cli::OptionTypes.prompt(add_catalog_item_type_option_types(), options[:options], @api_client, options[:params])
|
237
287
|
params.deep_merge!(v_prompt)
|
238
288
|
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_catalog_item_type_advanced_option_types, options[:options], @api_client, options[:params])
|
@@ -241,13 +291,15 @@ EOT
|
|
241
291
|
# convert checkbox "on" and "off" to true and false
|
242
292
|
params.booleanize!
|
243
293
|
# convert type to refType until api accepts type
|
244
|
-
if params['type'] && !params['refType']
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
294
|
+
# if params['type'] && !params['refType']
|
295
|
+
# if params['type'].to_s.downcase == 'instance'
|
296
|
+
# params['refType'] = 'InstanceType'
|
297
|
+
# elsif params['type'].to_s.downcase == 'blueprint'
|
298
|
+
# params['refType'] = 'AppTemplate'
|
299
|
+
# elsif params['type'].to_s.downcase == 'workflow'
|
300
|
+
# params['refType'] = 'OperationalWorkflow'
|
301
|
+
# end
|
302
|
+
# end
|
251
303
|
# convert config string to a map
|
252
304
|
config = params['config']
|
253
305
|
if config && config.is_a?(String)
|
@@ -261,14 +313,14 @@ EOT
|
|
261
313
|
params['config'] = config_map
|
262
314
|
end
|
263
315
|
end
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
316
|
+
# massage association params a bit
|
317
|
+
params['workflow'] = {'id' => params['workflow']} if params['workflow'] && !params['workflow'].is_a?(Hash)
|
318
|
+
params['blueprint'] = {'id' => params['blueprint']} if params['blueprint'] && !params['blueprint'].is_a?(Hash)
|
319
|
+
prompt_results = prompt_for_option_types(params, options, @api_client)
|
320
|
+
if prompt_results[:success]
|
321
|
+
params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
|
322
|
+
else
|
323
|
+
return 1, "failed to parse optionTypes"
|
272
324
|
end
|
273
325
|
payload[catalog_item_type_object_key].deep_merge!(params)
|
274
326
|
end
|
@@ -280,7 +332,7 @@ EOT
|
|
280
332
|
json_response = @catalog_item_types_interface.create(payload)
|
281
333
|
catalog_item_type = json_response[catalog_item_type_object_key]
|
282
334
|
render_response(json_response, options, catalog_item_type_object_key) do
|
283
|
-
print_green_success "Added catalog item #{catalog_item_type['name']}"
|
335
|
+
print_green_success "Added catalog item type #{catalog_item_type['name']}"
|
284
336
|
return _get(catalog_item_type["id"], {}, options)
|
285
337
|
end
|
286
338
|
return 0, nil
|
@@ -291,7 +343,7 @@ EOT
|
|
291
343
|
params = {}
|
292
344
|
payload = {}
|
293
345
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
294
|
-
opts.banner = subcommand_usage("[
|
346
|
+
opts.banner = subcommand_usage("[type] [options]")
|
295
347
|
build_option_type_options(opts, options, update_catalog_item_type_option_types)
|
296
348
|
opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
|
297
349
|
options[:config_file] = val.to_s
|
@@ -333,7 +385,7 @@ EOT
|
|
333
385
|
build_standard_update_options(opts, options)
|
334
386
|
opts.footer = <<-EOT
|
335
387
|
Update a catalog item type.
|
336
|
-
[
|
388
|
+
[type] is required. This is the name or id of a catalog item type.
|
337
389
|
EOT
|
338
390
|
end
|
339
391
|
optparse.parse!(args)
|
@@ -356,14 +408,7 @@ EOT
|
|
356
408
|
params.deep_merge!(advanced_config)
|
357
409
|
# convert checkbox "on" and "off" to true and false
|
358
410
|
params.booleanize!
|
359
|
-
|
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
|
411
|
+
|
367
412
|
# convert config string to a map
|
368
413
|
config = params['config']
|
369
414
|
if config && config.is_a?(String)
|
@@ -377,6 +422,18 @@ EOT
|
|
377
422
|
params['config'] = config_map
|
378
423
|
end
|
379
424
|
end
|
425
|
+
if params['optionTypes']
|
426
|
+
# todo: move to optionSource, so it will be /api/options/optionTypes lol
|
427
|
+
prompt_results = prompt_for_option_types(params, options, @api_client)
|
428
|
+
if prompt_results[:success]
|
429
|
+
params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
|
430
|
+
else
|
431
|
+
return 1, "failed to parse optionTypes"
|
432
|
+
end
|
433
|
+
end
|
434
|
+
# massage association params a bit
|
435
|
+
params['workflow'] = {'id' => params['workflow']} if params['workflow'] && !params['workflow'].is_a?(Hash)
|
436
|
+
params['blueprint'] = {'id' => params['blueprint']} if params['blueprint'] && !params['blueprint'].is_a?(Hash)
|
380
437
|
payload.deep_merge!({catalog_item_type_object_key => params})
|
381
438
|
if payload[catalog_item_type_object_key].empty? # || options[:no_prompt]
|
382
439
|
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
@@ -390,7 +447,7 @@ EOT
|
|
390
447
|
json_response = @catalog_item_types_interface.update(catalog_item_type['id'], payload)
|
391
448
|
catalog_item_type = json_response[catalog_item_type_object_key]
|
392
449
|
render_response(json_response, options, catalog_item_type_object_key) do
|
393
|
-
print_green_success "Updated catalog item #{catalog_item_type['name']}"
|
450
|
+
print_green_success "Updated catalog item type #{catalog_item_type['name']}"
|
394
451
|
return _get(catalog_item_type["id"], {}, options)
|
395
452
|
end
|
396
453
|
return 0, nil
|
@@ -400,11 +457,11 @@ EOT
|
|
400
457
|
options = {}
|
401
458
|
params = {}
|
402
459
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
403
|
-
opts.banner = subcommand_usage("[
|
460
|
+
opts.banner = subcommand_usage("[type] [options]")
|
404
461
|
build_standard_remove_options(opts, options)
|
405
462
|
opts.footer = <<-EOT
|
406
|
-
Delete a
|
407
|
-
[
|
463
|
+
Delete a catalog item type.
|
464
|
+
[type] is required. This is the name or id of a catalog item type.
|
408
465
|
EOT
|
409
466
|
end
|
410
467
|
optparse.parse!(args)
|
@@ -417,12 +474,12 @@ EOT
|
|
417
474
|
print_dry_run @catalog_item_types_interface.dry.destroy(catalog_item_type['id'], params)
|
418
475
|
return
|
419
476
|
end
|
420
|
-
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the catalog item #{catalog_item_type['name']}?")
|
477
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the catalog item type #{catalog_item_type['name']}?")
|
421
478
|
return 9, "aborted command"
|
422
479
|
end
|
423
480
|
json_response = @catalog_item_types_interface.destroy(catalog_item_type['id'], params)
|
424
481
|
render_response(json_response, options) do
|
425
|
-
print_green_success "Removed catalog item #{catalog_item_type['name']}"
|
482
|
+
print_green_success "Removed catalog item type #{catalog_item_type['name']}"
|
426
483
|
end
|
427
484
|
return 0, nil
|
428
485
|
end
|
@@ -436,6 +493,9 @@ EOT
|
|
436
493
|
"Description" => 'description',
|
437
494
|
"Type" => lambda {|it| format_catalog_type(it) },
|
438
495
|
"Blueprint" => lambda {|it| it['blueprint'] ? it['blueprint']['name'] : nil },
|
496
|
+
"Workflow" => lambda {|it| it['workflow'] ? it['workflow']['name'] : nil },
|
497
|
+
"Context" => lambda {|it| it['context'] },
|
498
|
+
# "Content" => lambda {|it| it['content'] },
|
439
499
|
"Enabled" => lambda {|it| format_boolean(it['enabled']) },
|
440
500
|
"Featured" => lambda {|it| format_boolean(it['featured']) },
|
441
501
|
#"Config" => lambda {|it| it['config'] },
|
@@ -455,6 +515,7 @@ EOT
|
|
455
515
|
out << (catalog_item_type['type']['name'] || catalog_item_type['type']['code']) rescue catalog_item_type['type'].to_s
|
456
516
|
end
|
457
517
|
else
|
518
|
+
# refType is not returned
|
458
519
|
ref_type = catalog_item_type['refType']
|
459
520
|
if ref_type == 'InstanceType'
|
460
521
|
out << "Instance"
|
@@ -469,18 +530,24 @@ EOT
|
|
469
530
|
out
|
470
531
|
end
|
471
532
|
|
472
|
-
# this is not so simple, need to first choose select instance, host or provider
|
473
533
|
def add_catalog_item_type_option_types
|
474
534
|
[
|
535
|
+
{'code' => 'catalogItemType.type', 'shorthand' => '-t', 'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}, {'name' => 'Workflow', 'value' => 'workflow'}], 'defaultValue' => 'instance', 'required' => true},
|
475
536
|
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
|
476
537
|
{'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
538
|
{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'defaultValue' => true},
|
479
539
|
{'fieldName' => 'featured', 'fieldLabel' => 'Featured', 'type' => 'checkbox', 'defaultValue' => false},
|
480
540
|
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'required' => true},
|
481
541
|
{'fieldName' => 'iconPath', 'fieldLabel' => 'Logo', 'type' => 'select', 'optionSource' => 'iconList'},
|
482
542
|
#{'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', '
|
543
|
+
{'dependsOnCode' => 'catalogItemType.type:instance', 'fieldName' => 'config', 'fieldLabel' => 'Config', 'type' => 'code-editor', 'description' => 'JSON or YAML', 'required' => true},
|
544
|
+
{'dependsOnCode' => 'catalogItemType.type:blueprint', 'fieldName' => 'blueprint', 'fieldLabel' => 'Blueprint', 'type' => 'select', 'optionSource' => 'blueprints', 'description' => 'Choose a blueprint to apply to the catalog item.', 'required' => true, 'noParams' => true},
|
545
|
+
{'dependsOnCode' => 'catalogItemType.type:blueprint', 'fieldName' => 'appSpec', 'fieldLabel' => 'App Spec', 'type' => 'code-editor', 'description' => 'Enter a spec in the for the App, the Scribe YAML format', 'required' => true},
|
546
|
+
{'dependsOnCode' => 'catalogItemType.type:workflow', 'fieldName' => 'workflow', 'fieldLabel' => 'Workflow', 'type' => 'select', 'optionSource' => 'operationWorkflows', 'description' => 'Enter a spec in the for the App, the Scribe YAML format', 'noParams' => true},
|
547
|
+
{'dependsOnCode' => 'catalogItemType.type:workflow', 'fieldName' => 'context', 'fieldLabel' => 'Context Type', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
|
548
|
+
[{'name' => "Select", 'value' => ""}, {'name' => "None", 'value' => "appliance"}, {'name' => "Instance", 'value' => "instance"}, {'name' => "Server", 'value' => "server"}]
|
549
|
+
}, 'description' => 'Context for operational workflow, determines target type', 'defaultValue' => 'Select', 'required' => false},
|
550
|
+
{'fieldName' => 'content', 'fieldLabel' => 'Content', 'type' => 'code-editor', 'description' => 'Wiki Page Content describing the catalog item'}
|
484
551
|
]
|
485
552
|
end
|
486
553
|
|
@@ -489,11 +556,13 @@ EOT
|
|
489
556
|
end
|
490
557
|
|
491
558
|
def update_catalog_item_type_option_types
|
492
|
-
add_catalog_item_type_option_types.collect {|it|
|
559
|
+
list = add_catalog_item_type_option_types.collect {|it|
|
493
560
|
it.delete('required')
|
494
561
|
it.delete('defaultValue')
|
495
562
|
it
|
496
563
|
}
|
564
|
+
list = list.reject {|it| ["type"].include? it['fieldName'] }
|
565
|
+
list
|
497
566
|
end
|
498
567
|
|
499
568
|
def update_catalog_item_type_advanced_option_types
|
@@ -504,4 +573,50 @@ EOT
|
|
504
573
|
}
|
505
574
|
end
|
506
575
|
|
576
|
+
def catalog_item_type_object_key
|
577
|
+
'catalogItemType'
|
578
|
+
end
|
579
|
+
|
580
|
+
def catalog_item_type_list_key
|
581
|
+
'catalogItemTypes'
|
582
|
+
end
|
583
|
+
|
584
|
+
def find_catalog_item_type_by_name_or_id(val)
|
585
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
586
|
+
return find_catalog_item_type_by_id(val)
|
587
|
+
else
|
588
|
+
return find_catalog_item_type_by_name(val)
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
def find_catalog_item_type_by_id(id)
|
593
|
+
begin
|
594
|
+
json_response = @catalog_item_types_interface.get(id.to_i)
|
595
|
+
return json_response[catalog_item_type_object_key]
|
596
|
+
rescue RestClient::Exception => e
|
597
|
+
if e.response && e.response.code == 404
|
598
|
+
print_red_alert "catalog item type not found by id '#{id}'"
|
599
|
+
else
|
600
|
+
raise e
|
601
|
+
end
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
def find_catalog_item_type_by_name(name)
|
606
|
+
json_response = @catalog_item_types_interface.list({name: name.to_s})
|
607
|
+
catalog_item_types = json_response[catalog_item_type_list_key]
|
608
|
+
if catalog_item_types.empty?
|
609
|
+
print_red_alert "catalog item type not found by name '#{name}'"
|
610
|
+
return nil
|
611
|
+
elsif catalog_item_types.size > 1
|
612
|
+
print_red_alert "#{catalog_item_types.size} catalog item types found by name '#{name}'"
|
613
|
+
puts_error as_pretty_table(catalog_item_types, [:id, :name], {color:red})
|
614
|
+
print_red_alert "Try using ID instead"
|
615
|
+
print reset,"\n"
|
616
|
+
return nil
|
617
|
+
else
|
618
|
+
return catalog_item_types[0]
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
507
622
|
end
|