morpheus-cli 4.2.8 → 4.2.10
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.rb +1 -1
- data/lib/morpheus/api/activity_interface.rb +9 -0
- data/lib/morpheus/api/api_client.rb +83 -27
- data/lib/morpheus/api/apps_interface.rb +21 -0
- data/lib/morpheus/api/dashboard_interface.rb +5 -21
- data/lib/morpheus/api/instances_interface.rb +3 -10
- data/lib/morpheus/api/invoice_line_items_interface.rb +14 -0
- data/lib/morpheus/api/invoices_interface.rb +7 -12
- data/lib/morpheus/api/library_layouts_interface.rb +8 -0
- data/lib/morpheus/api/ping_interface.rb +20 -0
- data/lib/morpheus/api/projects_interface.rb +33 -0
- data/lib/morpheus/api/setup_interface.rb +19 -36
- data/lib/morpheus/api/user_settings_interface.rb +0 -6
- data/lib/morpheus/api/whoami_interface.rb +4 -8
- data/lib/morpheus/benchmarking.rb +16 -26
- data/lib/morpheus/cli.rb +10 -5
- data/lib/morpheus/cli/access_token_command.rb +5 -8
- data/lib/morpheus/cli/activity_command.rb +146 -0
- data/lib/morpheus/cli/apps.rb +312 -121
- data/lib/morpheus/cli/archives_command.rb +1 -1
- data/lib/morpheus/cli/auth_command.rb +4 -11
- data/lib/morpheus/cli/blueprints_command.rb +196 -137
- data/lib/morpheus/cli/change_password_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +225 -72
- data/lib/morpheus/cli/cli_registry.rb +2 -2
- data/lib/morpheus/cli/cloud_datastores_command.rb +1 -1
- data/lib/morpheus/cli/clouds.rb +5 -20
- data/lib/morpheus/cli/clusters.rb +4 -28
- data/lib/morpheus/cli/commands/standard/alias_command.rb +2 -9
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +2 -0
- data/lib/morpheus/cli/commands/standard/curl_command.rb +2 -3
- data/lib/morpheus/cli/commands/standard/history_command.rb +3 -6
- data/lib/morpheus/cli/commands/standard/man_command.rb +10 -7
- data/lib/morpheus/cli/commands/standard/ssl_verification_command.rb +10 -9
- data/lib/morpheus/cli/containers_command.rb +3 -3
- data/lib/morpheus/cli/credentials.rb +13 -16
- data/lib/morpheus/cli/error_handler.rb +18 -12
- data/lib/morpheus/cli/errors.rb +45 -0
- data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
- data/lib/morpheus/cli/execution_request_command.rb +4 -4
- data/lib/morpheus/cli/groups.rb +84 -132
- data/lib/morpheus/cli/hosts.rb +6 -16
- data/lib/morpheus/cli/instances.rb +100 -183
- data/lib/morpheus/cli/invoices_command.rb +505 -71
- data/lib/morpheus/cli/library_layouts_command.rb +254 -166
- data/lib/morpheus/cli/library_option_lists_command.rb +0 -87
- data/lib/morpheus/cli/library_option_types_command.rb +0 -96
- data/lib/morpheus/cli/license.rb +3 -0
- data/lib/morpheus/cli/login.rb +17 -37
- data/lib/morpheus/cli/logout.rb +9 -5
- data/lib/morpheus/cli/mixins/accounts_helper.rb +83 -7
- data/lib/morpheus/cli/mixins/operations_helper.rb +41 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +255 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +18 -4
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +222 -13
- data/lib/morpheus/cli/mixins/remote_helper.rb +139 -0
- data/lib/morpheus/cli/monitoring_checks_command.rb +11 -3
- data/lib/morpheus/cli/network_groups_command.rb +8 -2
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/ping.rb +252 -0
- data/lib/morpheus/cli/price_sets_command.rb +16 -27
- data/lib/morpheus/cli/prices_command.rb +34 -27
- data/lib/morpheus/cli/processes_command.rb +81 -7
- data/lib/morpheus/cli/projects_command.rb +607 -0
- data/lib/morpheus/cli/recent_activity_command.rb +87 -65
- data/lib/morpheus/cli/remote.rb +965 -974
- data/lib/morpheus/cli/reports_command.rb +3 -15
- data/lib/morpheus/cli/roles.rb +8 -31
- data/lib/morpheus/cli/service_plans_command.rb +25 -31
- data/lib/morpheus/cli/setup.rb +392 -0
- data/lib/morpheus/cli/shell.rb +144 -56
- data/lib/morpheus/cli/subnets_command.rb +71 -11
- data/lib/morpheus/cli/tasks.rb +3 -3
- data/lib/morpheus/cli/user_sources_command.rb +4 -4
- data/lib/morpheus/cli/users.rb +135 -109
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +7 -7
- data/lib/morpheus/cli/whoami.rb +90 -129
- data/lib/morpheus/cli/wiki_command.rb +2 -14
- data/lib/morpheus/ext/rest_client.rb +36 -0
- data/lib/morpheus/formatters.rb +42 -5
- data/lib/morpheus/rest_client.rb +0 -10
- data/lib/morpheus/terminal.rb +41 -1
- data/lib/morpheus/util.rb +24 -0
- metadata +16 -3
- data/lib/morpheus/cli/command_error.rb +0 -22
|
@@ -6,11 +6,14 @@ require 'morpheus/cli/mixins/library_helper'
|
|
|
6
6
|
|
|
7
7
|
class Morpheus::Cli::LibraryLayoutsCommand
|
|
8
8
|
include Morpheus::Cli::CliCommand
|
|
9
|
+
include Morpheus::Cli::ProvisioningHelper
|
|
10
|
+
# make sure LibraryHelper is loaded after ProvisioningHelper because it overwrites some methods like find_instance_type_by_name
|
|
11
|
+
# ProvisioningHelper is needed just for permissions (resourcePermissions)
|
|
9
12
|
include Morpheus::Cli::LibraryHelper
|
|
10
13
|
|
|
11
14
|
set_command_name :'library-layouts'
|
|
12
15
|
|
|
13
|
-
register_subcommands :list, :get, :add, :update, :remove
|
|
16
|
+
register_subcommands :list, :get, :add, :update, :remove, :update_permissions
|
|
14
17
|
|
|
15
18
|
def initialize()
|
|
16
19
|
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
@@ -108,14 +111,18 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
108
111
|
def get(args)
|
|
109
112
|
options = {}
|
|
110
113
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
111
|
-
opts.banner = subcommand_usage("[
|
|
112
|
-
|
|
114
|
+
opts.banner = subcommand_usage("[layout]")
|
|
115
|
+
# opts.on( nil, '--permissions', "Display permissions" ) do
|
|
116
|
+
# options[:show_perms] = true
|
|
117
|
+
# end
|
|
118
|
+
build_standard_get_options(opts, options)
|
|
119
|
+
opts.footer = <<-EOT
|
|
120
|
+
Get details about a layout.
|
|
121
|
+
[layout] is required. This is the name or id of a layout.
|
|
122
|
+
EOT
|
|
113
123
|
end
|
|
124
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
|
114
125
|
optparse.parse!(args)
|
|
115
|
-
if args.count < 1
|
|
116
|
-
puts optparse
|
|
117
|
-
return 1
|
|
118
|
-
end
|
|
119
126
|
connect(options)
|
|
120
127
|
id_list = parse_id_list(args)
|
|
121
128
|
return run_command_for_each_arg(id_list) do |arg|
|
|
@@ -124,149 +131,153 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
124
131
|
end
|
|
125
132
|
|
|
126
133
|
def _get(id, options)
|
|
134
|
+
exit_code, err = 0, nil
|
|
127
135
|
instance_type_id = nil
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
params = {}
|
|
137
|
+
params.merge!(parse_query_options(options))
|
|
138
|
+
@library_layouts_interface.setopts(options)
|
|
139
|
+
if options[:dry_run]
|
|
140
|
+
if id.to_s =~ /\A\d{1,}\Z/
|
|
141
|
+
print_dry_run @library_layouts_interface.dry.get(instance_type_id, id.to_i, params)
|
|
142
|
+
else
|
|
143
|
+
print_dry_run @library_layouts_interface.dry.list(instance_type_id, params.merge({name:id}))
|
|
144
|
+
end
|
|
145
|
+
return
|
|
146
|
+
end
|
|
147
|
+
layout = find_layout_by_name_or_id(instance_type_id, id)
|
|
148
|
+
if layout.nil?
|
|
149
|
+
return 1
|
|
150
|
+
end
|
|
151
|
+
# skip redundant request
|
|
152
|
+
#json_response = @library_layouts_interface.get(instance_type_id, layout['id'])
|
|
153
|
+
json_response = {'instanceTypeLayout' => layout}
|
|
154
|
+
#layout = json_response['instanceTypeLayout']
|
|
155
|
+
if options[:json]
|
|
156
|
+
puts as_json(json_response, options, "instanceTypeLayout")
|
|
157
|
+
return 0
|
|
158
|
+
elsif options[:yaml]
|
|
159
|
+
puts as_yaml(json_response, options, "instanceTypeLayout")
|
|
160
|
+
return 0
|
|
161
|
+
elsif options[:csv]
|
|
162
|
+
puts records_as_csv([json_response['instanceTypeLayout']], options)
|
|
163
|
+
return 0
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
print_h1 "Layout Details"
|
|
167
|
+
print cyan
|
|
168
|
+
description_cols = {
|
|
169
|
+
"ID" => lambda {|it| it['id'] },
|
|
170
|
+
"Name" => lambda {|it| it['name'] },
|
|
171
|
+
"Instance Type" => lambda {|it| it['instanceType']['name'] rescue '' },
|
|
172
|
+
#"Code" => lambda {|it| it['code'] },
|
|
173
|
+
"Version" => lambda {|it| it['instanceVersion'] },
|
|
174
|
+
"Description" => lambda {|it| it['description'] },
|
|
175
|
+
"Technology" => lambda {|it| format_layout_technology(it) },
|
|
176
|
+
"Min Memory" => lambda {|it|
|
|
177
|
+
if it['memoryRequirement'].to_i != 0
|
|
178
|
+
(it['memoryRequirement'].to_i / (1024*1024)).to_s + " MB"
|
|
133
179
|
else
|
|
134
|
-
|
|
180
|
+
""
|
|
135
181
|
end
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
182
|
+
},
|
|
183
|
+
"Workflow" => lambda {|it|
|
|
184
|
+
if it['taskSets']
|
|
185
|
+
it['taskSets'][0]['name'] rescue ""
|
|
186
|
+
else
|
|
187
|
+
""
|
|
188
|
+
end
|
|
189
|
+
},
|
|
190
|
+
# "Category" => lambda {|it| it['category'].to_s.capitalize },
|
|
191
|
+
# # "Logo" => lambda {|it| it['logo'].to_s },
|
|
192
|
+
# "Visiblity" => lambda {|it| it['visibility'].to_s.capitalize },
|
|
193
|
+
# "Environment Prefix" => lambda {|it| it['environmentPrefix'] },
|
|
194
|
+
# "Enable Settings" => lambda {|it| format_boolean it['hasSettings'] },
|
|
195
|
+
# "Enable Scaling" => lambda {|it| format_boolean it['hasAutoScale'] },
|
|
196
|
+
# "Supports Deployments" => lambda {|it| format_boolean it['hasDeployment'] },
|
|
197
|
+
# "Featured" => lambda {|it| format_boolean it['featured'] },
|
|
198
|
+
# "Owner" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
|
199
|
+
# "Active" => lambda {|it| format_boolean it['active'] },
|
|
200
|
+
# "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
201
|
+
# "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
202
|
+
}
|
|
203
|
+
print_description_list(description_cols, layout)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
layout_evars = layout['environmentVariables']
|
|
208
|
+
if layout_evars && layout_evars.size > 0
|
|
209
|
+
print_h2 "Environment Variables"
|
|
210
|
+
evar_columns = [
|
|
211
|
+
{"NAME" => lambda {|it| it['name'] } },
|
|
212
|
+
{"VALUE" => lambda {|it| it['defaultValue'] } },
|
|
213
|
+
{"TYPE" => lambda {|it| it['valueType'].to_s.capitalize } },
|
|
214
|
+
{"EXPORT" => lambda {|it| format_boolean it['export'] } },
|
|
215
|
+
{"MASKED" => lambda {|it| format_boolean it['mask'] } },
|
|
216
|
+
]
|
|
217
|
+
print as_pretty_table(layout_evars, evar_columns)
|
|
218
|
+
else
|
|
219
|
+
# print yellow,"No environment variables found for this instance type.","\n",reset
|
|
220
|
+
end
|
|
156
221
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
},
|
|
174
|
-
"Workflow" => lambda {|it|
|
|
175
|
-
if it['taskSets']
|
|
176
|
-
it['taskSets'][0]['name'] rescue ""
|
|
177
|
-
else
|
|
178
|
-
""
|
|
179
|
-
end
|
|
180
|
-
},
|
|
181
|
-
# "Category" => lambda {|it| it['category'].to_s.capitalize },
|
|
182
|
-
# # "Logo" => lambda {|it| it['logo'].to_s },
|
|
183
|
-
# "Visiblity" => lambda {|it| it['visibility'].to_s.capitalize },
|
|
184
|
-
# "Environment Prefix" => lambda {|it| it['environmentPrefix'] },
|
|
185
|
-
# "Enable Settings" => lambda {|it| format_boolean it['hasSettings'] },
|
|
186
|
-
# "Enable Scaling" => lambda {|it| format_boolean it['hasAutoScale'] },
|
|
187
|
-
# "Supports Deployments" => lambda {|it| format_boolean it['hasDeployment'] },
|
|
188
|
-
# "Featured" => lambda {|it| format_boolean it['featured'] },
|
|
189
|
-
# "Owner" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
|
190
|
-
# "Active" => lambda {|it| format_boolean it['active'] },
|
|
191
|
-
# "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
192
|
-
# "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
193
|
-
}
|
|
194
|
-
print_description_list(description_cols, layout)
|
|
222
|
+
layout_option_types = layout['optionTypes']
|
|
223
|
+
if layout_option_types && layout_option_types.size > 0
|
|
224
|
+
print_h2 "Option Types"
|
|
225
|
+
columns = [
|
|
226
|
+
{"ID" => lambda {|it| it['id'] } },
|
|
227
|
+
{"NAME" => lambda {|it| it['name'] } },
|
|
228
|
+
{"TYPE" => lambda {|it| it['type'] } },
|
|
229
|
+
{"FIELD NAME" => lambda {|it| it['fieldName'] } },
|
|
230
|
+
{"FIELD LABEL" => lambda {|it| it['fieldLabel'] } },
|
|
231
|
+
{"DEFAULT" => lambda {|it| it['defaultValue'] } },
|
|
232
|
+
{"REQUIRED" => lambda {|it| format_boolean it['required'] } },
|
|
233
|
+
]
|
|
234
|
+
print as_pretty_table(layout_option_types, columns)
|
|
235
|
+
else
|
|
236
|
+
# print yellow,"No option types found for this layout.","\n",reset
|
|
237
|
+
end
|
|
195
238
|
|
|
196
|
-
|
|
239
|
+
layout_node_types = layout['containerTypes']
|
|
240
|
+
if layout_node_types && layout_node_types.size > 0
|
|
241
|
+
print_h2 "Node Types"
|
|
242
|
+
# match UI sorting [version desc, name asc]
|
|
243
|
+
# or use something simpler like one of these
|
|
244
|
+
layout_node_types = layout_node_types.sort { |a,b| a['name'] <=> b['name'] }
|
|
245
|
+
# layout_node_types = layout_node_types.sort { |a,b| a['sortOrder'] <=> b['sortOrder'] }
|
|
246
|
+
node_type_columns = [
|
|
247
|
+
{"ID" => lambda {|it| it['id'] } },
|
|
248
|
+
{"NAME" => lambda {|it| it['name'] } },
|
|
249
|
+
{"SHORT NAME" => lambda {|it| it['shortName'] } },
|
|
250
|
+
{"VERSION" => lambda {|it| it['containerVersion'] } },
|
|
251
|
+
{"TECHNOLOGY" => lambda {|it| it['provisionType'] ? it['provisionType']['name'] : '' } },
|
|
252
|
+
{"CATEGORY" => lambda {|it| it['category'] } },
|
|
253
|
+
]
|
|
254
|
+
print as_pretty_table(layout_node_types, node_type_columns)
|
|
255
|
+
else
|
|
256
|
+
# print yellow,"No node types for this layout.","\n",reset
|
|
257
|
+
end
|
|
197
258
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
layout_option_types = layout['optionTypes']
|
|
214
|
-
if layout_option_types && layout_option_types.size > 0
|
|
215
|
-
print_h2 "Option Types"
|
|
216
|
-
columns = [
|
|
217
|
-
{"ID" => lambda {|it| it['id'] } },
|
|
218
|
-
{"NAME" => lambda {|it| it['name'] } },
|
|
219
|
-
{"TYPE" => lambda {|it| it['type'] } },
|
|
220
|
-
{"FIELD NAME" => lambda {|it| it['fieldName'] } },
|
|
221
|
-
{"FIELD LABEL" => lambda {|it| it['fieldLabel'] } },
|
|
222
|
-
{"DEFAULT" => lambda {|it| it['defaultValue'] } },
|
|
223
|
-
{"REQUIRED" => lambda {|it| format_boolean it['required'] } },
|
|
224
|
-
]
|
|
225
|
-
print as_pretty_table(layout_option_types, columns)
|
|
226
|
-
else
|
|
227
|
-
# print yellow,"No option types found for this layout.","\n",reset
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
layout_node_types = layout['containerTypes']
|
|
231
|
-
if layout_node_types && layout_node_types.size > 0
|
|
232
|
-
print_h2 "Node Types"
|
|
233
|
-
# match UI sorting [version desc, name asc]
|
|
234
|
-
# or use something simpler like one of these
|
|
235
|
-
layout_node_types = layout_node_types.sort { |a,b| a['name'] <=> b['name'] }
|
|
236
|
-
# layout_node_types = layout_node_types.sort { |a,b| a['sortOrder'] <=> b['sortOrder'] }
|
|
237
|
-
node_type_columns = [
|
|
238
|
-
{"ID" => lambda {|it| it['id'] } },
|
|
239
|
-
{"NAME" => lambda {|it| it['name'] } },
|
|
240
|
-
{"SHORT NAME" => lambda {|it| it['shortName'] } },
|
|
241
|
-
{"VERSION" => lambda {|it| it['containerVersion'] } },
|
|
242
|
-
{"TECHNOLOGY" => lambda {|it| it['provisionType'] ? it['provisionType']['name'] : '' } },
|
|
243
|
-
{"CATEGORY" => lambda {|it| it['category'] } },
|
|
244
|
-
]
|
|
245
|
-
print as_pretty_table(layout_node_types, node_type_columns)
|
|
246
|
-
else
|
|
247
|
-
# print yellow,"No node types for this layout.","\n",reset
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
layout_spec_templates = layout['specTemplates']
|
|
251
|
-
if layout_spec_templates && layout_spec_templates.size > 0
|
|
252
|
-
print_h2 "Spec Templates"
|
|
253
|
-
layout_spec_templates = layout_spec_templates.sort { |a,b| a['name'] <=> b['name'] }
|
|
254
|
-
spec_template_columns = [
|
|
255
|
-
{"ID" => lambda {|it| it['id'] } },
|
|
256
|
-
{"NAME" => lambda {|it| it['name'] } },
|
|
257
|
-
{"TYPE" => lambda {|it| it['type']['name'] rescue '' } }
|
|
258
|
-
]
|
|
259
|
-
print as_pretty_table(layout_spec_templates, spec_template_columns)
|
|
260
|
-
else
|
|
261
|
-
# print yellow,"No spec templates for this layout.","\n",reset
|
|
262
|
-
end
|
|
259
|
+
layout_spec_templates = layout['specTemplates']
|
|
260
|
+
if layout_spec_templates && layout_spec_templates.size > 0
|
|
261
|
+
print_h2 "Spec Templates"
|
|
262
|
+
layout_spec_templates = layout_spec_templates.sort { |a,b| a['name'] <=> b['name'] }
|
|
263
|
+
spec_template_columns = [
|
|
264
|
+
{"ID" => lambda {|it| it['id'] } },
|
|
265
|
+
{"NAME" => lambda {|it| it['name'] } },
|
|
266
|
+
{"TYPE" => lambda {|it| it['type']['name'] rescue '' } }
|
|
267
|
+
]
|
|
268
|
+
print as_pretty_table(layout_spec_templates, spec_template_columns)
|
|
269
|
+
else
|
|
270
|
+
# print yellow,"No spec templates for this layout.","\n",reset
|
|
271
|
+
end
|
|
263
272
|
|
|
264
|
-
print reset,"\n"
|
|
265
273
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
274
|
+
if options[:show_perms] || (layout['permissions'] && !layout['permissions'].empty?)
|
|
275
|
+
print_permissions(layout['permissions'], layout_permission_excludes)
|
|
276
|
+
print reset
|
|
277
|
+
else
|
|
278
|
+
print reset,"\n"
|
|
269
279
|
end
|
|
280
|
+
return exit_code, err
|
|
270
281
|
end
|
|
271
282
|
|
|
272
283
|
def add(args)
|
|
@@ -327,9 +338,12 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
327
338
|
params['specTemplates'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
|
328
339
|
end
|
|
329
340
|
end
|
|
330
|
-
|
|
331
|
-
opts
|
|
332
|
-
|
|
341
|
+
add_perms_options(opts, options, layout_permission_excludes)
|
|
342
|
+
build_standard_add_options(opts, options)
|
|
343
|
+
opts.footer = <<-EOT
|
|
344
|
+
Create a new layout.
|
|
345
|
+
[instance-type] is required and can be passed as --instance-type instead.
|
|
346
|
+
EOT
|
|
333
347
|
end
|
|
334
348
|
optparse.parse!(args)
|
|
335
349
|
if args.count > 1
|
|
@@ -442,6 +456,15 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
442
456
|
|
|
443
457
|
payload = {'instanceTypeLayout' => params}
|
|
444
458
|
|
|
459
|
+
# Resource Permissions (Groups only for layouts)
|
|
460
|
+
perms = prompt_permissions(options.merge({}), layout_permission_excludes)
|
|
461
|
+
perms_payload = {}
|
|
462
|
+
perms_payload['resourcePermissions'] = perms['resourcePermissions'] if !perms['resourcePermissions'].empty?
|
|
463
|
+
#perms_payload['tenantPermissions'] = perms['tenantPermissions'] if !perms['tenantPermissions'].nil?
|
|
464
|
+
|
|
465
|
+
payload['instanceTypeLayout']['permissions'] = perms_payload
|
|
466
|
+
payload['instanceTypeLayout']['visibility'] = perms['resourcePool']['visibility'] if !perms['resourcePool'].nil? && !perms['resourcePool']['visibility'].nil?
|
|
467
|
+
|
|
445
468
|
end
|
|
446
469
|
@library_layouts_interface.setopts(options)
|
|
447
470
|
if options[:dry_run]
|
|
@@ -456,7 +479,7 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
456
479
|
return
|
|
457
480
|
end
|
|
458
481
|
|
|
459
|
-
print_green_success "Added
|
|
482
|
+
print_green_success "Added layout #{params['name']}"
|
|
460
483
|
|
|
461
484
|
#get([json_response['instanceTypeLayout']['id']])
|
|
462
485
|
|
|
@@ -472,7 +495,7 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
472
495
|
instance_type_id = nil
|
|
473
496
|
evars = nil
|
|
474
497
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
475
|
-
opts.banner = subcommand_usage("[
|
|
498
|
+
opts.banner = subcommand_usage("[layout] [options]")
|
|
476
499
|
opts.on('--name VALUE', String, "Name for this layout") do |val|
|
|
477
500
|
params['name'] = val
|
|
478
501
|
end
|
|
@@ -521,16 +544,18 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
521
544
|
params['specTemplates'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
|
522
545
|
end
|
|
523
546
|
end
|
|
524
|
-
|
|
525
|
-
opts
|
|
547
|
+
add_perms_options(opts, options, layout_permission_excludes)
|
|
548
|
+
build_standard_update_options(opts, options)
|
|
549
|
+
opts.footer = <<-EOT
|
|
550
|
+
Update a layout.
|
|
551
|
+
[layout] is required. This is the name or id of a layout.
|
|
552
|
+
EOT
|
|
526
553
|
end
|
|
527
554
|
optparse.parse!(args)
|
|
528
|
-
|
|
529
|
-
puts optparse
|
|
530
|
-
exit 1
|
|
531
|
-
end
|
|
555
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
|
532
556
|
connect(options)
|
|
533
|
-
|
|
557
|
+
exit_code, err = 0, nil
|
|
558
|
+
|
|
534
559
|
layout = find_layout_by_name_or_id(nil, args[0])
|
|
535
560
|
exit 1 if layout.nil?
|
|
536
561
|
payload = nil
|
|
@@ -576,6 +601,16 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
576
601
|
end
|
|
577
602
|
end
|
|
578
603
|
|
|
604
|
+
# perms
|
|
605
|
+
if options[:groupAccessAll] != nil || options[:groupAccessList]
|
|
606
|
+
perms = prompt_permissions(options.merge({no_prompt:true}), layout_permission_excludes)
|
|
607
|
+
perms_payload = {}
|
|
608
|
+
perms_payload['resourcePermissions'] = perms['resourcePermissions'] if !perms['resourcePermissions'].empty?
|
|
609
|
+
params.deep_merge!({'permissions' => perms_payload}) if !perms_payload.empty?
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
params['visibility'] = options[:visibility] if !options[:visibility].nil?
|
|
613
|
+
|
|
579
614
|
if params.empty?
|
|
580
615
|
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
|
581
616
|
end
|
|
@@ -596,12 +631,61 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
596
631
|
return
|
|
597
632
|
end
|
|
598
633
|
|
|
599
|
-
print_green_success "Updated
|
|
634
|
+
print_green_success "Updated layout #{params['name'] || layout['name']}"
|
|
600
635
|
#list([])
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
636
|
+
return exit_code, err
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
def update_permissions(args)
|
|
640
|
+
options = {}
|
|
641
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
642
|
+
opts.banner = subcommand_usage( "[layout]")
|
|
643
|
+
add_perms_options(opts, options, layout_permission_excludes)
|
|
644
|
+
build_standard_update_options(opts, options)
|
|
645
|
+
opts.footer = <<-EOT
|
|
646
|
+
Update layout permissions.
|
|
647
|
+
[layout] is required. This is the name or id of a layout.
|
|
648
|
+
EOT
|
|
649
|
+
end
|
|
650
|
+
optparse.parse!(args)
|
|
651
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
|
652
|
+
connect(options)
|
|
653
|
+
exit_code, err = 0, nil
|
|
654
|
+
# if !is_master_account
|
|
655
|
+
# print_red_alert "Permissions only available for master account"
|
|
656
|
+
# return 1
|
|
657
|
+
# end
|
|
658
|
+
layout = find_layout_by_name_or_id(nil, args[0])
|
|
659
|
+
return 1, "layout not found for #{args[0]}" if layout.nil?
|
|
660
|
+
payload = {}
|
|
661
|
+
if options[:payload]
|
|
662
|
+
payload = options[:payload]
|
|
663
|
+
payload.deep_merge!(parse_passed_options(options))
|
|
664
|
+
else
|
|
665
|
+
payload.deep_merge!(parse_passed_options(options))
|
|
666
|
+
|
|
667
|
+
perms = prompt_permissions(options.merge({}), layout_permission_excludes)
|
|
668
|
+
perms_payload = {}
|
|
669
|
+
perms_payload['resourcePermissions'] = perms['resourcePermissions'] if !perms['resourcePermissions'].empty?
|
|
670
|
+
payload.deep_merge!({'permissions' => perms_payload}) if !perms_payload.empty?
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
@library_layouts_interface.setopts(options)
|
|
674
|
+
if options[:dry_run]
|
|
675
|
+
print_dry_run @library_layouts_interface.dry.update_permissions(layout['id'], payload)
|
|
676
|
+
return
|
|
604
677
|
end
|
|
678
|
+
json_response = @library_layouts_interface.update_permissions(layout['id'], payload)
|
|
679
|
+
render_response(json_response, options, 'instanceTypeLayout') do
|
|
680
|
+
# note: this api does not return 400 when it fails?
|
|
681
|
+
if json_response['success']
|
|
682
|
+
print_green_success "Updated layout permissions"
|
|
683
|
+
else
|
|
684
|
+
print_rest_errors(json_response, options)
|
|
685
|
+
exit_code, err = 3, (json_response['msg'] || "api did not return success:true")
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
return exit_code, err
|
|
605
689
|
end
|
|
606
690
|
|
|
607
691
|
def remove(args)
|
|
@@ -637,7 +721,7 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
637
721
|
return
|
|
638
722
|
end
|
|
639
723
|
|
|
640
|
-
print_green_success "Removed
|
|
724
|
+
print_green_success "Removed layout #{layout['name']}"
|
|
641
725
|
#list([])
|
|
642
726
|
rescue RestClient::Exception => e
|
|
643
727
|
print_rest_exception(e, options)
|
|
@@ -647,29 +731,30 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
647
731
|
|
|
648
732
|
private
|
|
649
733
|
|
|
650
|
-
def find_layout_by_name_or_id(instance_type_id, val)
|
|
734
|
+
def find_layout_by_name_or_id(instance_type_id, val, params={})
|
|
651
735
|
if val.to_s =~ /\A\d{1,}\Z/
|
|
652
|
-
return find_layout_by_id(instance_type_id, val)
|
|
736
|
+
return find_layout_by_id(instance_type_id, val, params)
|
|
653
737
|
else
|
|
654
|
-
return find_layout_by_name(instance_type_id, val)
|
|
738
|
+
return find_layout_by_name(instance_type_id, val, params)
|
|
655
739
|
end
|
|
656
740
|
end
|
|
657
741
|
|
|
658
|
-
def find_layout_by_id(instance_type_id, id)
|
|
742
|
+
def find_layout_by_id(instance_type_id, id, params={})
|
|
659
743
|
begin
|
|
660
|
-
json_response = @library_layouts_interface.get(instance_type_id, id.to_i)
|
|
744
|
+
json_response = @library_layouts_interface.get(instance_type_id, id.to_i, params)
|
|
661
745
|
return json_response['instanceTypeLayout']
|
|
662
746
|
rescue RestClient::Exception => e
|
|
663
747
|
if e.response && e.response.code == 404
|
|
664
|
-
|
|
748
|
+
print_rest_exception(e)
|
|
749
|
+
#print_red_alert "Layout not found by id #{id}"
|
|
665
750
|
else
|
|
666
751
|
raise e
|
|
667
752
|
end
|
|
668
753
|
end
|
|
669
754
|
end
|
|
670
755
|
|
|
671
|
-
def find_layout_by_name(instance_type_id, name)
|
|
672
|
-
layouts = @library_layouts_interface.list(instance_type_id, {name: name.to_s})['instanceTypeLayouts']
|
|
756
|
+
def find_layout_by_name(instance_type_id, name, params={})
|
|
757
|
+
layouts = @library_layouts_interface.list(instance_type_id, params.merge({name: name.to_s}))['instanceTypeLayouts']
|
|
673
758
|
if layouts.empty?
|
|
674
759
|
print_red_alert "Layout not found by name #{name}"
|
|
675
760
|
return nil
|
|
@@ -712,4 +797,7 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
|
712
797
|
val.to_s # .capitalize
|
|
713
798
|
end
|
|
714
799
|
|
|
800
|
+
def layout_permission_excludes
|
|
801
|
+
['plans', 'groupDefaults', 'visibility', 'tenants']
|
|
802
|
+
end
|
|
715
803
|
end
|