morpheus-cli 4.2.16 → 4.2.17
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/README.md +8 -6
- data/lib/morpheus/api/api_client.rb +32 -14
- data/lib/morpheus/api/auth_interface.rb +4 -2
- data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
- data/lib/morpheus/api/backups_interface.rb +16 -0
- data/lib/morpheus/api/deploy_interface.rb +25 -56
- data/lib/morpheus/api/deployments_interface.rb +43 -54
- data/lib/morpheus/api/doc_interface.rb +57 -0
- data/lib/morpheus/api/instances_interface.rb +5 -0
- data/lib/morpheus/api/rest_interface.rb +40 -0
- data/lib/morpheus/api/user_sources_interface.rb +0 -15
- data/lib/morpheus/api/users_interface.rb +2 -3
- data/lib/morpheus/benchmarking.rb +2 -2
- data/lib/morpheus/cli.rb +3 -1
- data/lib/morpheus/cli/access_token_command.rb +27 -10
- data/lib/morpheus/cli/apps.rb +21 -15
- data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
- data/lib/morpheus/cli/backups_command.rb +271 -0
- data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +92 -41
- data/lib/morpheus/cli/clusters.rb +0 -18
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +7 -7
- data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
- data/lib/morpheus/cli/credentials.rb +13 -9
- data/lib/morpheus/cli/deploy.rb +374 -0
- data/lib/morpheus/cli/deployments.rb +521 -197
- data/lib/morpheus/cli/deploys.rb +271 -126
- data/lib/morpheus/cli/doc.rb +182 -0
- data/lib/morpheus/cli/error_handler.rb +23 -8
- data/lib/morpheus/cli/errors.rb +3 -2
- data/lib/morpheus/cli/image_builder_command.rb +2 -2
- data/lib/morpheus/cli/instances.rb +136 -17
- data/lib/morpheus/cli/invoices_command.rb +51 -38
- data/lib/morpheus/cli/library_layouts_command.rb +1 -1
- data/lib/morpheus/cli/login.rb +9 -3
- data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
- data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
- data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +110 -74
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
- data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
- data/lib/morpheus/cli/network_routers_command.rb +1 -1
- data/lib/morpheus/cli/option_parser.rb +48 -5
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/remote.rb +3 -2
- data/lib/morpheus/cli/roles.rb +49 -92
- data/lib/morpheus/cli/security_groups.rb +7 -1
- data/lib/morpheus/cli/service_plans_command.rb +10 -10
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +7 -6
- data/lib/morpheus/cli/subnets_command.rb +1 -1
- data/lib/morpheus/cli/tenants_command.rb +133 -163
- data/lib/morpheus/cli/user_groups_command.rb +20 -65
- data/lib/morpheus/cli/user_settings_command.rb +115 -13
- data/lib/morpheus/cli/user_sources_command.rb +57 -24
- data/lib/morpheus/cli/users.rb +210 -186
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
- data/lib/morpheus/cli/whoami.rb +113 -6
- data/lib/morpheus/cli/workflows.rb +1 -1
- data/lib/morpheus/ext/hash.rb +21 -0
- data/lib/morpheus/terminal.rb +1 -0
- metadata +12 -3
- data/lib/morpheus/cli/auth_command.rb +0 -105
@@ -0,0 +1,271 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
class Morpheus::Cli::BackupsCommand
|
4
|
+
include Morpheus::Cli::CliCommand
|
5
|
+
include Morpheus::Cli::BackupsHelper
|
6
|
+
include Morpheus::Cli::ProvisioningHelper
|
7
|
+
include Morpheus::Cli::OptionSourceHelper
|
8
|
+
|
9
|
+
set_command_hidden # hide until ready
|
10
|
+
|
11
|
+
set_command_name :'backups'
|
12
|
+
|
13
|
+
register_subcommands :list, :get, :add, :update, :remove, :run, :restore
|
14
|
+
|
15
|
+
def connect(opts)
|
16
|
+
@api_client = establish_remote_appliance_connection(opts)
|
17
|
+
@backups_interface = @api_client.backups
|
18
|
+
@backup_jobs_interface = @api_client.backup_jobs
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle(args)
|
22
|
+
handle_subcommand(args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def list(args)
|
26
|
+
options = {}
|
27
|
+
params = {}
|
28
|
+
ref_ids = []
|
29
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
30
|
+
opts.banner = subcommand_usage("[search]")
|
31
|
+
build_standard_list_options(opts, options)
|
32
|
+
opts.footer = "List backups."
|
33
|
+
end
|
34
|
+
optparse.parse!(args)
|
35
|
+
connect(options)
|
36
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
37
|
+
if args.count > 0
|
38
|
+
options[:phrase] = args.join(" ")
|
39
|
+
end
|
40
|
+
params.merge!(parse_list_options(options))
|
41
|
+
@backups_interface.setopts(options)
|
42
|
+
if options[:dry_run]
|
43
|
+
print_dry_run @backups_interface.dry.list(params)
|
44
|
+
return
|
45
|
+
end
|
46
|
+
json_response = @backups_interface.list(params)
|
47
|
+
backups = json_response['backups']
|
48
|
+
render_response(json_response, options, 'backups') do
|
49
|
+
print_h1 "Morpheus Backups", parse_list_subtitles(options), options
|
50
|
+
if backups.empty?
|
51
|
+
print cyan,"No backups found.",reset,"\n"
|
52
|
+
else
|
53
|
+
print as_pretty_table(backups, backup_column_definitions.upcase_keys!, options)
|
54
|
+
print_results_pagination(json_response)
|
55
|
+
end
|
56
|
+
print reset,"\n"
|
57
|
+
end
|
58
|
+
if backups.empty?
|
59
|
+
return 1, "no backups found"
|
60
|
+
else
|
61
|
+
return 0, nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def get(args)
|
66
|
+
params = {}
|
67
|
+
options = {}
|
68
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
69
|
+
opts.banner = subcommand_usage("[backup]")
|
70
|
+
build_standard_get_options(opts, options)
|
71
|
+
opts.footer = <<-EOT
|
72
|
+
Get details about a specific backup.
|
73
|
+
[backup] is required. This is the name or id of a backup.
|
74
|
+
EOT
|
75
|
+
end
|
76
|
+
optparse.parse!(args)
|
77
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
78
|
+
connect(options)
|
79
|
+
id_list = parse_id_list(args)
|
80
|
+
return run_command_for_each_arg(id_list) do |arg|
|
81
|
+
_get(arg, params, options)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def _get(id, options)
|
86
|
+
params = {}
|
87
|
+
@backups_interface.setopts(options)
|
88
|
+
if options[:dry_run]
|
89
|
+
print_dry_run @backups_interface.dry.get(id, params)
|
90
|
+
return
|
91
|
+
end
|
92
|
+
json_response = @backups_interface.get(id, params)
|
93
|
+
backup = json_response['backup']
|
94
|
+
render_response(json_response, options, 'backup') do
|
95
|
+
print_h1 "Backup Details", [], options
|
96
|
+
print cyan
|
97
|
+
print_description_list(backup_column_definitions, backup)
|
98
|
+
print reset,"\n"
|
99
|
+
end
|
100
|
+
return 0, nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def add(args)
|
104
|
+
options = {}
|
105
|
+
params = {}
|
106
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
107
|
+
opts.banner = subcommand_usage("[name] [options]")
|
108
|
+
build_option_type_options(opts, options, add_backup_option_types)
|
109
|
+
build_option_type_options(opts, options, add_backup_advanced_option_types)
|
110
|
+
build_standard_add_options(opts, options)
|
111
|
+
opts.footer = <<-EOT
|
112
|
+
Create a new backup.
|
113
|
+
EOT
|
114
|
+
end
|
115
|
+
optparse.parse!(args)
|
116
|
+
verify_args!(args:args, optparse:optparse, min:0, max:1)
|
117
|
+
options[:options]['name'] = args[0] if args[0]
|
118
|
+
connect(options)
|
119
|
+
payload = {}
|
120
|
+
if options[:payload]
|
121
|
+
payload = options[:payload]
|
122
|
+
payload.deep_merge!({'backup' => parse_passed_options(options)})
|
123
|
+
else
|
124
|
+
payload.deep_merge!({'backup' => parse_passed_options(options)})
|
125
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(add_backup_option_types(), options[:options], @api_client, options[:params])
|
126
|
+
params.deep_merge!(v_prompt)
|
127
|
+
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_backup_advanced_option_types, options[:options], @api_client, options[:params])
|
128
|
+
advanced_config.deep_compact!
|
129
|
+
params.deep_merge!(advanced_config)
|
130
|
+
payload['backup'].deep_merge!(params)
|
131
|
+
end
|
132
|
+
@backups_interface.setopts(options)
|
133
|
+
if options[:dry_run]
|
134
|
+
print_dry_run @backups_interface.dry.create(payload)
|
135
|
+
return 0, nil
|
136
|
+
end
|
137
|
+
json_response = @backups_interface.create(payload)
|
138
|
+
backup = json_response['backup']
|
139
|
+
render_response(json_response, options, 'backup') do
|
140
|
+
print_green_success "Added backup #{backup['name']}"
|
141
|
+
return _get(backup["id"], {}, options)
|
142
|
+
end
|
143
|
+
return 0, nil
|
144
|
+
end
|
145
|
+
|
146
|
+
def update(args)
|
147
|
+
options = {}
|
148
|
+
params = {}
|
149
|
+
payload = {}
|
150
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
151
|
+
opts.banner = subcommand_usage("[backup] [options]")
|
152
|
+
build_option_type_options(opts, options, update_backup_option_types)
|
153
|
+
build_option_type_options(opts, options, update_backup_advanced_option_types)
|
154
|
+
build_standard_update_options(opts, options)
|
155
|
+
opts.footer = <<-EOT
|
156
|
+
Update a backup.
|
157
|
+
[backup] is required. This is the name or id of a backup.
|
158
|
+
EOT
|
159
|
+
end
|
160
|
+
optparse.parse!(args)
|
161
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
162
|
+
connect(options)
|
163
|
+
backup = find_backup_by_name_or_id(args[0])
|
164
|
+
return 1 if backup.nil?
|
165
|
+
payload = {}
|
166
|
+
if options[:payload]
|
167
|
+
payload = options[:payload]
|
168
|
+
payload.deep_merge!({'backup' => parse_passed_options(options)})
|
169
|
+
else
|
170
|
+
payload.deep_merge!({'backup' => parse_passed_options(options)})
|
171
|
+
# do not prompt on update
|
172
|
+
v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_backup_option_types, options[:options], @api_client, options[:params])
|
173
|
+
v_prompt.deep_compact!
|
174
|
+
params.deep_merge!(v_prompt)
|
175
|
+
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_backup_advanced_option_types, options[:options], @api_client, options[:params])
|
176
|
+
advanced_config.deep_compact!
|
177
|
+
params.deep_merge!(advanced_config)
|
178
|
+
payload.deep_merge!({'backup' => params})
|
179
|
+
if payload['backup'].empty? # || options[:no_prompt]
|
180
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
@backups_interface.setopts(options)
|
184
|
+
if options[:dry_run]
|
185
|
+
print_dry_run @backups_interface.dry.update(backup['id'], payload)
|
186
|
+
return
|
187
|
+
end
|
188
|
+
json_response = @backups_interface.update(backup['id'], payload)
|
189
|
+
backup = json_response['backup']
|
190
|
+
render_response(json_response, options, 'backup') do
|
191
|
+
print_green_success "Updated backup #{backup['name']}"
|
192
|
+
return _get(backup["id"], {}, options)
|
193
|
+
end
|
194
|
+
return 0, nil
|
195
|
+
end
|
196
|
+
|
197
|
+
def remove(args)
|
198
|
+
options = {}
|
199
|
+
params = {}
|
200
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
201
|
+
opts.banner = subcommand_usage("[backup] [options]")
|
202
|
+
build_standard_remove_options(opts, options)
|
203
|
+
opts.footer = <<-EOT
|
204
|
+
Delete a backup.
|
205
|
+
[backup] is required. This is the name or id of a backup.
|
206
|
+
EOT
|
207
|
+
end
|
208
|
+
optparse.parse!(args)
|
209
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
210
|
+
connect(options)
|
211
|
+
backup = find_backup_by_name_or_id(args[0])
|
212
|
+
return 1 if backup.nil?
|
213
|
+
@backups_interface.setopts(options)
|
214
|
+
if options[:dry_run]
|
215
|
+
print_dry_run @backups_interface.dry.destroy(backup['id'], params)
|
216
|
+
return
|
217
|
+
end
|
218
|
+
json_response = @backups_interface.destroy(backup['id'], params)
|
219
|
+
render_response(json_response, options) do
|
220
|
+
print_green_success "Removed backup #{backup['name']}"
|
221
|
+
end
|
222
|
+
return 0, nil
|
223
|
+
end
|
224
|
+
|
225
|
+
private
|
226
|
+
|
227
|
+
def backup_column_definitions()
|
228
|
+
{
|
229
|
+
"ID" => 'id',
|
230
|
+
"Name" => 'name',
|
231
|
+
"Schedule" => lambda {|it| it['schedule']['name'] rescue '' },
|
232
|
+
"Backup Job" => lambda {|it| it['job']['name'] rescue '' },
|
233
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
234
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
# this is not so simple, need to first choose select instance, host or provider
|
239
|
+
def add_backup_option_types
|
240
|
+
[
|
241
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
242
|
+
{'fieldName' => 'jobId', 'fieldLabel' => 'Backup Job', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
|
243
|
+
# @options_interface.options_for_source("licenseTypes", {})['data']
|
244
|
+
@backup_jobs_interface.list({max:10000})['backupJobs'].collect {|backup_job|
|
245
|
+
{'name' => backup_job['name'], 'value' => backup_job['id'], 'id' => backup_job['id']}
|
246
|
+
}
|
247
|
+
}, 'required' => true, 'displayOrder' => 3},
|
248
|
+
]
|
249
|
+
end
|
250
|
+
|
251
|
+
def add_backup_advanced_option_types
|
252
|
+
[]
|
253
|
+
end
|
254
|
+
|
255
|
+
def update_backup_option_types
|
256
|
+
add_backup_option_types.collect {|it|
|
257
|
+
it.delete('required')
|
258
|
+
it.delete('defaultValue')
|
259
|
+
it
|
260
|
+
}
|
261
|
+
end
|
262
|
+
|
263
|
+
def update_backup_advanced_option_types
|
264
|
+
add_backup_advanced_option_types.collect {|it|
|
265
|
+
it.delete('required')
|
266
|
+
it.delete('defaultValue')
|
267
|
+
it
|
268
|
+
}
|
269
|
+
end
|
270
|
+
|
271
|
+
end
|
@@ -279,7 +279,7 @@ class Morpheus::Cli::BootScriptsCommand
|
|
279
279
|
options = {}
|
280
280
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
281
281
|
opts.banner = subcommand_usage("[boot-script]")
|
282
|
-
build_common_options(opts, options, [:
|
282
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
283
283
|
end
|
284
284
|
optparse.parse!(args)
|
285
285
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'json'
|
3
|
+
require 'fileutils'
|
3
4
|
require 'morpheus/logging'
|
4
5
|
require 'morpheus/benchmarking'
|
5
6
|
require 'morpheus/cli/option_parser'
|
@@ -232,11 +233,11 @@ module Morpheus
|
|
232
233
|
## the standard options for a command that makes api requests (most of them)
|
233
234
|
|
234
235
|
def build_standard_get_options(opts, options, includes=[], excludes=[])
|
235
|
-
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :quiet, :dry_run, :remote]
|
236
|
+
build_common_options(opts, options, includes + [:query, :json, :yaml, :csv, :fields, :quiet, :dry_run, :remote], excludes)
|
236
237
|
end
|
237
238
|
|
238
239
|
def build_standard_post_options(opts, options, includes=[], excludes=[])
|
239
|
-
build_common_options(opts, options, [:options, :payload, :json, :quiet, :dry_run, :remote]
|
240
|
+
build_common_options(opts, options, includes + [:options, :payload, :json, :quiet, :dry_run, :remote], excludes)
|
240
241
|
end
|
241
242
|
|
242
243
|
def build_standard_put_options(opts, options, includes=[], excludes=[])
|
@@ -244,7 +245,7 @@ module Morpheus
|
|
244
245
|
end
|
245
246
|
|
246
247
|
def build_standard_delete_options(opts, options, includes=[], excludes=[])
|
247
|
-
build_common_options(opts, options, [:auto_confirm, :query, :json, :quiet, :dry_run, :remote]
|
248
|
+
build_common_options(opts, options, includes + [:auto_confirm, :query, :json, :quiet, :dry_run, :remote], excludes)
|
248
249
|
end
|
249
250
|
|
250
251
|
# list is GET that supports phrase,max,offset,sort,direction
|
@@ -285,13 +286,24 @@ module Morpheus
|
|
285
286
|
while (option_key = option_keys.shift) do
|
286
287
|
case option_key.to_sym
|
287
288
|
|
288
|
-
when :account
|
289
|
-
|
289
|
+
when :tenant, :account
|
290
|
+
# todo: let's deprecate this in favor of :tenant --tenant to keep -a reserved for --all perhaps?
|
291
|
+
opts.on('--tenant TENANT', String, "Tenant (Account) Name or ID") do |val|
|
290
292
|
options[:account] = val
|
291
293
|
end
|
292
|
-
opts.on('
|
294
|
+
opts.on('--tenant-id ID', String, "Tenant (Account) ID") do |val|
|
293
295
|
options[:account_id] = val
|
294
296
|
end
|
297
|
+
# todo: let's deprecate this in favor of :tenant --tenant to keep -a reserved for --all perhaps?
|
298
|
+
opts.on('-a','--account ACCOUNT', "Alias for --tenant") do |val|
|
299
|
+
options[:account] = val
|
300
|
+
end
|
301
|
+
opts.on('-A','--account-id ID', "Tenant (Account) ID") do |val|
|
302
|
+
options[:account_id] = val
|
303
|
+
end
|
304
|
+
opts.add_hidden_option('--tenant-id') if opts.is_a?(Morpheus::Cli::OptionParser)
|
305
|
+
opts.add_hidden_option('-a, --account') if opts.is_a?(Morpheus::Cli::OptionParser)
|
306
|
+
opts.add_hidden_option('-A, --account-id') if opts.is_a?(Morpheus::Cli::OptionParser)
|
295
307
|
|
296
308
|
when :options
|
297
309
|
options[:options] ||= {}
|
@@ -459,7 +471,7 @@ module Morpheus
|
|
459
471
|
end
|
460
472
|
|
461
473
|
# arbitrary query parameters in the format -Q "category=web&phrase=nginx"
|
462
|
-
# opts.on( '-Q', '--query PARAMS', "Query parameters. PARAMS format is '
|
474
|
+
# opts.on( '-Q', '--query PARAMS', "Query parameters. PARAMS format is 'foo=bar&category=web'" ) do |val|
|
463
475
|
# options[:query_filters_raw] = val
|
464
476
|
# options[:query_filters] = {}
|
465
477
|
# # todo: smarter parsing
|
@@ -477,7 +489,7 @@ module Morpheus
|
|
477
489
|
|
478
490
|
when :query, :query_filters
|
479
491
|
# arbitrary query parameters in the format -Q "category=web&phrase=nginx"
|
480
|
-
opts.on( '-Q', '--query PARAMS', "Query parameters. PARAMS format is '
|
492
|
+
opts.on( '-Q', '--query PARAMS', "Query parameters. PARAMS format is 'foo=bar&category=web'" ) do |val|
|
481
493
|
options[:query_filters_raw] = val
|
482
494
|
options[:query_filters] = {}
|
483
495
|
# todo: smarter parsing
|
@@ -603,9 +615,17 @@ module Morpheus
|
|
603
615
|
opts.add_hidden_option('json-raw') if opts.is_a?(Morpheus::Cli::OptionParser)
|
604
616
|
|
605
617
|
when :yaml
|
606
|
-
|
607
|
-
|
608
|
-
|
618
|
+
# -y for --yes and for --yaml
|
619
|
+
if includes.include?(:auto_confirm)
|
620
|
+
opts.on(nil, '--yaml', "YAML Output") do
|
621
|
+
options[:yaml] = true
|
622
|
+
options[:format] = :yaml
|
623
|
+
end
|
624
|
+
else
|
625
|
+
opts.on('-y', '--yaml', "YAML Output") do
|
626
|
+
options[:yaml] = true
|
627
|
+
options[:format] = :yaml
|
628
|
+
end
|
609
629
|
end
|
610
630
|
opts.on(nil, '--yml', "alias for --yaml") do
|
611
631
|
options[:yaml] = true
|
@@ -783,7 +803,11 @@ module Morpheus
|
|
783
803
|
end
|
784
804
|
opts.add_hidden_option('--no-debug') if opts.is_a?(Morpheus::Cli::OptionParser)
|
785
805
|
|
786
|
-
|
806
|
+
opts.on('--hidden-help', "Print help that includes all the hidden options, like this one." ) do
|
807
|
+
puts opts.full_help_message({show_hidden_options:true})
|
808
|
+
exit # return 0 maybe?
|
809
|
+
end
|
810
|
+
opts.add_hidden_option('--hidden-help') if opts.is_a?(Morpheus::Cli::OptionParser)
|
787
811
|
opts.on('-h', '--help', "Print this help" ) do
|
788
812
|
puts opts
|
789
813
|
exit # return 0 maybe?
|
@@ -1011,7 +1035,7 @@ module Morpheus
|
|
1011
1035
|
# raise_command_error "Please specify a remote appliance with -r or see the command `remote use`"
|
1012
1036
|
# end
|
1013
1037
|
|
1014
|
-
Morpheus::Logging::DarkPrinter.puts "establishing connection to remote #{display_appliance(@appliance_name, @appliance_url)}" if Morpheus::Logging.debug?
|
1038
|
+
Morpheus::Logging::DarkPrinter.puts "establishing connection to remote #{display_appliance(@appliance_name, @appliance_url)}" if Morpheus::Logging.debug? # && !options[:quiet]
|
1015
1039
|
|
1016
1040
|
if options[:no_authorization]
|
1017
1041
|
# maybe handle this here..
|
@@ -1082,7 +1106,7 @@ module Morpheus
|
|
1082
1106
|
else
|
1083
1107
|
if opts[:min]
|
1084
1108
|
if args.count < opts[:min]
|
1085
|
-
raise_args_error("not
|
1109
|
+
raise_args_error("not enough arguments, expected #{opts[:min] || '0'}-#{opts[:max] || 'N'} and got #{args.count == 0 ? '0' : args.count.to_s + ': '}#{args.join(', ')}", args, opts[:optparse])
|
1086
1110
|
end
|
1087
1111
|
end
|
1088
1112
|
if opts[:max]
|
@@ -1173,22 +1197,32 @@ module Morpheus
|
|
1173
1197
|
payload
|
1174
1198
|
end
|
1175
1199
|
|
1176
|
-
def
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1200
|
+
def validate_outfile(outfile, options)
|
1201
|
+
full_filename = File.expand_path(outfile)
|
1202
|
+
outdir = File.dirname(full_filename)
|
1203
|
+
if Dir.exists?(full_filename)
|
1204
|
+
print_red_alert "[local-file] is invalid. It is the name of an existing directory: #{outfile}"
|
1205
|
+
return false
|
1206
|
+
end
|
1207
|
+
if !Dir.exists?(outdir)
|
1208
|
+
if options[:mkdir]
|
1209
|
+
print cyan,"Creating local directory #{outdir}",reset,"\n"
|
1210
|
+
FileUtils.mkdir_p(outdir)
|
1183
1211
|
else
|
1184
|
-
|
1212
|
+
print_red_alert "[local-file] is invalid. Directory not found: #{outdir}"
|
1213
|
+
return false
|
1185
1214
|
end
|
1186
1215
|
end
|
1216
|
+
if File.exists?(full_filename) && !options[:overwrite]
|
1217
|
+
print_red_alert "[local-file] is invalid. File already exists: #{outfile}\nUse -f to overwrite the existing file."
|
1218
|
+
return false
|
1219
|
+
end
|
1220
|
+
return true
|
1187
1221
|
end
|
1188
1222
|
|
1189
1223
|
# basic rendering for options :json, :yml, :csv, :quiet, and :outfile
|
1190
1224
|
# returns the string rendered, or nil if nothing was rendered.
|
1191
|
-
def
|
1225
|
+
def render_response(json_response, options, object_key=nil, &block)
|
1192
1226
|
output = nil
|
1193
1227
|
if options[:json]
|
1194
1228
|
output = as_json(json_response, options, object_key)
|
@@ -1201,32 +1235,49 @@ module Morpheus
|
|
1201
1235
|
else
|
1202
1236
|
output = records_as_csv([row], options)
|
1203
1237
|
end
|
1204
|
-
elsif options[:quiet]
|
1205
|
-
# note: returning non nil means the calling function knows to return rght away.. kinda weird..
|
1206
|
-
# but means we need less if options[:quiet] blocks in every action.
|
1207
|
-
return ""
|
1208
1238
|
end
|
1209
|
-
if
|
1210
|
-
if
|
1239
|
+
if options[:outfile]
|
1240
|
+
if output
|
1211
1241
|
print_to_file(output, options[:outfile], options[:overwrite])
|
1242
|
+
print "#{cyan}Wrote output to file #{options[:outfile]} (#{File.size(options[:outfile])} B)\n" unless options[:quiet]
|
1212
1243
|
else
|
1213
|
-
|
1244
|
+
# uhhh ok lets try this
|
1245
|
+
Morpheus::Logging::DarkPrinter.puts "using experimental feature: --outfile without a common format like json, yml or csv" if Morpheus::Logging.debug?
|
1246
|
+
result = with_stdout_to_file(options[:outfile], options[:overwrite], 'w+', &block)
|
1247
|
+
print "#{cyan}Wrote output to file #{options[:outfile]} (#{File.size(options[:outfile])} B)\n" unless options[:quiet]
|
1248
|
+
if result
|
1249
|
+
return result
|
1250
|
+
end
|
1251
|
+
return 0, nil
|
1214
1252
|
end
|
1215
1253
|
else
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1254
|
+
# --quiet means do not render, still want to print to outfile though
|
1255
|
+
if options[:quiet]
|
1256
|
+
return 0, nil
|
1257
|
+
end
|
1258
|
+
# render ouput generated above
|
1259
|
+
if output
|
1260
|
+
puts output
|
1261
|
+
return 0, nil
|
1262
|
+
else
|
1263
|
+
# no render happened, so calling the block if given
|
1264
|
+
if block_given?
|
1265
|
+
result = yield
|
1266
|
+
if result
|
1267
|
+
return result
|
1268
|
+
else
|
1269
|
+
return 0, nil
|
1270
|
+
end
|
1271
|
+
else
|
1272
|
+
# nil means nothing was rendered, some methods still using render_with_format() are relying on this
|
1273
|
+
return nil
|
1274
|
+
end
|
1275
|
+
end
|
1226
1276
|
end
|
1227
|
-
return output
|
1228
1277
|
end
|
1229
1278
|
|
1279
|
+
alias :render_with_format :render_response
|
1280
|
+
|
1230
1281
|
module ClassMethods
|
1231
1282
|
|
1232
1283
|
def set_command_name(cmd_name)
|