morpheus-cli 8.0.1 → 8.0.3
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/lib/morpheus/cli/cli_command.rb +18 -3
- data/lib/morpheus/cli/commands/clusters.rb +50 -44
- data/lib/morpheus/cli/commands/hosts.rb +9 -3
- data/lib/morpheus/cli/commands/instances.rb +37 -66
- data/lib/morpheus/cli/commands/library_cluster_layouts_command.rb +1 -1
- data/lib/morpheus/cli/commands/processes_command.rb +2 -2
- data/lib/morpheus/cli/commands/shell.rb +18 -39
- data/lib/morpheus/cli/commands/snapshots.rb +24 -8
- data/lib/morpheus/cli/commands/virtual_images.rb +71 -17
- data/lib/morpheus/cli/mixins/execution_request_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/processes_helper.rb +34 -4
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -324
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +1 -1
- data/test/cli/auth_test.rb +6 -0
- data/test/cli/roles_test.rb +15 -2
- data/test/test_case.rb +1 -0
- metadata +2 -2
@@ -172,11 +172,8 @@ EOT
|
|
172
172
|
id
|
173
173
|
else
|
174
174
|
image = find_virtual_image_by_name_or_id(id)
|
175
|
-
if image
|
176
|
-
|
177
|
-
else
|
178
|
-
raise_command_error "virtual image not found for name '#{id}'"
|
179
|
-
end
|
175
|
+
return 1, "virtual image not found for name '#{id}'" if image.nil?
|
176
|
+
image['id']
|
180
177
|
end
|
181
178
|
end
|
182
179
|
return run_command_for_each_arg(id_list) do |arg|
|
@@ -383,15 +380,16 @@ EOT
|
|
383
380
|
# storageProviderId, format, name
|
384
381
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
385
382
|
opts.banner = subcommand_usage("[image] [options]")
|
386
|
-
opts.on('-n', '--name NAME', String, "Name (optional) of the new converted image. Default is name of the original image.") do |val|
|
387
|
-
|
388
|
-
end
|
389
|
-
opts.on('-f', '--format FORMAT', String, "Format (optional). Default is 'qcow2'") do |val|
|
390
|
-
|
391
|
-
end
|
392
|
-
opts.on('--storageProvider VALUE', String, "Storage Provider ID (optional). Default is storage provider of the original image.") do |val|
|
393
|
-
|
394
|
-
end
|
383
|
+
# opts.on('-n', '--name NAME', String, "Name (optional) of the new converted image. Default is name of the original image.") do |val|
|
384
|
+
# options[:options]['name'] = val
|
385
|
+
# end
|
386
|
+
# opts.on('-f', '--format FORMAT', String, "Format (optional). Default is 'qcow2'") do |val|
|
387
|
+
# options[:options]['format'] = val
|
388
|
+
# end
|
389
|
+
# opts.on('--storageProvider VALUE', String, "Storage Provider ID (optional). Default is storage provider of the original image.") do |val|
|
390
|
+
# options[:options]['storageProvider'] = val.to_s
|
391
|
+
# end
|
392
|
+
build_option_type_options(opts, options, convert_virtual_image_option_types)
|
395
393
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
396
394
|
opts.footer = "Convert a virtual image to a new format." + "\n" +
|
397
395
|
"[image] is required. This is the name or id of a virtual image."
|
@@ -411,7 +409,18 @@ EOT
|
|
411
409
|
payload.deep_merge!({virtual_image_object_key => passed_options}) unless passed_options.empty?
|
412
410
|
else
|
413
411
|
virtual_image_payload = passed_options
|
414
|
-
|
412
|
+
source_format = virtual_image['imageType']
|
413
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(convert_virtual_image_option_types(source_format), options[:options], @api_client, {'virtualImageId': virtual_image['id']})
|
414
|
+
v_prompt.deep_compact!
|
415
|
+
virtual_image_payload.deep_merge!(v_prompt)
|
416
|
+
# support "storageProviderId" too
|
417
|
+
if virtual_image_payload['storageProviderId']
|
418
|
+
virtual_image_payload['storageProvider'] = virtual_image_payload.delete('storageProviderId')
|
419
|
+
end
|
420
|
+
# convert "storageProvider":1 to "storageProvider": {"id":1}
|
421
|
+
if virtual_image_payload['storageProvider'] && !virtual_image_payload['storageProvider'].is_a?(Hash)
|
422
|
+
virtual_image_payload['storageProvider'] = {'id' => virtual_image_payload['storageProvider'].to_i }
|
423
|
+
end
|
415
424
|
payload = virtual_image_payload
|
416
425
|
end
|
417
426
|
@virtual_images_interface.setopts(options)
|
@@ -990,11 +999,20 @@ EOT
|
|
990
999
|
|
991
1000
|
def find_virtual_image_by_name(name)
|
992
1001
|
json_results = @virtual_images_interface.list({name: name.to_s})
|
993
|
-
|
1002
|
+
records = json_results['virtualImages']
|
1003
|
+
if records.empty?
|
994
1004
|
print_red_alert "Virtual Image not found by name #{name}"
|
995
1005
|
return nil
|
1006
|
+
elsif records.size > 1
|
1007
|
+
print_red_alert "More than one Virtual Image found by name '#{name}'"
|
1008
|
+
print_error "\n"
|
1009
|
+
puts_error as_pretty_table(records, [:id, :name], {color:red})
|
1010
|
+
print_red_alert "Try using ID instead"
|
1011
|
+
print_error reset,"\n"
|
1012
|
+
return nil
|
1013
|
+
else
|
1014
|
+
virtual_image = records[0]
|
996
1015
|
end
|
997
|
-
virtual_image = json_results['virtualImages'][0]
|
998
1016
|
return virtual_image
|
999
1017
|
end
|
1000
1018
|
|
@@ -1074,6 +1092,42 @@ EOT
|
|
1074
1092
|
list
|
1075
1093
|
end
|
1076
1094
|
|
1095
|
+
def convert_virtual_image_option_types(source_format=nil)
|
1096
|
+
[
|
1097
|
+
{'shorthand' => '-f', 'fieldName' => 'format', 'type' => 'select', 'fieldLabel' => 'Format', 'selectOptions' => get_convert_image_formats(source_format), 'required' => true, 'defaultValue' => (source_format == 'qcow2' ? nil : 'qcow2')},
|
1098
|
+
{'shorthand' => '-b', 'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => 'Bucket', 'optionSource' => 'storageProviders', 'required' => false, 'description' => 'Select Storage Provider Bucket or File Share.'},
|
1099
|
+
{'shorthand' => '-n', 'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false}
|
1100
|
+
]
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
def convert_source_types
|
1104
|
+
["raw","qcow2","vmdk",'vmware', "vhd","ovf"]
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
def convert_destination_types
|
1108
|
+
#["raw", "qcow2", "vmdk",'vmware',"vhd","ovf"]
|
1109
|
+
convert_source_types
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
def get_convert_image_formats(source_format=nil)
|
1113
|
+
categories = [
|
1114
|
+
{'name' => 'QCOW2', 'value' => 'qcow2'},
|
1115
|
+
{'name' => 'VMDK', 'value' => 'ovf'},
|
1116
|
+
{'name' => 'VHD', 'value' => 'vhd'},
|
1117
|
+
{'name' => 'Raw', 'value' => 'raw'}
|
1118
|
+
]
|
1119
|
+
# if source format (imageType) is not in the list, then no options
|
1120
|
+
# else reject the current value
|
1121
|
+
if source_format
|
1122
|
+
if !convert_source_types.include?(source_format.to_s.downcase)
|
1123
|
+
categories = []
|
1124
|
+
else
|
1125
|
+
categories = categories.select {|it| it['value'] != source_format.to_s.downcase }
|
1126
|
+
end
|
1127
|
+
end
|
1128
|
+
return categories
|
1129
|
+
end
|
1130
|
+
|
1077
1131
|
def format_tenants(accounts)
|
1078
1132
|
if accounts && accounts.size > 0
|
1079
1133
|
accounts = accounts.sort {|a,b| a['name'] <=> b['name'] }.uniq {|it| it['id'] }
|
@@ -29,7 +29,7 @@ module Morpheus::Cli::ExecutionRequestHelper
|
|
29
29
|
# unless options[:quiet]
|
30
30
|
# print cyan, "Execution request has not yet finished. Refreshing every #{refresh_display_seconds} seconds...", "\n", reset
|
31
31
|
# end
|
32
|
-
while
|
32
|
+
while (options[:waiting_status] || ['new', 'pending']).include?(execution_request['status']) do
|
33
33
|
sleep(refresh_interval)
|
34
34
|
execution_request = execution_request_interface.get(execution_request_id)['executionRequest']
|
35
35
|
end
|
@@ -8,8 +8,17 @@ module Morpheus::Cli::ProcessesHelper
|
|
8
8
|
klass.send :include, Morpheus::Cli::PrintHelper
|
9
9
|
end
|
10
10
|
|
11
|
+
def api_client
|
12
|
+
raise "#{self.class} has not defined @api_client" if @api_client.nil?
|
13
|
+
@api_client
|
14
|
+
end
|
15
|
+
|
16
|
+
def processes_interface
|
17
|
+
# get_interface('processes')
|
18
|
+
api_client.processes
|
19
|
+
end
|
11
20
|
|
12
|
-
def print_process_details(process)
|
21
|
+
def print_process_details(process, options={})
|
13
22
|
description_cols = {
|
14
23
|
"Process ID" => lambda {|it| it['id'] },
|
15
24
|
"Name" => lambda {|it| it['displayName'] },
|
@@ -22,7 +31,7 @@ module Morpheus::Cli::ProcessesHelper
|
|
22
31
|
"Status" => lambda {|it| format_process_status(it) },
|
23
32
|
# "# Events" => lambda {|it| (it['events'] || []).size() },
|
24
33
|
}
|
25
|
-
print_description_list(description_cols, process)
|
34
|
+
print_description_list(description_cols, process, options)
|
26
35
|
|
27
36
|
if process['error']
|
28
37
|
print_h2 "Error"
|
@@ -39,7 +48,7 @@ module Morpheus::Cli::ProcessesHelper
|
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
42
|
-
def print_process_event_details(process_event)
|
51
|
+
def print_process_event_details(process_event, options={})
|
43
52
|
# process_event =~ process
|
44
53
|
description_cols = {
|
45
54
|
"Process ID" => lambda {|it| it['processId'] },
|
@@ -53,7 +62,7 @@ module Morpheus::Cli::ProcessesHelper
|
|
53
62
|
"Duration" => lambda {|it| format_process_duration(it) },
|
54
63
|
"Status" => lambda {|it| format_process_status(it) },
|
55
64
|
}
|
56
|
-
print_description_list(description_cols, process_event)
|
65
|
+
print_description_list(description_cols, process_event, options)
|
57
66
|
|
58
67
|
if process_event['error']
|
59
68
|
print_h2 "Error"
|
@@ -111,4 +120,25 @@ module Morpheus::Cli::ProcessesHelper
|
|
111
120
|
out
|
112
121
|
end
|
113
122
|
|
123
|
+
def wait_for_process_execution(process_id, options={}, print_output = true)
|
124
|
+
refresh_interval = 10
|
125
|
+
if options[:refresh_interval].to_i > 0
|
126
|
+
refresh_interval = options[:refresh_interval]
|
127
|
+
end
|
128
|
+
refresh_display_seconds = refresh_interval % 1.0 == 0 ? refresh_interval.to_i : refresh_interval
|
129
|
+
unless options[:quiet]
|
130
|
+
print cyan, "Refreshing every #{refresh_display_seconds} seconds until process is complete...", "\n", reset
|
131
|
+
end
|
132
|
+
process = processes_interface.get(process_id)['process']
|
133
|
+
while ['new','queued','pending','running'].include?(process['status']) do
|
134
|
+
sleep(refresh_interval)
|
135
|
+
process = processes_interface.get(process_id)['process']
|
136
|
+
end
|
137
|
+
if print_output && options[:quiet] != true
|
138
|
+
print_h1 "Process Details", [], options
|
139
|
+
print_process_details(process, options)
|
140
|
+
end
|
141
|
+
return process
|
142
|
+
end
|
143
|
+
|
114
144
|
end
|