morpheus-cli 4.2.16 → 4.2.17
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/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)
|