morpheus-cli 9.0.0 → 9.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/clusters_interface.rb +72 -0
- data/lib/morpheus/api/instances_interface.rb +1 -1
- data/lib/morpheus/api/options_interface.rb +1 -1
- data/lib/morpheus/api/servers_interface.rb +8 -0
- data/lib/morpheus/api/storage_volumes_interface.rb +8 -0
- data/lib/morpheus/api/virtual_images_interface.rb +10 -2
- data/lib/morpheus/api/virtual_switches_interface.rb +9 -0
- data/lib/morpheus/cli/commands/backups_command.rb +20 -6
- data/lib/morpheus/cli/commands/clusters.rb +575 -14
- data/lib/morpheus/cli/commands/hosts.rb +72 -1
- data/lib/morpheus/cli/commands/instances.rb +13 -2
- data/lib/morpheus/cli/commands/networks_command.rb +35 -3
- data/lib/morpheus/cli/commands/storage_volumes.rb +77 -2
- data/lib/morpheus/cli/commands/virtual_switches_command.rb +336 -0
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +6 -4
- data/lib/morpheus/cli/version.rb +1 -1
- data/test/cli/storage_volumes_test.rb +79 -0
- metadata +6 -2
|
@@ -15,7 +15,7 @@ class Morpheus::Cli::Hosts
|
|
|
15
15
|
:wiki, :update_wiki,
|
|
16
16
|
:maintenance, :leave_maintenance, :placement,
|
|
17
17
|
:list_devices, :assign_device, :detach_device, :attach_device,
|
|
18
|
-
:snapshot
|
|
18
|
+
:snapshot, :create_linked_clone
|
|
19
19
|
alias_subcommand :details, :get
|
|
20
20
|
set_default_subcommand :list
|
|
21
21
|
|
|
@@ -796,6 +796,10 @@ class Morpheus::Cli::Hosts
|
|
|
796
796
|
opts.on("--security-groups LIST", Integer, "Security Groups, comma separated list of security group IDs") do |val|
|
|
797
797
|
options[:security_groups] = val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
|
|
798
798
|
end
|
|
799
|
+
opts.on("--storage-controller ARRAY", String, "Storage Controllers, JSON array of controller configs. Each entry accepts id, busNumber, typeId, typeName, removable, editable.") do |val|
|
|
800
|
+
options[:options] ||= {}
|
|
801
|
+
options[:options]['storageController'] = JSON.parse(val)
|
|
802
|
+
end
|
|
799
803
|
opts.on('--tags LIST', String, "Metadata tags in the format 'ping=pong,flash=bang'") do |val|
|
|
800
804
|
options[:metadata] = val
|
|
801
805
|
end
|
|
@@ -956,6 +960,10 @@ class Morpheus::Cli::Hosts
|
|
|
956
960
|
payload['volumes'] = volumes
|
|
957
961
|
end
|
|
958
962
|
|
|
963
|
+
if options[:options] && options[:options]['storageController']
|
|
964
|
+
payload['storageController'] = options[:options]['storageController']
|
|
965
|
+
end
|
|
966
|
+
|
|
959
967
|
# plan customizations
|
|
960
968
|
plan_opts = prompt_service_plan_options(service_plan, options, @api_client, {})
|
|
961
969
|
if plan_opts && !plan_opts.empty?
|
|
@@ -1347,6 +1355,10 @@ class Morpheus::Cli::Hosts
|
|
|
1347
1355
|
options = {}
|
|
1348
1356
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
1349
1357
|
opts.banner = subcommand_usage("[name]")
|
|
1358
|
+
opts.on("--storage-controller ARRAY", String, "Storage Controllers, JSON array of controller configs. Each entry accepts id, busNumber, typeId, typeName, removable, editable.") do |val|
|
|
1359
|
+
options[:options] ||= {}
|
|
1360
|
+
options[:options]['storageController'] = JSON.parse(val)
|
|
1361
|
+
end
|
|
1350
1362
|
build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
|
|
1351
1363
|
end
|
|
1352
1364
|
optparse.parse!(args)
|
|
@@ -1435,6 +1447,9 @@ class Morpheus::Cli::Hosts
|
|
|
1435
1447
|
# only amazon supports this option
|
|
1436
1448
|
# for now, always do this
|
|
1437
1449
|
payload[:deleteOriginalVolumes] = true
|
|
1450
|
+
if options[:options] && options[:options]['storageController']
|
|
1451
|
+
payload[:storageController] = options[:options]['storageController']
|
|
1452
|
+
end
|
|
1438
1453
|
@servers_interface.setopts(options)
|
|
1439
1454
|
if options[:dry_run]
|
|
1440
1455
|
print_dry_run @servers_interface.dry.resize(server['id'], payload)
|
|
@@ -2716,6 +2731,62 @@ EOT
|
|
|
2716
2731
|
return 0, nil
|
|
2717
2732
|
end
|
|
2718
2733
|
|
|
2734
|
+
def create_linked_clone(args)
|
|
2735
|
+
options = {}
|
|
2736
|
+
server = nil
|
|
2737
|
+
snapshot_id = nil
|
|
2738
|
+
|
|
2739
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
2740
|
+
opts.banner = subcommand_usage("[host]")
|
|
2741
|
+
opts.on("--snapshot ID", String, "Snapshot ID") do |val|
|
|
2742
|
+
snapshot_id = val
|
|
2743
|
+
end
|
|
2744
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
|
2745
|
+
opts.footer = "Create a linked clone using the selected snapshot of a Host." + "\n" +
|
|
2746
|
+
"[snapshotId] is required. This is the id of the snapshot which the clone will refer to."
|
|
2747
|
+
end
|
|
2748
|
+
|
|
2749
|
+
optparse.parse!(args)
|
|
2750
|
+
if args.count != 1
|
|
2751
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
2752
|
+
end
|
|
2753
|
+
connect(options)
|
|
2754
|
+
begin
|
|
2755
|
+
server = find_host_by_name_or_id(args[0])
|
|
2756
|
+
options[:options]['serverId'] = server['id']
|
|
2757
|
+
begin
|
|
2758
|
+
snapshot_options = @servers_interface.snapshots(server['id'], {})['snapshots'].collect {|it| {'name' => "#{it['name']} (#{it['id']})", 'value' => it['id']} }
|
|
2759
|
+
snapshot_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'snapshotId', 'type' => 'select', 'fieldLabel' => 'Snapshot', 'selectOptions' => snapshot_options, 'required' => true, 'description' => 'Select Snapshot.'}], {}, @api_client, options[:options])
|
|
2760
|
+
|
|
2761
|
+
if !snapshot_prompt['snapshotId'].to_s.empty?
|
|
2762
|
+
snapshot_id = snapshot_prompt['snapshotId']
|
|
2763
|
+
end
|
|
2764
|
+
rescue RestClient::Exception => e
|
|
2765
|
+
puts "Failed to load host snapshots"
|
|
2766
|
+
end
|
|
2767
|
+
|
|
2768
|
+
@servers_interface.setopts(options)
|
|
2769
|
+
|
|
2770
|
+
payload = {}
|
|
2771
|
+
if options[:dry_run]
|
|
2772
|
+
print_dry_run @servers_interface.dry.create_linked_clone(server['id'], snapshot_id, payload)
|
|
2773
|
+
return
|
|
2774
|
+
end
|
|
2775
|
+
|
|
2776
|
+
json_response = @servers_interface.create_linked_clone(server['id'], snapshot_id, payload)
|
|
2777
|
+
if options[:json]
|
|
2778
|
+
puts as_json(json_response, options)
|
|
2779
|
+
else
|
|
2780
|
+
print_green_success "Linked Clone creation initiated."
|
|
2781
|
+
end
|
|
2782
|
+
return 0
|
|
2783
|
+
|
|
2784
|
+
rescue RestClient::Exception => e
|
|
2785
|
+
print_rest_exception(e, options)
|
|
2786
|
+
exit 1
|
|
2787
|
+
end
|
|
2788
|
+
end
|
|
2789
|
+
|
|
2719
2790
|
## Server Devices
|
|
2720
2791
|
|
|
2721
2792
|
def list_devices(args)
|
|
@@ -315,7 +315,7 @@ class Morpheus::Cli::Instances
|
|
|
315
315
|
}
|
|
316
316
|
row
|
|
317
317
|
}
|
|
318
|
-
columns = [:id, {:name => {:max_width => 50}}, :tenant, :group, :cloud,
|
|
318
|
+
columns = [:id, {:name => {:max_width => 50}}, :labels, :tenant, :group, :cloud,
|
|
319
319
|
:type, :version, :environment, :plan,
|
|
320
320
|
{:created => {:display_name => "CREATED"}},
|
|
321
321
|
{:user => {:display_name => "OWNER", :max_width => 20}},
|
|
@@ -465,6 +465,10 @@ class Morpheus::Cli::Instances
|
|
|
465
465
|
opts.on("--layout-size NUMBER", Integer, "Apply a multiply factor of containers/vms within the instance") do |val|
|
|
466
466
|
options[:layout_size] = val.to_i
|
|
467
467
|
end
|
|
468
|
+
opts.on("--storage-controller ARRAY", String, "Storage Controllers, JSON array of controller configs. Each entry accepts id, busNumber, typeId, typeName, removable, editable. Example: '[{\"busNumber\":\"1\",\"typeName\":\"SCSI\"}]'") do |val|
|
|
469
|
+
options[:options] ||= {}
|
|
470
|
+
options[:options]['storageController'] = JSON.parse(val)
|
|
471
|
+
end
|
|
468
472
|
opts.on( '-l', '--layout LAYOUT', "Layout ID" ) do |val|
|
|
469
473
|
options[:layout] = val
|
|
470
474
|
end
|
|
@@ -595,6 +599,9 @@ class Morpheus::Cli::Instances
|
|
|
595
599
|
end
|
|
596
600
|
|
|
597
601
|
payload['instance'] ||= {}
|
|
602
|
+
if options[:options] && options[:options]['storageController']
|
|
603
|
+
payload['storageController'] = options[:options]['storageController']
|
|
604
|
+
end
|
|
598
605
|
if options[:instance_name]
|
|
599
606
|
payload['instance']['name'] = options[:instance_name]
|
|
600
607
|
end
|
|
@@ -2910,6 +2917,10 @@ class Morpheus::Cli::Instances
|
|
|
2910
2917
|
opts.on('--include-network-interfaces','--include-network-interfaces', "Populate payload networkInterfaces with current interfaces") do
|
|
2911
2918
|
options[:include_nics] = true
|
|
2912
2919
|
end
|
|
2920
|
+
opts.on("--storage-controller ARRAY", String, "Storage Controllers, JSON array of controller configs. Each entry accepts id, busNumber, typeId, typeName, removable, editable.") do |val|
|
|
2921
|
+
options[:options] ||= {}
|
|
2922
|
+
options[:options]['storageController'] = JSON.parse(val)
|
|
2923
|
+
end
|
|
2913
2924
|
build_standard_update_options(opts, options)
|
|
2914
2925
|
end
|
|
2915
2926
|
optparse.parse!(args)
|
|
@@ -3958,7 +3969,7 @@ List snapshots for an instance.
|
|
|
3958
3969
|
|
|
3959
3970
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
3960
3971
|
opts.banner = subcommand_usage("[instance]")
|
|
3961
|
-
opts.on("--snapshot ID", String, "
|
|
3972
|
+
opts.on("--snapshot ID", String, "Snapshot ID") do |val|
|
|
3962
3973
|
snapshot_id = val
|
|
3963
3974
|
end
|
|
3964
3975
|
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
|
@@ -5,6 +5,7 @@ class Morpheus::Cli::NetworksCommand
|
|
|
5
5
|
include Morpheus::Cli::WhoamiHelper
|
|
6
6
|
include Morpheus::Cli::InfrastructureHelper
|
|
7
7
|
include Morpheus::Cli::ProvisioningHelper
|
|
8
|
+
include Morpheus::Cli::AccountsHelper
|
|
8
9
|
|
|
9
10
|
set_command_name :networks
|
|
10
11
|
|
|
@@ -28,6 +29,8 @@ class Morpheus::Cli::NetworksCommand
|
|
|
28
29
|
@groups_interface = @api_client.groups
|
|
29
30
|
@clouds_interface = @api_client.clouds
|
|
30
31
|
@options_interface = @api_client.options
|
|
32
|
+
@accounts_interface = @api_client.accounts
|
|
33
|
+
@account_users_interface = @api_client.account_users
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def handle(args)
|
|
@@ -57,6 +60,13 @@ class Morpheus::Cli::NetworksCommand
|
|
|
57
60
|
opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
|
|
58
61
|
add_query_parameter(params, 'allLabels', parse_labels(val))
|
|
59
62
|
end
|
|
63
|
+
opts.on('--include-tenants','--include-tenants', "Include sub tenant networks") do
|
|
64
|
+
options[:include_tenants] = true
|
|
65
|
+
params['includeTenants'] = true
|
|
66
|
+
end
|
|
67
|
+
opts.on('--tenant TENANT', String, "Tenant Name or ID" ) do |val|
|
|
68
|
+
options[:tenant] = val
|
|
69
|
+
end
|
|
60
70
|
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
|
|
61
71
|
opts.footer = "List networks."
|
|
62
72
|
end
|
|
@@ -73,6 +83,18 @@ class Morpheus::Cli::NetworksCommand
|
|
|
73
83
|
return 1 if cloud.nil?
|
|
74
84
|
params['zoneId'] = cloud['id']
|
|
75
85
|
end
|
|
86
|
+
if options[:tenant]
|
|
87
|
+
if options[:tenant].to_s !~ /\A\d{1,}\Z/
|
|
88
|
+
account = find_account_by_name_or_id(options[:tenant])
|
|
89
|
+
if account.nil?
|
|
90
|
+
return 1, "Tenant not found by name: #{options[:tenant]}"
|
|
91
|
+
else
|
|
92
|
+
params['tenantId'] = account['id']
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
params['tenantId'] = options[:tenant]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
76
98
|
@networks_interface.setopts(options)
|
|
77
99
|
if options[:dry_run]
|
|
78
100
|
print_dry_run @networks_interface.dry.list(params)
|
|
@@ -109,6 +131,7 @@ class Morpheus::Cli::NetworksCommand
|
|
|
109
131
|
type: network['type'] ? network['type']['name'] : '',
|
|
110
132
|
group: network['group'] ? network['group']['name'] : 'Shared',
|
|
111
133
|
cloud: network['zone'] ? network['zone']['name'] : '',
|
|
134
|
+
tenant: network['owner'] ? network['owner']['name'] : '',
|
|
112
135
|
cidr: network['cidr'],
|
|
113
136
|
pool: network['pool'] ? network['pool']['name'] : '',
|
|
114
137
|
dhcp: network['dhcpServer'] ? 'Yes' : 'No',
|
|
@@ -128,6 +151,7 @@ class Morpheus::Cli::NetworksCommand
|
|
|
128
151
|
type: "Subnet",
|
|
129
152
|
group: network['group'] ? network['group']['name'] : 'Shared',
|
|
130
153
|
cloud: network['zone'] ? network['zone']['name'] : '',
|
|
154
|
+
tenant: network['owner'] ? network['owner']['name'] : '',
|
|
131
155
|
cidr: subnet['cidr'],
|
|
132
156
|
pool: subnet['pool'] ? subnet['pool']['name'] : '',
|
|
133
157
|
dhcp: subnet['dhcpServer'] ? 'Yes' : 'No',
|
|
@@ -139,9 +163,13 @@ class Morpheus::Cli::NetworksCommand
|
|
|
139
163
|
end
|
|
140
164
|
end
|
|
141
165
|
end
|
|
142
|
-
columns = [:id, :name, :labels, :type, :group, :cloud, :cidr, :pool, :dhcp, :subnets, :active, :visibility, :tenants]
|
|
166
|
+
columns = [:id, :name, :labels, :type, :group, :cloud, :tenant, :cidr, :pool, :dhcp, :subnets, :active, :visibility, :tenants]
|
|
143
167
|
if options[:include_fields]
|
|
144
168
|
columns = options[:include_fields]
|
|
169
|
+
else
|
|
170
|
+
if !options[:include_tenants] && !options[:tenant]
|
|
171
|
+
columns.delete(:tenant)
|
|
172
|
+
end
|
|
145
173
|
end
|
|
146
174
|
print cyan
|
|
147
175
|
print as_pretty_table(rows, columns, options)
|
|
@@ -160,6 +188,9 @@ class Morpheus::Cli::NetworksCommand
|
|
|
160
188
|
options = {}
|
|
161
189
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
162
190
|
opts.banner = subcommand_usage("[network]")
|
|
191
|
+
opts.on('--include-tenants','--include-tenants', "Include sub tenant networks when finding network by name") do
|
|
192
|
+
options[:include_tenants] = true
|
|
193
|
+
end
|
|
163
194
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
|
164
195
|
opts.footer = "Get details about a network." + "\n" +
|
|
165
196
|
"[network] is required. This is the name or id of a network."
|
|
@@ -177,11 +208,11 @@ class Morpheus::Cli::NetworksCommand
|
|
|
177
208
|
if args[0].to_s =~ /\A\d{1,}\Z/
|
|
178
209
|
print_dry_run @networks_interface.dry.get(args[0].to_i)
|
|
179
210
|
else
|
|
180
|
-
print_dry_run @networks_interface.dry.list({name:args[0]})
|
|
211
|
+
print_dry_run @networks_interface.dry.list({name:args[0]}, options[:include_tenants])
|
|
181
212
|
end
|
|
182
213
|
return
|
|
183
214
|
end
|
|
184
|
-
network = find_network_by_name_or_id(args[0])
|
|
215
|
+
network = find_network_by_name_or_id(args[0], options[:include_tenants])
|
|
185
216
|
return 1 if network.nil?
|
|
186
217
|
json_response = {'network' => network} # skip redundant request
|
|
187
218
|
# json_response = @networks_interface.get(network['id'])
|
|
@@ -206,6 +237,7 @@ class Morpheus::Cli::NetworksCommand
|
|
|
206
237
|
"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
|
|
207
238
|
"Group" => lambda {|it| it['group'] ? it['group']['name'] : 'Shared' },
|
|
208
239
|
"Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
|
|
240
|
+
"Tenant" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
|
|
209
241
|
"IPv4 Enabled" => 'ipv4Enabled',
|
|
210
242
|
"IPv6 Enabled" => 'ipv6Enabled',
|
|
211
243
|
"CIDR" => 'cidr',
|
|
@@ -4,13 +4,14 @@ class Morpheus::Cli::StorageVolumes
|
|
|
4
4
|
include Morpheus::Cli::CliCommand
|
|
5
5
|
include Morpheus::Cli::RestCommand
|
|
6
6
|
include Morpheus::Cli::StorageVolumesHelper
|
|
7
|
+
include Morpheus::Cli::AccountsHelper
|
|
7
8
|
|
|
8
9
|
set_command_name :'storage-volumes'
|
|
9
10
|
set_command_description "View and manage storage volumes."
|
|
10
|
-
register_subcommands :list, :get, :add, :remove, :resize
|
|
11
|
+
register_subcommands :list, :get, :add, :remove, :resize, :update_tenant
|
|
11
12
|
|
|
12
13
|
# RestCommand settings
|
|
13
|
-
register_interfaces :storage_volumes, :storage_volume_types
|
|
14
|
+
register_interfaces :storage_volumes, :storage_volume_types, :accounts
|
|
14
15
|
set_rest_has_type true
|
|
15
16
|
|
|
16
17
|
protected
|
|
@@ -28,12 +29,28 @@ class Morpheus::Cli::StorageVolumes
|
|
|
28
29
|
opts.on('--category VALUE', String, "Filter by category") do |val|
|
|
29
30
|
params['category'] = val
|
|
30
31
|
end
|
|
32
|
+
opts.on('--include-tenants', '--include-tenants', "Include sub-tenant storage volumes (master tenant only)") do
|
|
33
|
+
options[:include_tenants] = true
|
|
34
|
+
params['includeTenants'] = true
|
|
35
|
+
end
|
|
36
|
+
opts.on('--tenant TENANT', String, "Filter by Tenant Name or ID (master tenant only)") do |val|
|
|
37
|
+
options[:tenant] = val
|
|
38
|
+
end
|
|
31
39
|
# build_standard_list_options(opts, options)
|
|
32
40
|
super
|
|
33
41
|
end
|
|
34
42
|
|
|
35
43
|
def parse_list_options!(args, options, params)
|
|
36
44
|
parse_parameter_as_resource_id!(:storage_server, options, params)
|
|
45
|
+
if options[:tenant]
|
|
46
|
+
if options[:tenant].to_s =~ /\A\d+\Z/
|
|
47
|
+
params['tenantId'] = options[:tenant]
|
|
48
|
+
else
|
|
49
|
+
account = find_account_by_name_or_id(options[:tenant])
|
|
50
|
+
return 1 if account.nil?
|
|
51
|
+
params['tenantId'] = account['id']
|
|
52
|
+
end
|
|
53
|
+
end
|
|
37
54
|
super
|
|
38
55
|
end
|
|
39
56
|
|
|
@@ -122,6 +139,64 @@ class Morpheus::Cli::StorageVolumes
|
|
|
122
139
|
end
|
|
123
140
|
end
|
|
124
141
|
|
|
142
|
+
def update_tenant(args)
|
|
143
|
+
options = {}
|
|
144
|
+
params = {}
|
|
145
|
+
tenant_id = nil
|
|
146
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
147
|
+
opts.banner = subcommand_usage("[volume] --tenant TENANT")
|
|
148
|
+
opts.on('--tenant TENANT', String, "Target Tenant (Account) Name or ID to transfer ownership to.") do |val|
|
|
149
|
+
tenant_id = val
|
|
150
|
+
end
|
|
151
|
+
build_standard_update_options(opts, options)
|
|
152
|
+
opts.footer = <<-EOT
|
|
153
|
+
Transfer ownership of a storage volume to another tenant.
|
|
154
|
+
[volume] is required. This is the name or id of a storage volume.
|
|
155
|
+
--tenant is required unless provided via --payload. This is the name or id of the target tenant.
|
|
156
|
+
Only an unattached volume may be transferred. All authorization and business-rule
|
|
157
|
+
validation is performed by the server; its message is shown verbatim on failure.
|
|
158
|
+
EOT
|
|
159
|
+
end
|
|
160
|
+
optparse.parse!(args)
|
|
161
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
|
162
|
+
# CLI-side validation: require a target tenant unless a full payload is supplied.
|
|
163
|
+
# All other authorization and business rules are validated server-side.
|
|
164
|
+
if !options[:payload] && tenant_id.nil?
|
|
165
|
+
raise_command_error "--tenant is required to transfer ownership.\n#{optparse}"
|
|
166
|
+
end
|
|
167
|
+
connect(options)
|
|
168
|
+
volume = find_volume_by_name_or_id(args[0])
|
|
169
|
+
return 1 if volume.nil?
|
|
170
|
+
id = volume['id']
|
|
171
|
+
passed_options = parse_passed_options(options)
|
|
172
|
+
payload = {}
|
|
173
|
+
if options[:payload]
|
|
174
|
+
payload = options[:payload]
|
|
175
|
+
payload.deep_merge!({storage_volume_object_key => passed_options}) unless passed_options.empty?
|
|
176
|
+
else
|
|
177
|
+
account = find_account_by_name_or_id(tenant_id)
|
|
178
|
+
return 1 if account.nil?
|
|
179
|
+
payload[storage_volume_object_key] = {'tenant' => {'id' => account['id']}}
|
|
180
|
+
payload.deep_merge!({storage_volume_object_key => passed_options}) unless passed_options.empty?
|
|
181
|
+
end
|
|
182
|
+
@storage_volumes_interface.setopts(options)
|
|
183
|
+
if options[:dry_run]
|
|
184
|
+
print_dry_run @storage_volumes_interface.dry.update_tenant(id, payload)
|
|
185
|
+
return 0, nil
|
|
186
|
+
end
|
|
187
|
+
json_response = @storage_volumes_interface.update_tenant(id, payload)
|
|
188
|
+
render_response(json_response, options, storage_volume_object_key) do
|
|
189
|
+
record = json_response[storage_volume_object_key]
|
|
190
|
+
owner_name = (record && record['owner'] ? record['owner']['name'] : (record && record['account'] ? record['account']['name'] : tenant_id))
|
|
191
|
+
print_green_success "Transferred storage volume #{record ? record['name'] : id} to tenant #{owner_name}"
|
|
192
|
+
print_h1 rest_label, [], options
|
|
193
|
+
print cyan
|
|
194
|
+
print_description_list(storage_volume_column_definitions(options), record, options)
|
|
195
|
+
print reset,"\n"
|
|
196
|
+
end
|
|
197
|
+
return 0, nil
|
|
198
|
+
end
|
|
199
|
+
|
|
125
200
|
def find_volume_by_id(id)
|
|
126
201
|
begin
|
|
127
202
|
json_response = @storage_volumes_interface.get(id.to_i)
|