morpheus-cli 5.5.2.1 → 5.5.3
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/.gitignore +2 -1
- data/Dockerfile +1 -1
- data/README.md +57 -4
- data/Rakefile +9 -0
- data/bin/morpheus +4 -4
- data/lib/morpheus/api/api_client.rb +8 -2
- data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
- data/lib/morpheus/api/archive_files_interface.rb +3 -3
- data/lib/morpheus/api/clients_interface.rb +2 -2
- data/lib/morpheus/api/clusters_interface.rb +8 -1
- data/lib/morpheus/api/containers_interface.rb +29 -16
- data/lib/morpheus/api/custom_instance_types_interface.rb +0 -2
- data/lib/morpheus/api/doc_interface.rb +8 -6
- data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
- data/lib/morpheus/api/health_interface.rb +1 -1
- data/lib/morpheus/api/image_builder_interface.rb +3 -3
- data/lib/morpheus/api/instances_interface.rb +25 -0
- data/lib/morpheus/api/logs_interface.rb +2 -4
- data/lib/morpheus/api/monitoring_interface.rb +6 -6
- data/lib/morpheus/api/packages_interface.rb +1 -1
- data/lib/morpheus/api/reports_interface.rb +1 -1
- data/lib/morpheus/api/servers_interface.rb +9 -1
- data/lib/morpheus/api/storage_providers_interface.rb +2 -2
- data/lib/morpheus/api/virtual_images_interface.rb +1 -1
- data/lib/morpheus/api.rb +2 -0
- data/lib/morpheus/benchmarking.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +69 -36
- data/lib/morpheus/cli/cli_registry.rb +19 -10
- data/lib/morpheus/cli/commands/access_token_command.rb +1 -1
- data/lib/morpheus/cli/commands/apps.rb +1 -1
- data/lib/morpheus/cli/commands/archives_command.rb +25 -33
- data/lib/morpheus/cli/commands/blueprints_command.rb +10 -21
- data/lib/morpheus/cli/commands/boot_scripts_command.rb +2 -2
- data/lib/morpheus/cli/commands/cat_command.rb +1 -1
- data/lib/morpheus/cli/commands/catalog_item_types_command.rb +12 -12
- data/lib/morpheus/cli/commands/clouds.rb +3 -3
- data/lib/morpheus/cli/commands/clusters.rb +154 -3
- data/lib/morpheus/cli/commands/containers_command.rb +398 -253
- data/lib/morpheus/cli/commands/deployments.rb +1 -1
- data/lib/morpheus/cli/commands/deploys.rb +9 -9
- data/lib/morpheus/cli/commands/doc.rb +15 -16
- data/lib/morpheus/cli/commands/execution_request_command.rb +2 -2
- data/lib/morpheus/cli/commands/file_copy_request_command.rb +5 -5
- data/lib/morpheus/cli/commands/groups.rb +2 -2
- data/lib/morpheus/cli/commands/health_command.rb +4 -4
- data/lib/morpheus/cli/commands/hosts.rb +43 -5
- data/lib/morpheus/cli/commands/image_builder_command.rb +1 -1
- data/lib/morpheus/cli/commands/instances.rb +419 -148
- data/lib/morpheus/cli/commands/integrations_command.rb +22 -20
- data/lib/morpheus/cli/commands/key_pairs.rb +2 -2
- data/lib/morpheus/cli/commands/library_container_scripts_command.rb +2 -2
- data/lib/morpheus/cli/commands/library_container_templates_command.rb +2 -2
- data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -3
- data/lib/morpheus/cli/commands/library_spec_templates_command.rb +2 -2
- data/lib/morpheus/cli/commands/login.rb +1 -1
- data/lib/morpheus/cli/commands/man_command.rb +32 -18
- data/lib/morpheus/cli/commands/packages_command.rb +11 -11
- data/lib/morpheus/cli/commands/plugins.rb +1 -1
- data/lib/morpheus/cli/commands/policies_command.rb +4 -4
- data/lib/morpheus/cli/commands/preseed_scripts_command.rb +2 -2
- data/lib/morpheus/cli/commands/remote.rb +1 -1
- data/lib/morpheus/cli/commands/reports_command.rb +3 -3
- data/lib/morpheus/cli/commands/roles.rb +6 -3
- data/lib/morpheus/cli/commands/security_groups.rb +1 -1
- data/lib/morpheus/cli/commands/shell.rb +40 -62
- data/lib/morpheus/cli/commands/snapshots.rb +3 -5
- data/lib/morpheus/cli/commands/source_command.rb +8 -16
- data/lib/morpheus/cli/commands/storage_providers_command.rb +7 -7
- data/lib/morpheus/cli/commands/tasks.rb +2 -2
- data/lib/morpheus/cli/commands/vdi_pools_command.rb +6 -6
- data/lib/morpheus/cli/commands/view.rb +5 -1
- data/lib/morpheus/cli/commands/whitelabel_settings_command.rb +4 -4
- data/lib/morpheus/cli/commands/whoami.rb +2 -2
- data/lib/morpheus/cli/credentials.rb +30 -8
- data/lib/morpheus/cli/dot_file.rb +8 -15
- data/lib/morpheus/cli/error_handler.rb +16 -0
- data/lib/morpheus/cli/errors.rb +8 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +17 -13
- data/lib/morpheus/cli/mixins/rest_command.rb +18 -18
- data/lib/morpheus/cli/mixins/secondary_rest_command.rb +12 -12
- data/lib/morpheus/cli/option_parser.rb +5 -1
- data/lib/morpheus/cli/option_types.rb +59 -12
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli.rb +26 -16
- data/lib/morpheus/ext/rest_client.rb +3 -2
- data/lib/morpheus/formatters.rb +1 -1
- data/lib/morpheus/logging.rb +4 -4
- data/lib/morpheus/morpkg.rb +4 -4
- data/lib/morpheus/rest_client.rb +2 -2
- data/lib/morpheus/routes.rb +2 -2
- data/lib/morpheus/terminal.rb +65 -16
- data/lib/morpheus.rb +1 -1
- data/morpheus-cli.gemspec +1 -0
- data/test/api/containers_interface_test.rb +68 -0
- data/test/api/doc_interface_test.rb +35 -0
- data/test/api/instances_interface_test.rb +22 -0
- data/test/api/whoami_interface_test.rb +14 -0
- data/test/cli/access_token_test.rb +36 -0
- data/test/cli/auth_test.rb +82 -0
- data/test/cli/cli_test.rb +48 -0
- data/test/cli/containers_test.rb +92 -0
- data/test/cli/doc_test.rb +35 -0
- data/test/cli/help_test.rb +25 -0
- data/test/cli/instances_test.rb +36 -0
- data/test/cli/man_test.rb +14 -0
- data/test/cli/remote_test.rb +89 -0
- data/test/cli/roles_test.rb +34 -0
- data/test/cli/shell_test.rb +81 -0
- data/test/cli/version_test.rb +23 -0
- data/test/cli/view_test.rb +55 -0
- data/test/cli/whoami_test.rb +17 -0
- data/test/morpheus_test.rb +16 -0
- data/test/test_case.rb +338 -0
- data/test/test_config.rb +137 -0
- data/test/test_data_helper.rb +97 -0
- metadata +61 -3
|
@@ -144,7 +144,7 @@ module Morpheus::Cli::PrintHelper
|
|
|
144
144
|
data = {}
|
|
145
145
|
begin
|
|
146
146
|
data = JSON.parse(e.response.to_s)
|
|
147
|
-
rescue
|
|
147
|
+
rescue
|
|
148
148
|
# Morpheus::Logging::DarkPrinter.puts "Failed to parse error response as JSON: #{ex}" if Morpheus::Logging.debug?
|
|
149
149
|
end
|
|
150
150
|
return data
|
|
@@ -1329,19 +1329,19 @@ module Morpheus::Cli::PrintHelper
|
|
|
1329
1329
|
outfile = nil
|
|
1330
1330
|
begin
|
|
1331
1331
|
full_filename = File.expand_path(filename)
|
|
1332
|
-
if File.
|
|
1332
|
+
if File.exist?(full_filename)
|
|
1333
1333
|
if !overwrite
|
|
1334
1334
|
print "#{red}Output file '#{filename}' already exists.#{reset}\n"
|
|
1335
1335
|
print "#{red}Use --overwrite to overwrite the existing file.#{reset}\n"
|
|
1336
1336
|
return 1
|
|
1337
1337
|
end
|
|
1338
1338
|
end
|
|
1339
|
-
if Dir.
|
|
1339
|
+
if Dir.exist?(full_filename)
|
|
1340
1340
|
print "#{red}Output file '#{filename}' is invalid. It is the name of an existing directory.#{reset}\n"
|
|
1341
1341
|
return 1
|
|
1342
1342
|
end
|
|
1343
1343
|
target_dir = File.dirname(full_filename)
|
|
1344
|
-
if !Dir.
|
|
1344
|
+
if !Dir.exist?(target_dir)
|
|
1345
1345
|
FileUtils.mkdir_p(target_dir)
|
|
1346
1346
|
end
|
|
1347
1347
|
outfile = File.open(full_filename, access_mode)
|
|
@@ -1362,19 +1362,19 @@ module Morpheus::Cli::PrintHelper
|
|
|
1362
1362
|
outfile = nil
|
|
1363
1363
|
begin
|
|
1364
1364
|
full_filename = File.expand_path(filename)
|
|
1365
|
-
if File.
|
|
1365
|
+
if File.exist?(full_filename)
|
|
1366
1366
|
if !overwrite
|
|
1367
1367
|
print "#{red}Output file '#{filename}' already exists.#{reset}\n"
|
|
1368
1368
|
print "#{red}Use --overwrite to overwrite the existing file.#{reset}\n"
|
|
1369
1369
|
return 1
|
|
1370
1370
|
end
|
|
1371
1371
|
end
|
|
1372
|
-
if Dir.
|
|
1372
|
+
if Dir.exist?(full_filename)
|
|
1373
1373
|
print "#{red}Output file '#{filename}' is invalid. It is the name of an existing directory.#{reset}\n"
|
|
1374
1374
|
return 1
|
|
1375
1375
|
end
|
|
1376
1376
|
target_dir = File.dirname(full_filename)
|
|
1377
|
-
if !Dir.
|
|
1377
|
+
if !Dir.exist?(target_dir)
|
|
1378
1378
|
FileUtils.mkdir_p(target_dir)
|
|
1379
1379
|
end
|
|
1380
1380
|
outfile = File.open(full_filename, access_mode)
|
|
@@ -1402,13 +1402,17 @@ module Morpheus::Cli::PrintHelper
|
|
|
1402
1402
|
end
|
|
1403
1403
|
end
|
|
1404
1404
|
|
|
1405
|
-
def format_percent(val, sig_dig=2)
|
|
1405
|
+
def format_percent(val, sig_dig=2, hide_zero=false)
|
|
1406
1406
|
if val.nil?
|
|
1407
1407
|
return ""
|
|
1408
1408
|
end
|
|
1409
1409
|
percent_value = val.to_f
|
|
1410
1410
|
if percent_value == 0
|
|
1411
|
-
|
|
1411
|
+
if hide_zero
|
|
1412
|
+
""
|
|
1413
|
+
else
|
|
1414
|
+
return "0%"
|
|
1415
|
+
end
|
|
1412
1416
|
else
|
|
1413
1417
|
return percent_value.round(sig_dig).to_s + "%"
|
|
1414
1418
|
end
|
|
@@ -1431,8 +1435,8 @@ module Morpheus::Cli::PrintHelper
|
|
|
1431
1435
|
|
|
1432
1436
|
# convert JSON or YAML string to a map
|
|
1433
1437
|
def parse_json_or_yaml(config, parsers = [:json, :yaml])
|
|
1434
|
-
rtn = {success: false, data: nil,
|
|
1435
|
-
|
|
1438
|
+
rtn = {success: false, data: nil, error: nil}
|
|
1439
|
+
error = nil
|
|
1436
1440
|
config = config.strip
|
|
1437
1441
|
if config[0..2] == "---"
|
|
1438
1442
|
parsers = [:yaml]
|
|
@@ -1455,7 +1459,7 @@ module Morpheus::Cli::PrintHelper
|
|
|
1455
1459
|
rtn[:success] = true
|
|
1456
1460
|
break
|
|
1457
1461
|
rescue => ex
|
|
1458
|
-
rtn[:
|
|
1462
|
+
rtn[:error] = ex if rtn[:error].nil?
|
|
1459
1463
|
end
|
|
1460
1464
|
elsif parser == :json
|
|
1461
1465
|
begin
|
|
@@ -1464,7 +1468,7 @@ module Morpheus::Cli::PrintHelper
|
|
|
1464
1468
|
rtn[:success] = true
|
|
1465
1469
|
break
|
|
1466
1470
|
rescue => ex
|
|
1467
|
-
rtn[:
|
|
1471
|
+
rtn[:error] = ex if rtn[:error].nil?
|
|
1468
1472
|
end
|
|
1469
1473
|
end
|
|
1470
1474
|
end
|
|
@@ -43,7 +43,7 @@ module Morpheus::Cli::RestCommand
|
|
|
43
43
|
# It is used to derive all other default rest settings key, label, etc.
|
|
44
44
|
# The default name the command name with underscores `_` instead of dashes `-`.
|
|
45
45
|
def rest_name
|
|
46
|
-
@rest_name
|
|
46
|
+
defined?(@rest_name) ? @rest_name : default_rest_name
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def default_rest_name
|
|
@@ -58,7 +58,7 @@ module Morpheus::Cli::RestCommand
|
|
|
58
58
|
|
|
59
59
|
# rest_key is the singular name of the resource eg. "neat_thing"
|
|
60
60
|
def rest_key
|
|
61
|
-
@rest_key
|
|
61
|
+
defined?(@rest_key) ? @rest_key : default_rest_key
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def default_rest_key
|
|
@@ -73,7 +73,7 @@ module Morpheus::Cli::RestCommand
|
|
|
73
73
|
|
|
74
74
|
# rest_arg is a label for the arg in the command usage eg. "thing" gets displayed as [thing]
|
|
75
75
|
def rest_arg
|
|
76
|
-
@rest_arg
|
|
76
|
+
defined?(@rest_arg) ? @rest_arg : default_rest_arg
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def default_rest_arg
|
|
@@ -89,7 +89,7 @@ module Morpheus::Cli::RestCommand
|
|
|
89
89
|
# rest_has_name indicates a resource has a name and can be retrieved by name or id
|
|
90
90
|
# true by default, set to false for lookups by only id
|
|
91
91
|
def rest_has_name
|
|
92
|
-
@rest_has_name
|
|
92
|
+
defined?(@rest_has_name) ? @rest_has_name : default_rest_has_name
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def default_rest_has_name
|
|
@@ -104,7 +104,7 @@ module Morpheus::Cli::RestCommand
|
|
|
104
104
|
|
|
105
105
|
# rest_label is the capitalized resource label eg. "Neat Thing"
|
|
106
106
|
def rest_label
|
|
107
|
-
@rest_label
|
|
107
|
+
defined?(@rest_label) ? @rest_label : default_rest_label
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def default_rest_label
|
|
@@ -119,7 +119,7 @@ module Morpheus::Cli::RestCommand
|
|
|
119
119
|
|
|
120
120
|
# the plural version of the label eg. "Neat Things"
|
|
121
121
|
def rest_label_plural
|
|
122
|
-
@rest_label_plural
|
|
122
|
+
defined?(@rest_label_plural) ? @rest_label_plural : default_rest_label_plural
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def default_rest_label_plural
|
|
@@ -135,7 +135,7 @@ module Morpheus::Cli::RestCommand
|
|
|
135
135
|
|
|
136
136
|
# rest_interface_name is the interface name for the resource. eg. "neat_things"
|
|
137
137
|
def rest_interface_name
|
|
138
|
-
@rest_interface_name
|
|
138
|
+
defined?(@rest_interface_name) ? @rest_interface_name : default_rest_interface_name
|
|
139
139
|
end
|
|
140
140
|
|
|
141
141
|
def default_rest_interface_name
|
|
@@ -150,7 +150,7 @@ module Morpheus::Cli::RestCommand
|
|
|
150
150
|
|
|
151
151
|
# rest_perms_config enables and configures permissions prompt
|
|
152
152
|
def rest_perms_config
|
|
153
|
-
@rest_perms_config
|
|
153
|
+
defined?(@rest_perms_config) ? @rest_perms_config : {}
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
def rest_perms_config=(v)
|
|
@@ -161,7 +161,7 @@ module Morpheus::Cli::RestCommand
|
|
|
161
161
|
|
|
162
162
|
# rest_option_context_map specifies context mapping during option prompt. default is domain => ''
|
|
163
163
|
def rest_option_context_map
|
|
164
|
-
@option_context_map
|
|
164
|
+
defined?(@option_context_map) ? @option_context_map : {'domain' => ''}
|
|
165
165
|
end
|
|
166
166
|
|
|
167
167
|
def rest_option_context_map=(v)
|
|
@@ -172,7 +172,7 @@ module Morpheus::Cli::RestCommand
|
|
|
172
172
|
|
|
173
173
|
# rest_has_type indicates a resource has a type. default is false
|
|
174
174
|
def rest_has_type
|
|
175
|
-
@rest_has_type
|
|
175
|
+
defined?(@rest_has_type) && @rest_has_type
|
|
176
176
|
end
|
|
177
177
|
|
|
178
178
|
def default_rest_has_type
|
|
@@ -189,7 +189,7 @@ module Morpheus::Cli::RestCommand
|
|
|
189
189
|
|
|
190
190
|
# rest_type_name is the rest_name for the type, only applicable if rest_has_type
|
|
191
191
|
def rest_type_name
|
|
192
|
-
@rest_type_name
|
|
192
|
+
defined?(@rest_type_name) ? @rest_type_name : default_rest_type_name
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
def default_rest_type_name
|
|
@@ -206,7 +206,7 @@ module Morpheus::Cli::RestCommand
|
|
|
206
206
|
|
|
207
207
|
# rest_type_key is the singular name of the resource eg. "neat_thing"
|
|
208
208
|
def rest_type_key
|
|
209
|
-
@rest_type_key
|
|
209
|
+
defined?(@rest_type_key) ? @rest_type_key : default_rest_type_key
|
|
210
210
|
end
|
|
211
211
|
|
|
212
212
|
def default_rest_type_key
|
|
@@ -220,7 +220,7 @@ module Morpheus::Cli::RestCommand
|
|
|
220
220
|
alias :set_rest_type_key :rest_type_key=
|
|
221
221
|
|
|
222
222
|
def rest_type_arg
|
|
223
|
-
@rest_type_arg
|
|
223
|
+
defined?(@rest_type_arg) ? @rest_type_arg : default_rest_type_arg
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
def default_rest_type_arg
|
|
@@ -236,7 +236,7 @@ module Morpheus::Cli::RestCommand
|
|
|
236
236
|
|
|
237
237
|
# rest_type_label is the capitalized resource label eg. "Neat Thing"
|
|
238
238
|
def rest_type_label
|
|
239
|
-
@rest_type_label
|
|
239
|
+
defined?(@rest_type_label) ? @rest_type_label : default_rest_type_label
|
|
240
240
|
end
|
|
241
241
|
|
|
242
242
|
def default_rest_type_label
|
|
@@ -251,7 +251,7 @@ module Morpheus::Cli::RestCommand
|
|
|
251
251
|
|
|
252
252
|
# the plural version of the label eg. "Neat Things"
|
|
253
253
|
def rest_type_label_plural
|
|
254
|
-
@rest_type_label_plural
|
|
254
|
+
defined?(@rest_type_label_plural) ? @rest_type_label_plural : default_rest_type_label_plural
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
def default_rest_type_label_plural
|
|
@@ -267,7 +267,7 @@ module Morpheus::Cli::RestCommand
|
|
|
267
267
|
|
|
268
268
|
# the name of the default interface, matches the rest name eg. "neat_things"
|
|
269
269
|
def rest_type_interface_name
|
|
270
|
-
@rest_type_interface_name
|
|
270
|
+
defined?(@rest_type_interface_name) ? @rest_type_interface_name : default_rest_type_interface_name
|
|
271
271
|
end
|
|
272
272
|
|
|
273
273
|
def default_rest_type_interface_name
|
|
@@ -742,7 +742,6 @@ EOT
|
|
|
742
742
|
end
|
|
743
743
|
|
|
744
744
|
def update(args)
|
|
745
|
-
id = args[0]
|
|
746
745
|
record_type = nil
|
|
747
746
|
record_type_id = nil
|
|
748
747
|
options = {}
|
|
@@ -762,6 +761,7 @@ EOT
|
|
|
762
761
|
optparse.parse!(args)
|
|
763
762
|
verify_args!(args:args, optparse:optparse, count:1)
|
|
764
763
|
connect(options)
|
|
764
|
+
id = args[0]
|
|
765
765
|
record = rest_find_by_name_or_id(id)
|
|
766
766
|
if record.nil?
|
|
767
767
|
return 1, "#{rest_name} not found for '#{id}'"
|
|
@@ -857,7 +857,6 @@ EOT
|
|
|
857
857
|
end
|
|
858
858
|
|
|
859
859
|
def remove(args)
|
|
860
|
-
id = args[0]
|
|
861
860
|
params = {}
|
|
862
861
|
options = {}
|
|
863
862
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
@@ -872,6 +871,7 @@ EOT
|
|
|
872
871
|
verify_args!(args:args, optparse:optparse, count:1)
|
|
873
872
|
connect(options)
|
|
874
873
|
params.merge!(parse_query_options(options))
|
|
874
|
+
id = args[0]
|
|
875
875
|
record = rest_find_by_name_or_id(id)
|
|
876
876
|
if record.nil?
|
|
877
877
|
return 1, "#{rest_name} not found for '#{id}'"
|
|
@@ -33,7 +33,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
33
33
|
|
|
34
34
|
# rest_parent_name is the rest_name for the parent
|
|
35
35
|
def rest_parent_name
|
|
36
|
-
@rest_parent_name
|
|
36
|
+
defined?(@rest_parent_name) ? @rest_parent_name : default_rest_parent_name
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def default_rest_parent_name
|
|
@@ -58,7 +58,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
58
58
|
|
|
59
59
|
# rest_parent_key is the singular name of the resource eg. "neat_thing"
|
|
60
60
|
def rest_parent_key
|
|
61
|
-
@rest_parent_key
|
|
61
|
+
defined?(@rest_parent_key) ? @rest_parent_key : default_rest_parent_key
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def default_rest_parent_key
|
|
@@ -72,7 +72,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
72
72
|
alias :set_rest_parent_key :rest_parent_key=
|
|
73
73
|
|
|
74
74
|
def rest_parent_arg
|
|
75
|
-
@rest_parent_arg
|
|
75
|
+
defined?(@rest_parent_arg) ? @rest_parent_arg : default_rest_parent_arg
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def default_rest_parent_arg
|
|
@@ -86,7 +86,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
86
86
|
alias :set_rest_parent_arg :rest_parent_arg=
|
|
87
87
|
|
|
88
88
|
def rest_parent_param
|
|
89
|
-
@rest_parent_param
|
|
89
|
+
defined?(@rest_parent_param) ? @rest_parent_param : default_rest_parent_param
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
def default_rest_parent_param
|
|
@@ -103,7 +103,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
103
103
|
# rest_parent_has_name indicates a resource has a name and can be retrieved by name or id
|
|
104
104
|
# true by default, set to false for lookups by only id
|
|
105
105
|
def rest_parent_has_name
|
|
106
|
-
@rest_parent_has_name
|
|
106
|
+
defined?(@rest_parent_has_name) ? @rest_parent_has_name : default_rest_parent_has_name
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def default_rest_parent_has_name
|
|
@@ -118,7 +118,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
118
118
|
|
|
119
119
|
# rest_parent_label is the capitalized resource label eg. "Neat Thing"
|
|
120
120
|
def rest_parent_label
|
|
121
|
-
@rest_parent_label
|
|
121
|
+
defined?(@rest_parent_label) ? @rest_parent_label : default_rest_parent_label
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
def default_rest_parent_label
|
|
@@ -133,7 +133,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
133
133
|
|
|
134
134
|
# the plural version of the label eg. "Neat Things"
|
|
135
135
|
def rest_parent_label_plural
|
|
136
|
-
@rest_parent_label_plural
|
|
136
|
+
defined?(@rest_parent_label_plural) ? @rest_parent_label_plural : default_rest_parent_label_plural
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
def default_rest_parent_label_plural
|
|
@@ -149,7 +149,7 @@ module Morpheus::Cli::SecondaryRestCommand
|
|
|
149
149
|
|
|
150
150
|
# the name of the default interface, matches the rest name eg. "neat_things"
|
|
151
151
|
def rest_parent_interface_name
|
|
152
|
-
@rest_parent_interface_name
|
|
152
|
+
defined?(@rest_parent_interface_name) ? @rest_parent_interface_name : default_rest_parent_interface_name
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
def default_rest_parent_interface_name
|
|
@@ -514,8 +514,6 @@ EOT
|
|
|
514
514
|
end
|
|
515
515
|
|
|
516
516
|
def update(args)
|
|
517
|
-
parent_id = args[0]
|
|
518
|
-
id = args[1]
|
|
519
517
|
record_type = nil
|
|
520
518
|
record_type_id = nil
|
|
521
519
|
options = {}
|
|
@@ -533,6 +531,8 @@ EOT
|
|
|
533
531
|
optparse.parse!(args)
|
|
534
532
|
verify_args!(args:args, optparse:optparse, count:2)
|
|
535
533
|
connect(options)
|
|
534
|
+
parent_id = args[0]
|
|
535
|
+
id = args[1]
|
|
536
536
|
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
|
537
537
|
if parent_record.nil?
|
|
538
538
|
return 1, "#{rest_parent_label} not found for '#{parent_id}"
|
|
@@ -633,8 +633,6 @@ EOT
|
|
|
633
633
|
end
|
|
634
634
|
|
|
635
635
|
def remove(args)
|
|
636
|
-
parent_id = args[0]
|
|
637
|
-
id = args[1]
|
|
638
636
|
params = {}
|
|
639
637
|
options = {}
|
|
640
638
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
@@ -649,6 +647,8 @@ EOT
|
|
|
649
647
|
optparse.parse!(args)
|
|
650
648
|
verify_args!(args:args, optparse:optparse, count:2)
|
|
651
649
|
connect(options)
|
|
650
|
+
parent_id = args[0]
|
|
651
|
+
id = args[1]
|
|
652
652
|
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
|
653
653
|
if parent_record.nil?
|
|
654
654
|
return 1, "#{rest_parent_label} not found for '#{parent_id}"
|
|
@@ -43,7 +43,7 @@ module Morpheus
|
|
|
43
43
|
my_summaries.each do |full_line|
|
|
44
44
|
opt_description = full_line.to_s.strip
|
|
45
45
|
if opt_description.start_with?("-")
|
|
46
|
-
is_hidden = (
|
|
46
|
+
is_hidden = (hidden_options || []).find { |hidden_switch|
|
|
47
47
|
if hidden_switch.start_with?("-")
|
|
48
48
|
opt_description.start_with?("#{hidden_switch} ")
|
|
49
49
|
else
|
|
@@ -74,6 +74,10 @@ module Morpheus
|
|
|
74
74
|
out
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
+
def hidden_options
|
|
78
|
+
@hidden_options ||= []
|
|
79
|
+
end
|
|
80
|
+
|
|
77
81
|
def add_hidden_option(opt_name)
|
|
78
82
|
opt_array = [opt_name].flatten.compact
|
|
79
83
|
@hidden_options ||= []
|
|
@@ -14,12 +14,25 @@ module Morpheus
|
|
|
14
14
|
default_value = options[:default]
|
|
15
15
|
value_found = false
|
|
16
16
|
while value_found == false do
|
|
17
|
+
# if default_value.nil?
|
|
18
|
+
# print "#{message} (yes/no): "
|
|
19
|
+
# else
|
|
20
|
+
# print "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
|
|
21
|
+
# end
|
|
22
|
+
# input = $stdin.gets.chomp!
|
|
23
|
+
|
|
24
|
+
# should use Readline.readline to probably
|
|
25
|
+
Readline.completion_append_character = ""
|
|
26
|
+
Readline.basic_word_break_characters = ''
|
|
27
|
+
Readline.completion_proc = nil
|
|
17
28
|
if default_value.nil?
|
|
18
|
-
|
|
29
|
+
confirm_prompt = "#{message} (yes/no): "
|
|
19
30
|
else
|
|
20
|
-
|
|
31
|
+
confirm_prompt = "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
|
|
21
32
|
end
|
|
22
|
-
input =
|
|
33
|
+
input = Readline.readline(confirm_prompt, false).to_s
|
|
34
|
+
input = input.chomp.strip
|
|
35
|
+
|
|
23
36
|
if input.empty? && !default_value.nil?
|
|
24
37
|
return !!default_value
|
|
25
38
|
end
|
|
@@ -86,6 +99,25 @@ module Morpheus
|
|
|
86
99
|
context_map = results
|
|
87
100
|
value = nil
|
|
88
101
|
value_found = false
|
|
102
|
+
|
|
103
|
+
# allow for mapping of domain to relevant type: domain.zone => router.zone
|
|
104
|
+
option_type['fieldContext'] = (options[:context_map] || {})[option_type['fieldContext']] || option_type['fieldContext']
|
|
105
|
+
field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
|
106
|
+
help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
|
|
107
|
+
namespaces = field_key.split(".")
|
|
108
|
+
field_name = namespaces.pop
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# support --no-options --skip-option x,y,z --only-option x,y,z
|
|
112
|
+
if options[:no_options]
|
|
113
|
+
next
|
|
114
|
+
elsif options[:skip_options] && options[:skip_options].find {|it| it.to_s.downcase == option_type['fieldName'].to_s.downcase || it.to_s.downcase == option_type['fieldLabel'].to_s.downcase }
|
|
115
|
+
next
|
|
116
|
+
elsif options[:only_options] && !options[:only_options].find {|it| it.to_s.downcase == option_type['fieldName'].to_s.downcase || it.to_s.downcase == option_type['fieldLabel'].to_s.downcase }
|
|
117
|
+
next
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
89
121
|
field_group = (option_type['fieldGroup'] || 'default').to_s.sub(/options\Z/i, "").strip # avoid "ADVANCED OPTION OPTIONS"
|
|
90
122
|
|
|
91
123
|
if cur_field_group != field_group
|
|
@@ -105,12 +137,6 @@ module Morpheus
|
|
|
105
137
|
# end
|
|
106
138
|
# end
|
|
107
139
|
|
|
108
|
-
# allow for mapping of domain to relevant type: domain.zone => router.zone
|
|
109
|
-
option_type['fieldContext'] = (options[:context_map] || {})[option_type['fieldContext']] || option_type['fieldContext']
|
|
110
|
-
field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
|
111
|
-
help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
|
|
112
|
-
namespaces = field_key.split(".")
|
|
113
|
-
field_name = namespaces.pop
|
|
114
140
|
|
|
115
141
|
# respect optionType.dependsOnCode
|
|
116
142
|
# i guess this switched to visibleOnCode, respect one or the other
|
|
@@ -612,6 +638,7 @@ module Morpheus
|
|
|
612
638
|
end
|
|
613
639
|
|
|
614
640
|
while !value_found do
|
|
641
|
+
#Readline.input = $stdin
|
|
615
642
|
Readline.completion_append_character = ""
|
|
616
643
|
Readline.basic_word_break_characters = ''
|
|
617
644
|
Readline.completion_proc = proc {|s|
|
|
@@ -703,6 +730,7 @@ module Morpheus
|
|
|
703
730
|
elsif no_prompt
|
|
704
731
|
input = default_value
|
|
705
732
|
else
|
|
733
|
+
#Readline.input = $stdin
|
|
706
734
|
Readline.completion_append_character = ""
|
|
707
735
|
Readline.basic_word_break_characters = ''
|
|
708
736
|
Readline.completion_proc = proc {|s|
|
|
@@ -970,8 +998,26 @@ module Morpheus
|
|
|
970
998
|
def self.password_prompt(option_type)
|
|
971
999
|
value_found = false
|
|
972
1000
|
while !value_found do
|
|
973
|
-
|
|
974
|
-
|
|
1001
|
+
# readline is still echoing secret with 'NUL:'' so just use $stdin on windows for now
|
|
1002
|
+
if Morpheus::Cli.windows?
|
|
1003
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
|
|
1004
|
+
input = $stdin.noecho(&:gets).chomp!
|
|
1005
|
+
else
|
|
1006
|
+
Readline.completion_append_character = ""
|
|
1007
|
+
Readline.basic_word_break_characters = ''
|
|
1008
|
+
Readline.completion_proc = nil
|
|
1009
|
+
# needs to work like $stdin.noecho
|
|
1010
|
+
Readline.pre_input_hook = lambda {
|
|
1011
|
+
Readline.output = File.open('/dev/null', 'w')
|
|
1012
|
+
#Readline.output = File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
|
|
1013
|
+
#$stdout = File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
|
|
1014
|
+
}
|
|
1015
|
+
password_prompt = "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
|
|
1016
|
+
input = Readline.readline(password_prompt, false).to_s.chomp
|
|
1017
|
+
Readline.pre_input_hook = nil
|
|
1018
|
+
Readline.output = Morpheus::Terminal.instance.stdout #my_terminal.stdout
|
|
1019
|
+
end
|
|
1020
|
+
|
|
975
1021
|
value = input
|
|
976
1022
|
print "\n"
|
|
977
1023
|
if input == '?'
|
|
@@ -991,6 +1037,7 @@ module Morpheus
|
|
|
991
1037
|
value = nil
|
|
992
1038
|
while !value_found do
|
|
993
1039
|
#print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
|
1040
|
+
#Readline.input = $stdin
|
|
994
1041
|
Readline.completion_append_character = ""
|
|
995
1042
|
Readline.basic_word_break_characters = ''
|
|
996
1043
|
Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
|
|
@@ -1005,7 +1052,7 @@ module Morpheus
|
|
|
1005
1052
|
value_found = true
|
|
1006
1053
|
elsif value
|
|
1007
1054
|
filename = File.expand_path(value)
|
|
1008
|
-
if !File.
|
|
1055
|
+
if !File.exist?(filename)
|
|
1009
1056
|
# print_red_alert "File not found: #{filename}"
|
|
1010
1057
|
# exit 1
|
|
1011
1058
|
print Term::ANSIColor.red," File not found: #{filename}",Term::ANSIColor.reset, "\n"
|
data/lib/morpheus/cli/version.rb
CHANGED
data/lib/morpheus/cli.rb
CHANGED
|
@@ -36,38 +36,48 @@ module Morpheus
|
|
|
36
36
|
begin
|
|
37
37
|
require 'rbconfig'
|
|
38
38
|
@@is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
|
39
|
-
rescue
|
|
39
|
+
rescue
|
|
40
40
|
# $stderr.puts "unable to determine if this is a Windows machine."
|
|
41
41
|
end
|
|
42
42
|
return @@is_windows
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
# load
|
|
45
|
+
# load! does the initial loading of all the CLI utilities and commands
|
|
46
46
|
def self.load!()
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
require 'morpheus/api
|
|
50
|
-
|
|
51
|
-
Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each {|file| load file }
|
|
52
|
-
|
|
53
|
-
# load mixins
|
|
54
|
-
Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| load file }
|
|
47
|
+
|
|
48
|
+
# api interfaces
|
|
49
|
+
require 'morpheus/api'
|
|
50
|
+
Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each { |file| require file }
|
|
55
51
|
|
|
56
|
-
#
|
|
52
|
+
# utilites
|
|
53
|
+
# Dir[File.dirname(__FILE__) + "/cli/*.rb"].each { |file| require file }
|
|
57
54
|
require 'morpheus/cli/cli_registry.rb'
|
|
58
55
|
require 'morpheus/cli/expression_parser.rb'
|
|
59
56
|
require 'morpheus/cli/dot_file.rb'
|
|
60
57
|
require 'morpheus/cli/errors'
|
|
58
|
+
require 'morpheus/cli/cli_command.rb'
|
|
59
|
+
require 'morpheus/cli/option_types.rb'
|
|
60
|
+
require 'morpheus/cli/credentials.rb'
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
load 'morpheus/cli/credentials.rb'
|
|
62
|
+
# mixins
|
|
63
|
+
Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| require file }
|
|
65
64
|
|
|
66
|
-
#
|
|
67
|
-
Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file|
|
|
65
|
+
# commands
|
|
66
|
+
Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| require file }
|
|
68
67
|
|
|
69
68
|
end
|
|
70
69
|
|
|
70
|
+
# reload! can be used for live reloading changes while developing
|
|
71
|
+
def self.reload!()
|
|
72
|
+
# api interfaces
|
|
73
|
+
Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each { |file| load file }
|
|
74
|
+
# mixins
|
|
75
|
+
Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| load file }
|
|
76
|
+
# commands
|
|
77
|
+
Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| load file }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# require all CLI modules now (on require)
|
|
71
81
|
load!
|
|
72
82
|
|
|
73
83
|
end
|
|
@@ -5,6 +5,7 @@ require 'rest-client'
|
|
|
5
5
|
module RestClient
|
|
6
6
|
class Request
|
|
7
7
|
|
|
8
|
+
alias_method :original_log_request, :log_request
|
|
8
9
|
def log_request
|
|
9
10
|
begin
|
|
10
11
|
return unless RestClient.log
|
|
@@ -14,10 +15,10 @@ module RestClient
|
|
|
14
15
|
out << payload.short_inspect if payload
|
|
15
16
|
out << processed_headers.to_a.sort.map { |(k, v)| [k.inspect, v.inspect].join("=>") }.join(", ")
|
|
16
17
|
RestClient.log << out.join(', ') + "\n"
|
|
17
|
-
rescue
|
|
18
|
+
rescue
|
|
18
19
|
# something went wrong, wrong gem version maybe...above is from rest-client 2.0.2
|
|
19
20
|
# do it the old way
|
|
20
|
-
|
|
21
|
+
original_log_request()
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
=begin
|
data/lib/morpheus/formatters.rb
CHANGED
data/lib/morpheus/logging.rb
CHANGED
|
@@ -85,18 +85,18 @@ module Morpheus::Logging
|
|
|
85
85
|
msg = msg.clone
|
|
86
86
|
# looks for RestClient format (hash.inspect) and request/curl output name: value
|
|
87
87
|
msg.gsub!(/Authorization\"\s?\=\>\s?\"Bearer [^"]+/i, 'Authorization"=>"Bearer ************')
|
|
88
|
-
msg.gsub!(/Authorization\:\s?Bearer [^"'
|
|
88
|
+
msg.gsub!(/Authorization\:\s?Bearer [^"']+/i, 'Authorization: Bearer ************')
|
|
89
89
|
# msg.gsub!(/#{AUTHORIZATION_HEADER}\"\s?\=\>\s?\"Bearer [^"]+/, "#{AUTHORIZATION_HEADER}"=>"Bearer ************")
|
|
90
|
-
# msg.gsub!(/#{AUTHORIZATION_HEADER}\:\s?Bearer [^"'
|
|
90
|
+
# msg.gsub!(/#{AUTHORIZATION_HEADER}\:\s?Bearer [^"']+/, "#{AUTHORIZATION_HEADER}: Bearer ************")
|
|
91
91
|
SECRET_TOKEN_HEADERS.each do |header|
|
|
92
92
|
msg.gsub!(/#{header}\"\s?\=\>\s?\"[^"]+/, "#{header}\"=>\"************")
|
|
93
|
-
msg.gsub!(/#{header}\:\s?[^"'
|
|
93
|
+
msg.gsub!(/#{header}\:\s?[^"']+/, "#{header}: ************")
|
|
94
94
|
end
|
|
95
95
|
msg.gsub!(/password\"\: "[^"]+/, 'password": "************') # json properties ending with password
|
|
96
96
|
msg.gsub!(/Password\"\: "[^"]+/, 'Password": "************') # json properties ending with Password
|
|
97
97
|
msg.gsub!(/password\"\s?\=\>\s?\"[^"]+/i, 'password"=>"************')
|
|
98
98
|
msg.gsub!(/password\=\"[^"]+/i, 'password="************')
|
|
99
|
-
msg.gsub!(/password\=[^"'
|
|
99
|
+
msg.gsub!(/password\=[^"'&]+/i, 'password=************') # buggy, wont work with ampersand or quotes in passwords! heh
|
|
100
100
|
msg.gsub!(/passwordConfirmation\=[^" ]+/i, 'passwordConfirmation="************')
|
|
101
101
|
msg.gsub!(/passwordConfirmation\=[^" ]+/i, 'passwordConfirmation=************')
|
|
102
102
|
end
|