morpheus-cli 5.3.3 → 5.3.4
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 +12 -0
- data/lib/morpheus/api/clouds_interface.rb +4 -11
- data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
- data/lib/morpheus/api/load_balancer_profiles_interface.rb +10 -0
- data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +4 -4
- data/lib/morpheus/api/network_routers_interface.rb +21 -0
- data/lib/morpheus/api/network_servers_interface.rb +42 -0
- data/lib/morpheus/api/rest_interface.rb +2 -1
- data/lib/morpheus/api/virtual_servers_interface.rb +9 -0
- data/lib/morpheus/cli/cli_command.rb +2 -1
- data/lib/morpheus/cli/cloud_resource_pools_command.rb +1 -1
- data/lib/morpheus/cli/clouds.rb +22 -40
- data/lib/morpheus/cli/hosts.rb +0 -1
- data/lib/morpheus/cli/instances.rb +111 -7
- data/lib/morpheus/cli/invoices_command.rb +42 -38
- data/lib/morpheus/cli/library_option_lists_command.rb +3 -3
- data/lib/morpheus/cli/load_balancer_pools.rb +111 -0
- data/lib/morpheus/cli/load_balancer_virtual_servers.rb +136 -0
- data/lib/morpheus/cli/load_balancers.rb +0 -155
- data/lib/morpheus/cli/mixins/load_balancers_helper.rb +2 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +32 -11
- data/lib/morpheus/cli/mixins/rest_command.rb +53 -37
- data/lib/morpheus/cli/mixins/secondary_rest_command.rb +488 -0
- data/lib/morpheus/cli/network_routers_command.rb +291 -7
- data/lib/morpheus/cli/network_scopes_command.rb +442 -0
- data/lib/morpheus/cli/networks_command.rb +2 -2
- data/lib/morpheus/cli/option_types.rb +20 -0
- data/lib/morpheus/cli/subnets_command.rb +7 -2
- data/lib/morpheus/cli/tasks.rb +25 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +2 -0
- data/lib/morpheus/cli.rb +9 -1
- metadata +9 -2
@@ -0,0 +1,488 @@
|
|
1
|
+
# SecondaryRestCommand is a mixin for Morpheus::Cli command classes.
|
2
|
+
# for resources that are secondary to some parent resource.
|
3
|
+
# Provides basic CRUD commands: list, get, add, update, remove
|
4
|
+
# The parent resource is specified as the first argument for all the comments.
|
5
|
+
#
|
6
|
+
# Example of a SecondaryRestCommand for `morpheus load-balancer-virtual-servers`.
|
7
|
+
#
|
8
|
+
# class Morpheus::Cli::LoadBalancerVirtualServers
|
9
|
+
#
|
10
|
+
# include Morpheus::Cli::CliCommand
|
11
|
+
# include Morpheus::Cli::RestCommand
|
12
|
+
# include Morpheus::Cli::SecondaryRestCommand
|
13
|
+
# include Morpheus::Cli::LoadBalancersHelper
|
14
|
+
#
|
15
|
+
# set_command_name :'load-balancer-virtual-servers'
|
16
|
+
# register_subcommands :list, :get, :add, :update, :remove
|
17
|
+
#
|
18
|
+
# register_interfaces :load_balancer_virtual_servers,
|
19
|
+
# :load_balancers, :load_balancer_types
|
20
|
+
#
|
21
|
+
# set_rest_parent_name :load_balancers
|
22
|
+
#
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
module Morpheus::Cli::SecondaryRestCommand
|
26
|
+
def self.included(base)
|
27
|
+
base.extend ClassMethods
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
## duplicated the rest_* settings with rest_parent_*, for defining the parent resource
|
33
|
+
|
34
|
+
# rest_parent_name is the rest_name for the parent
|
35
|
+
def rest_parent_name
|
36
|
+
@rest_parent_name || default_rest_parent_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_rest_parent_name
|
40
|
+
words = rest_name.split("_")
|
41
|
+
if words.size > 1
|
42
|
+
words.pop
|
43
|
+
return words.join("_") + "s"
|
44
|
+
else
|
45
|
+
# this wont happen, default wont make sense in this scenario
|
46
|
+
# "parent_" + rest_name
|
47
|
+
raise "Unable to determine default_rest_parent_name for rest_name: #{rest_name}, class: #{self}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def rest_parent_name=(v)
|
52
|
+
@rest_parent_name = v.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
alias :set_rest_parent_name :rest_parent_name=
|
56
|
+
alias :set_rest_parent :rest_parent_name=
|
57
|
+
#alias :rest_parent= :rest_parent_name=
|
58
|
+
|
59
|
+
# rest_parent_key is the singular name of the resource eg. "neat_thing"
|
60
|
+
def rest_parent_key
|
61
|
+
@rest_parent_key || default_rest_parent_key
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_rest_parent_key
|
65
|
+
rest_parent_name.chomp("s")
|
66
|
+
end
|
67
|
+
|
68
|
+
def rest_parent_key=(v)
|
69
|
+
@rest_parent_key = v.to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
alias :set_rest_parent_key :rest_parent_key=
|
73
|
+
|
74
|
+
def rest_parent_arg
|
75
|
+
@rest_parent_arg || default_rest_parent_arg
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_rest_parent_arg
|
79
|
+
rest_parent_key.to_s.gsub("_", " ")
|
80
|
+
end
|
81
|
+
|
82
|
+
def rest_parent_arg=(v)
|
83
|
+
@rest_parent_arg = v.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
alias :set_rest_parent_arg :rest_parent_arg=
|
87
|
+
|
88
|
+
# rest_parent_label is the capitalized resource label eg. "Neat Thing"
|
89
|
+
def rest_parent_label
|
90
|
+
@rest_parent_label || default_rest_parent_label
|
91
|
+
end
|
92
|
+
|
93
|
+
def default_rest_parent_label
|
94
|
+
rest_parent_key.to_s.split("_").collect {|it| it.to_s.capitalize }.join(" ")
|
95
|
+
end
|
96
|
+
|
97
|
+
def rest_parent_label=(v)
|
98
|
+
@rest_parent_label = v.to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
alias :set_rest_parent_label :rest_parent_label=
|
102
|
+
|
103
|
+
# the plural version of the label eg. "Neat Things"
|
104
|
+
def rest_parent_label_plural
|
105
|
+
@rest_parent_label_plural || default_rest_parent_label_plural
|
106
|
+
end
|
107
|
+
|
108
|
+
def default_rest_parent_label_plural
|
109
|
+
#rest_parent_name.to_s.split("_").collect {|it| it.to_s.capitalize }.join(" ")
|
110
|
+
rest_parent_label.to_s.pluralize
|
111
|
+
end
|
112
|
+
|
113
|
+
def rest_parent_label_plural=(v)
|
114
|
+
@rest_parent_label_plural = v.to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
alias :set_rest_parent_label_plural :rest_parent_label_plural=
|
118
|
+
|
119
|
+
# the name of the default interface, matches the rest name eg. "neat_things"
|
120
|
+
def rest_parent_interface_name
|
121
|
+
@rest_parent_interface_name || default_rest_parent_interface_name
|
122
|
+
end
|
123
|
+
|
124
|
+
def default_rest_parent_interface_name
|
125
|
+
rest_parent_name
|
126
|
+
end
|
127
|
+
|
128
|
+
def rest_parent_interface_name=(v)
|
129
|
+
@rest_parent_interface_name = v.to_s
|
130
|
+
end
|
131
|
+
|
132
|
+
alias :set_rest_parent_interface_name :rest_parent_interface_name=
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
## duplicated the rest_* settings with rest_parent, for the parents resource
|
137
|
+
|
138
|
+
def rest_parent_name
|
139
|
+
self.class.rest_parent_name
|
140
|
+
end
|
141
|
+
|
142
|
+
def rest_parent_key
|
143
|
+
self.class.rest_parent_key
|
144
|
+
end
|
145
|
+
|
146
|
+
def rest_parent_arg
|
147
|
+
self.class.rest_parent_arg
|
148
|
+
end
|
149
|
+
|
150
|
+
def rest_parent_label
|
151
|
+
self.class.rest_parent_label
|
152
|
+
end
|
153
|
+
|
154
|
+
def rest_parent_label_plural
|
155
|
+
self.class.rest_parent_label_plural
|
156
|
+
end
|
157
|
+
|
158
|
+
def rest_parent_interface_name
|
159
|
+
self.class.rest_parent_interface_name # || "@#{rest_parent_name}_interface"
|
160
|
+
end
|
161
|
+
|
162
|
+
def rest_parent_interface
|
163
|
+
instance_variable_get("@#{rest_parent_interface_name}_interface")
|
164
|
+
end
|
165
|
+
|
166
|
+
def rest_parent_object_key
|
167
|
+
self.send("#{rest_parent_key}_object_key")
|
168
|
+
end
|
169
|
+
|
170
|
+
def rest_parent_list_key
|
171
|
+
self.send("#{rest_parent_key}_list_key")
|
172
|
+
end
|
173
|
+
|
174
|
+
def rest_parent_column_definitions
|
175
|
+
self.send("#{rest_parent_key}_column_definitions")
|
176
|
+
end
|
177
|
+
|
178
|
+
def rest_parent_list_column_definitions
|
179
|
+
self.send("#{rest_parent_key}_list_column_definitions")
|
180
|
+
end
|
181
|
+
|
182
|
+
def rest_parent_find_by_name_or_id(name)
|
183
|
+
return self.send("find_#{rest_parent_key}_by_name_or_id", name)
|
184
|
+
end
|
185
|
+
|
186
|
+
def registered_interfaces
|
187
|
+
self.class.registered_interfaces
|
188
|
+
end
|
189
|
+
|
190
|
+
def list(args)
|
191
|
+
parent_id, parent_record = nil, nil
|
192
|
+
params = {}
|
193
|
+
options = {}
|
194
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
195
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [search]")
|
196
|
+
build_standard_list_options(opts, options)
|
197
|
+
opts.footer = <<-EOT
|
198
|
+
List #{rest_label_plural.downcase}.
|
199
|
+
[#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
|
200
|
+
[search] is optional. This is a search phrase to filter the results.
|
201
|
+
EOT
|
202
|
+
end
|
203
|
+
optparse.parse!(args)
|
204
|
+
parent_id = args[0]
|
205
|
+
if args[1] # && rest_has_name
|
206
|
+
record_name = args[1]
|
207
|
+
end
|
208
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
209
|
+
if args.count > 1
|
210
|
+
options[:phrase] = args[1..-1].join(" ")
|
211
|
+
end
|
212
|
+
connect(options)
|
213
|
+
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
214
|
+
if parent_record.nil?
|
215
|
+
raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
|
216
|
+
end
|
217
|
+
parent_id = parent_record['id']
|
218
|
+
params.merge!(parse_list_options(options))
|
219
|
+
rest_interface.setopts(options)
|
220
|
+
if options[:dry_run]
|
221
|
+
print_dry_run rest_interface.dry.list(parent_id, params)
|
222
|
+
return
|
223
|
+
end
|
224
|
+
json_response = rest_interface.list(parent_id, params)
|
225
|
+
render_response(json_response, options, rest_list_key) do
|
226
|
+
records = json_response[rest_list_key]
|
227
|
+
print_h1 "Morpheus #{rest_label_plural}"
|
228
|
+
if records.nil? || records.empty?
|
229
|
+
print cyan,"No #{rest_label_plural.downcase} found.",reset,"\n"
|
230
|
+
else
|
231
|
+
print as_pretty_table(records, rest_list_column_definitions.upcase_keys!, options)
|
232
|
+
print_results_pagination(json_response) if json_response['meta']
|
233
|
+
end
|
234
|
+
print reset,"\n"
|
235
|
+
end
|
236
|
+
return 0, nil
|
237
|
+
end
|
238
|
+
|
239
|
+
def get(args)
|
240
|
+
params = {}
|
241
|
+
options = {}
|
242
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
243
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}]")
|
244
|
+
build_standard_get_options(opts, options)
|
245
|
+
opts.footer = <<-EOT
|
246
|
+
Get details about #{a_or_an(rest_label)} #{rest_label.downcase}.
|
247
|
+
[#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
|
248
|
+
[#{rest_arg}] is required. This is the name or id of #{a_or_an(rest_label)} #{rest_label.downcase}.
|
249
|
+
EOT
|
250
|
+
end
|
251
|
+
optparse.parse!(args)
|
252
|
+
verify_args!(args:args, optparse:optparse, min:2)
|
253
|
+
connect(options)
|
254
|
+
parent_id = args[0]
|
255
|
+
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
256
|
+
if parent_record.nil?
|
257
|
+
raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
|
258
|
+
end
|
259
|
+
parent_id = parent_record['id']
|
260
|
+
params.merge!(parse_query_options(options))
|
261
|
+
id_list = parse_id_list(args[1..-1])
|
262
|
+
return run_command_for_each_arg(id_list) do |arg|
|
263
|
+
_get(parent_id, arg, params, options)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def _get(parent_id, id, params, options)
|
268
|
+
if id !~ /\A\d{1,}\Z/
|
269
|
+
record = rest_find_by_name_or_id(id)
|
270
|
+
if record.nil?
|
271
|
+
raise_command_error "#{rest_label} not found for name '#{id}'"
|
272
|
+
end
|
273
|
+
id = record['id']
|
274
|
+
end
|
275
|
+
rest_interface.setopts(options)
|
276
|
+
if options[:dry_run]
|
277
|
+
print_dry_run rest_interface.dry.get(id, params)
|
278
|
+
return
|
279
|
+
end
|
280
|
+
json_response = rest_interface.get(id, params)
|
281
|
+
render_response_for_get(json_response, options)
|
282
|
+
return 0, nil
|
283
|
+
end
|
284
|
+
|
285
|
+
def render_response_for_get(json_response, options)
|
286
|
+
render_response(json_response, options, rest_object_key) do
|
287
|
+
record = json_response[rest_object_key]
|
288
|
+
print_h1 rest_label, [], options
|
289
|
+
print cyan
|
290
|
+
print_description_list(rest_column_definitions, record, options)
|
291
|
+
# show config settings...
|
292
|
+
if record['optionTypes'] && record['optionTypes'].size > 0
|
293
|
+
print_h2 "Option Types", options
|
294
|
+
print format_option_types_table(record['optionTypes'], options, rest_object_key)
|
295
|
+
end
|
296
|
+
print reset,"\n"
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def add(args)
|
301
|
+
parent_id, parent_record = nil, nil
|
302
|
+
record_type_id = nil
|
303
|
+
options = {}
|
304
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
305
|
+
if rest_has_type
|
306
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}] -t TYPE")
|
307
|
+
opts.on( '-t', "--#{rest_type_arg} TYPE", "#{rest_type_label}" ) do |val|
|
308
|
+
record_type_id = val
|
309
|
+
end
|
310
|
+
else
|
311
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}]")
|
312
|
+
end
|
313
|
+
# if defined?(add_#{rest_key}_option_types)
|
314
|
+
# build_option_type_options(opts, options, add_#{rest_key}_option_types)
|
315
|
+
# end
|
316
|
+
build_standard_add_options(opts, options)
|
317
|
+
opts.footer = <<-EOT
|
318
|
+
Create a new #{rest_label.downcase}.
|
319
|
+
[#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
|
320
|
+
[#{rest_arg}] is required. This is the name of the new #{rest_label.downcase}.
|
321
|
+
EOT
|
322
|
+
end
|
323
|
+
optparse.parse!(args)
|
324
|
+
verify_args!(args:args, optparse:optparse, min:1, max: 2)
|
325
|
+
# todo: make supporting args[0] optional and more flexible
|
326
|
+
# for now args[0] is assumed to be the 'name'
|
327
|
+
record_name = nil
|
328
|
+
parent_id = args[0]
|
329
|
+
if args[1] # && rest_has_name
|
330
|
+
record_name = args[1]
|
331
|
+
end
|
332
|
+
# todo: maybe need a flag to make this required, it could be an option type too, so
|
333
|
+
if rest_has_type
|
334
|
+
if record_type_id.nil?
|
335
|
+
raise_command_error "#{rest_type_label} is required.\n#{optparse}"
|
336
|
+
end
|
337
|
+
end
|
338
|
+
connect(options)
|
339
|
+
if rest_has_type
|
340
|
+
record_type = rest_type_find_by_name_or_id(record_type_id)
|
341
|
+
if record_type.nil?
|
342
|
+
raise_command_error "#{rest_type_label} not found for '#{record_type_id}'.\n#{optparse}"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
346
|
+
if parent_record.nil?
|
347
|
+
raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
|
348
|
+
end
|
349
|
+
parent_id = parent_record['id']
|
350
|
+
passed_options = parse_passed_options(options)
|
351
|
+
payload = {}
|
352
|
+
if options[:payload]
|
353
|
+
payload = options[:payload]
|
354
|
+
payload.deep_merge!({rest_object_key => passed_options})
|
355
|
+
else
|
356
|
+
record_payload = {}
|
357
|
+
if record_name
|
358
|
+
record_payload['name'] = record_name
|
359
|
+
options[:options]['name'] = record_name # injected for prompt
|
360
|
+
end
|
361
|
+
if rest_has_type && record_type
|
362
|
+
# record_payload['type'] = {'code' => record_type['code']}
|
363
|
+
record_payload['type'] = record_type['code']
|
364
|
+
options[:options]['type'] = record_type['code'] # injected for prompt
|
365
|
+
end
|
366
|
+
record_payload.deep_merge!(passed_options)
|
367
|
+
# options by type
|
368
|
+
my_option_types = record_type ? record_type['optionTypes'] : nil
|
369
|
+
if my_option_types && !my_option_types.empty?
|
370
|
+
# remove redundant fieldContext
|
371
|
+
my_option_types.each do |option_type|
|
372
|
+
if option_type['fieldContext'] == rest_object_key
|
373
|
+
option_type['fieldContext'] = nil
|
374
|
+
end
|
375
|
+
end
|
376
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, options[:params])
|
377
|
+
v_prompt.deep_compact!
|
378
|
+
v_prompt.booleanize! # 'on' => true
|
379
|
+
record_payload.deep_merge!(v_prompt)
|
380
|
+
end
|
381
|
+
payload[rest_object_key] = record_payload
|
382
|
+
end
|
383
|
+
rest_interface.setopts(options)
|
384
|
+
if options[:dry_run]
|
385
|
+
print_dry_run rest_interface.dry.create(parent_id, payload)
|
386
|
+
return
|
387
|
+
end
|
388
|
+
json_response = rest_interface.create(parent_id, payload)
|
389
|
+
render_response(json_response, options, rest_object_key) do
|
390
|
+
record = json_response[rest_object_key]
|
391
|
+
print_green_success "Added #{rest_label.downcase} #{record['name'] || record['id']}"
|
392
|
+
return _get(parent_id, record["id"], {}, options)
|
393
|
+
end
|
394
|
+
return 0, nil
|
395
|
+
end
|
396
|
+
|
397
|
+
def update(args)
|
398
|
+
parent_id = args[0]
|
399
|
+
id = args[1]
|
400
|
+
options = {}
|
401
|
+
params = {}
|
402
|
+
account_name = nil
|
403
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
404
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}] [options]")
|
405
|
+
build_standard_update_options(opts, options)
|
406
|
+
opts.footer = <<-EOT
|
407
|
+
Update an existing #{rest_label.downcase}.
|
408
|
+
[#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
|
409
|
+
[#{rest_arg}] is required. This is the name or id of #{a_or_an(rest_label)} #{rest_label.downcase}.
|
410
|
+
EOT
|
411
|
+
end
|
412
|
+
optparse.parse!(args)
|
413
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
414
|
+
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
415
|
+
if parent_record.nil?
|
416
|
+
raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
|
417
|
+
end
|
418
|
+
parent_id = parent_record['id']
|
419
|
+
connect(options)
|
420
|
+
record = rest_find_by_name_or_id(id)
|
421
|
+
passed_options = parse_passed_options(options)
|
422
|
+
payload = nil
|
423
|
+
if options[:payload]
|
424
|
+
payload = options[:payload]
|
425
|
+
payload.deep_merge!({rest_object_key => passed_options}) unless passed_options.empty?
|
426
|
+
else
|
427
|
+
record_payload = passed_options
|
428
|
+
if record_payload.empty?
|
429
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
430
|
+
end
|
431
|
+
payload[rest_object_key] = record_payload
|
432
|
+
end
|
433
|
+
rest_interface.setopts(options)
|
434
|
+
if options[:dry_run]
|
435
|
+
print_dry_run rest_interface.dry.update(parent_id, record['id'], payload)
|
436
|
+
return
|
437
|
+
end
|
438
|
+
json_response = rest_interface.update(parent_id, record['id'], payload)
|
439
|
+
render_response(json_response, options, rest_object_key) do
|
440
|
+
print_green_success "Updated #{rest_label.downcase} #{record['name'] || record['id']}"
|
441
|
+
_get(parent_id, record["id"], {}, options)
|
442
|
+
end
|
443
|
+
return 0, nil
|
444
|
+
end
|
445
|
+
|
446
|
+
def remove(args)
|
447
|
+
parent_id = args[0]
|
448
|
+
id = args[1]
|
449
|
+
params = {}
|
450
|
+
options = {}
|
451
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
452
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}]")
|
453
|
+
build_standard_remove_options(opts, options)
|
454
|
+
opts.footer = <<-EOT
|
455
|
+
Delete an existing #{rest_label.downcase}.
|
456
|
+
[#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
|
457
|
+
[#{rest_arg}] is required. This is the name or id of #{a_or_an(rest_label)} #{rest_label.downcase}.
|
458
|
+
EOT
|
459
|
+
end
|
460
|
+
optparse.parse!(args)
|
461
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
462
|
+
connect(options)
|
463
|
+
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
464
|
+
if parent_record.nil?
|
465
|
+
raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
|
466
|
+
end
|
467
|
+
record = rest_find_by_name_or_id(id)
|
468
|
+
if record.nil?
|
469
|
+
return 1, "#{rest_name} not found for '#{id}'"
|
470
|
+
end
|
471
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the #{rest_label.downcase} #{record['name'] || record['id']}?")
|
472
|
+
return 9, "aborted"
|
473
|
+
end
|
474
|
+
params.merge!(parse_query_options(options))
|
475
|
+
rest_interface.setopts(options)
|
476
|
+
if options[:dry_run]
|
477
|
+
print_dry_run rest_interface.dry.destroy(parent_id, record['id'])
|
478
|
+
return 0, nil
|
479
|
+
end
|
480
|
+
json_response = rest_interface.destroy(parent_id, record['id'], params)
|
481
|
+
render_response(json_response, options) do
|
482
|
+
print_green_success "Removed #{rest_label.downcase} #{record['name'] || record['id']}"
|
483
|
+
end
|
484
|
+
return 0, nil
|
485
|
+
end
|
486
|
+
|
487
|
+
end
|
488
|
+
|