morpheus-cli 3.3.2.6.2 → 3.3.2.7
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/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/cloud_datastores_interface.rb +47 -0
- data/lib/morpheus/api/virtual_images_interface.rb +2 -2
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/cli/app_templates.rb +5 -15
- data/lib/morpheus/cli/cli_command.rb +5 -1
- data/lib/morpheus/cli/cloud_datastores_command.rb +399 -0
- data/lib/morpheus/cli/containers_command.rb +2 -8
- data/lib/morpheus/cli/hosts.rb +10 -21
- data/lib/morpheus/cli/instance_types.rb +4 -10
- data/lib/morpheus/cli/instances.rb +14 -34
- data/lib/morpheus/cli/library_container_scripts_command.rb +5 -12
- data/lib/morpheus/cli/library_container_templates_command.rb +4 -10
- data/lib/morpheus/cli/library_container_types_command.rb +4 -10
- data/lib/morpheus/cli/library_instance_types_command.rb +4 -10
- data/lib/morpheus/cli/library_layouts_command.rb +4 -10
- data/lib/morpheus/cli/library_option_types_command.rb +2 -5
- data/lib/morpheus/cli/library_upgrades_command.rb +4 -10
- data/lib/morpheus/cli/load_balancers.rb +4 -16
- data/lib/morpheus/cli/monitoring_apps_command.rb +5 -14
- data/lib/morpheus/cli/monitoring_checks_command.rb +13 -33
- data/lib/morpheus/cli/monitoring_contacts_command.rb +10 -11
- data/lib/morpheus/cli/monitoring_groups_command.rb +19 -38
- data/lib/morpheus/cli/monitoring_incidents_command.rb +37 -66
- data/lib/morpheus/cli/network_domains_command.rb +7 -16
- data/lib/morpheus/cli/network_groups_command.rb +6 -16
- data/lib/morpheus/cli/network_pool_servers_command.rb +6 -16
- data/lib/morpheus/cli/network_pools_command.rb +6 -16
- data/lib/morpheus/cli/network_proxies_command.rb +6 -16
- data/lib/morpheus/cli/network_services_command.rb +4 -11
- data/lib/morpheus/cli/networks_command.rb +6 -16
- data/lib/morpheus/cli/packages_command.rb +148 -13
- data/lib/morpheus/cli/policies_command.rb +6 -16
- data/lib/morpheus/cli/power_scheduling_command.rb +6 -24
- data/lib/morpheus/cli/recent_activity_command.rb +19 -19
- data/lib/morpheus/cli/remote.rb +7 -8
- data/lib/morpheus/cli/storage_providers_command.rb +6 -16
- data/lib/morpheus/cli/tasks.rb +4 -12
- data/lib/morpheus/cli/user_groups_command.rb +7 -25
- data/lib/morpheus/cli/user_sources_command.rb +9 -21
- data/lib/morpheus/cli/users.rb +6 -17
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/workflows.rb +4 -12
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da32aab0b8c456c30264a444970d2a38f5149d20
|
4
|
+
data.tar.gz: fe160346b150a094cd79a6cc9a52d3d6b7e0db52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53492ec5876825ff11a01c57f9ea5ea3aa0600323c437cdf1afb880ee4cf9ab1f8ccd589de026a4fbc3540b0313beed80c4e236ddc2fe5a9bf97aa883109c2e7
|
7
|
+
data.tar.gz: a94042c2234b42ce0b4fc6325e467a5c8d9181c1c87c44c6ab34c8f383f5d25b43dc78dac06c5b8f307d851c5c1ba1467e6bcd368264dfa9213ba92bf27ecd87
|
@@ -73,6 +73,10 @@ class Morpheus::APIClient
|
|
73
73
|
Morpheus::CloudsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
74
74
|
end
|
75
75
|
|
76
|
+
def cloud_datastores
|
77
|
+
Morpheus::CloudDatastoresInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
78
|
+
end
|
79
|
+
|
76
80
|
def servers
|
77
81
|
Morpheus::ServersInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
78
82
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
|
3
|
+
class Morpheus::CloudDatastoresInterface < Morpheus::APIClient
|
4
|
+
def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
|
5
|
+
@access_token = access_token
|
6
|
+
@refresh_token = refresh_token
|
7
|
+
@base_url = base_url
|
8
|
+
@expires_at = expires_at
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(cloud_id, id, params={})
|
12
|
+
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
13
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/data-stores/#{id}"
|
14
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
15
|
+
opts = {method: :get, url: url, headers: headers}
|
16
|
+
execute(opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def list(cloud_id, params={})
|
20
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/data-stores"
|
21
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
22
|
+
opts = {method: :get, url: url, headers: headers}
|
23
|
+
execute(opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(cloud_id, payload)
|
27
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/data-stores"
|
28
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
29
|
+
opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
|
30
|
+
execute(opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update(cloud_id, id, payload)
|
34
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/data-stores/#{id}"
|
35
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
36
|
+
opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
|
37
|
+
execute(opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy(cloud_id, id, params={})
|
41
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/data-stores/#{id}"
|
42
|
+
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
43
|
+
opts = {method: :delete, url: url, timeout: 30, headers: headers}
|
44
|
+
execute(opts)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -68,14 +68,14 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
|
|
68
68
|
headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/octet-stream'}
|
69
69
|
headers[:params][:filename] = filename
|
70
70
|
payload = image_file
|
71
|
-
execute(method: :post, url: url, headers: headers, payload: payload)
|
71
|
+
execute(method: :post, url: url, headers: headers, payload: payload, timeout: 36000)
|
72
72
|
end
|
73
73
|
|
74
74
|
def upload_by_url(id, file_url)
|
75
75
|
url = "#{@base_url}/api/virtual-images/#{id}/upload"
|
76
76
|
headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/octet-stream'}
|
77
77
|
headers[:params][:url] = file_url
|
78
|
-
execute(method: :post, url: url, headers: headers)
|
78
|
+
execute(method: :post, url: url, headers: headers, timeout: 36000)
|
79
79
|
end
|
80
80
|
|
81
81
|
def destroy_file(id, filename)
|
data/lib/morpheus/cli.rb
CHANGED
@@ -84,6 +84,7 @@ module Morpheus
|
|
84
84
|
load 'morpheus/cli/recent_activity_command.rb'
|
85
85
|
load 'morpheus/cli/groups.rb'
|
86
86
|
load 'morpheus/cli/clouds.rb'
|
87
|
+
load 'morpheus/cli/cloud_datastores_command.rb'
|
87
88
|
load 'morpheus/cli/hosts.rb'
|
88
89
|
load 'morpheus/cli/load_balancers.rb'
|
89
90
|
load 'morpheus/cli/shell.rb'
|
@@ -65,17 +65,14 @@ class Morpheus::Cli::AppTemplates
|
|
65
65
|
json_response = @app_templates_interface.list(params)
|
66
66
|
app_templates = json_response['appTemplates']
|
67
67
|
|
68
|
-
if options[:include_fields]
|
69
|
-
json_response = {"appTemplates" => filter_data(json_response["appTemplates"], options[:include_fields]) }
|
70
|
-
end
|
71
68
|
if options[:json]
|
72
|
-
puts as_json(json_response, options)
|
69
|
+
puts as_json(json_response, options, "appTemplates")
|
73
70
|
return 0
|
74
71
|
elsif options[:csv]
|
75
72
|
puts records_as_csv(json_response['appTemplates'], options)
|
76
73
|
return 0
|
77
74
|
elsif options[:yaml]
|
78
|
-
puts as_yaml(json_response, options)
|
75
|
+
puts as_yaml(json_response, options, "appTemplates")
|
79
76
|
return 0
|
80
77
|
end
|
81
78
|
|
@@ -151,19 +148,12 @@ class Morpheus::Cli::AppTemplates
|
|
151
148
|
end
|
152
149
|
|
153
150
|
if options[:json]
|
154
|
-
|
155
|
-
json_response = {"appTemplate" => filter_data(json_response["appTemplate"], options[:include_fields]) }
|
156
|
-
end
|
157
|
-
puts as_json(json_response, options)
|
151
|
+
puts as_json(json_response, options, "appTemplate")
|
158
152
|
return 0
|
159
153
|
elsif options[:yaml]
|
160
|
-
|
161
|
-
json_response = {"appTemplate" => filter_data(json_response["appTemplate"], options[:include_fields]) }
|
162
|
-
end
|
163
|
-
puts as_yaml(json_response, options)
|
154
|
+
puts as_yaml(json_response, options, "appTemplate")
|
164
155
|
return 0
|
165
|
-
|
166
|
-
if options[:csv]
|
156
|
+
elsif options[:csv]
|
167
157
|
puts records_as_csv([json_response['appTemplate']], options)
|
168
158
|
return 0
|
169
159
|
end
|
@@ -389,7 +389,6 @@ module Morpheus
|
|
389
389
|
options[:format] = :json
|
390
390
|
options[:pretty_json] = false
|
391
391
|
end
|
392
|
-
|
393
392
|
opts.add_hidden_option('json-raw') if opts.is_a?(Morpheus::Cli::OptionParser)
|
394
393
|
|
395
394
|
when :yaml
|
@@ -397,6 +396,11 @@ module Morpheus
|
|
397
396
|
options[:yaml] = true
|
398
397
|
options[:format] = :yaml
|
399
398
|
end
|
399
|
+
opts.on(nil, '--yml', "alias for --yaml") do
|
400
|
+
options[:yaml] = true
|
401
|
+
options[:format] = :yaml
|
402
|
+
end
|
403
|
+
opts.add_hidden_option('yml') if opts.is_a?(Morpheus::Cli::OptionParser)
|
400
404
|
|
401
405
|
when :csv
|
402
406
|
opts.on(nil, '--csv', "CSV Output") do
|
@@ -0,0 +1,399 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'optparse'
|
3
|
+
require 'filesize'
|
4
|
+
require 'table_print'
|
5
|
+
require 'morpheus/cli/cli_command'
|
6
|
+
require 'morpheus/cli/mixins/infrastructure_helper'
|
7
|
+
|
8
|
+
class Morpheus::Cli::CloudDatastoresCommand
|
9
|
+
include Morpheus::Cli::CliCommand
|
10
|
+
include Morpheus::Cli::InfrastructureHelper
|
11
|
+
|
12
|
+
# set_command_name :'cloud-datastores'
|
13
|
+
set_command_name :'datastores'
|
14
|
+
|
15
|
+
register_subcommands :list, :get, :update
|
16
|
+
|
17
|
+
def initialize()
|
18
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
19
|
+
end
|
20
|
+
|
21
|
+
def connect(opts)
|
22
|
+
@api_client = establish_remote_appliance_connection(opts)
|
23
|
+
@cloud_datastores_interface = @api_client.cloud_datastores
|
24
|
+
@clouds_interface = @api_client.clouds
|
25
|
+
@options_interface = @api_client.options
|
26
|
+
end
|
27
|
+
|
28
|
+
def handle(args)
|
29
|
+
handle_subcommand(args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def list(args)
|
33
|
+
cloud_id = nil
|
34
|
+
options = {}
|
35
|
+
params = {}
|
36
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
37
|
+
opts.banner = subcommand_usage("-c [cloud]")
|
38
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
|
39
|
+
cloud_id = val
|
40
|
+
end
|
41
|
+
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
|
42
|
+
opts.footer = "List datastores for a cloud." + "\n" +
|
43
|
+
"-c [cloud] is required. This is the name or id of the cloud."
|
44
|
+
end
|
45
|
+
optparse.parse!(args)
|
46
|
+
connect(options)
|
47
|
+
begin
|
48
|
+
# load cloud
|
49
|
+
if cloud_id.nil?
|
50
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: [cloud]\n#{optparse}"
|
51
|
+
return 1
|
52
|
+
end
|
53
|
+
cloud = find_cloud_by_name_or_id(cloud_id)
|
54
|
+
return 1 if cloud.nil?
|
55
|
+
|
56
|
+
params.merge!(parse_list_options(options))
|
57
|
+
if options[:dry_run]
|
58
|
+
print_dry_run @cloud_datastores_interface.dry.list(cloud['id'], params)
|
59
|
+
return
|
60
|
+
end
|
61
|
+
json_response = @cloud_datastores_interface.list(cloud['id'], params)
|
62
|
+
datastores = json_response["datastores"]
|
63
|
+
if options[:json]
|
64
|
+
puts as_json(json_response, options, "datastores")
|
65
|
+
return 0
|
66
|
+
elsif options[:yaml]
|
67
|
+
puts as_yaml(json_response, options, "datastores")
|
68
|
+
return 0
|
69
|
+
elsif options[:csv]
|
70
|
+
puts records_as_csv(datastores, options)
|
71
|
+
return 0
|
72
|
+
end
|
73
|
+
title = "Morpheus Datastores - Cloud: #{cloud['name']}"
|
74
|
+
subtitles = []
|
75
|
+
subtitles += parse_list_subtitles(options)
|
76
|
+
print_h1 title, subtitles
|
77
|
+
if datastores.empty?
|
78
|
+
print cyan,"No datastores found.",reset,"\n"
|
79
|
+
else
|
80
|
+
rows = datastores.collect {|datastore|
|
81
|
+
row = {
|
82
|
+
id: datastore['id'],
|
83
|
+
name: datastore['name'],
|
84
|
+
type: datastore['type'].to_s.capitalize,
|
85
|
+
#cloud: datastore['zone'] ? datastore['zone']['name'] : '',
|
86
|
+
capacity: datastore['freeSpace'] ? Filesize.from("#{datastore['freeSpace']} B").pretty.strip : "Unknown",
|
87
|
+
online: format_boolean(datastore['online']),
|
88
|
+
active: format_boolean(datastore['active']),
|
89
|
+
visibility: datastore['visibility'].to_s.capitalize,
|
90
|
+
tenants: datastore['tenants'] ? datastore['tenants'].collect {|it| it['name'] }.uniq.join(', ') : ''
|
91
|
+
# owner: datastore['owner'] ? datastore['owner']['name'] : ''
|
92
|
+
}
|
93
|
+
row
|
94
|
+
}
|
95
|
+
columns = [:id, :name, :type, :capacity, :online, :active, :visibility, :tenants]
|
96
|
+
if options[:include_fields]
|
97
|
+
columns = options[:include_fields]
|
98
|
+
end
|
99
|
+
print cyan
|
100
|
+
print as_pretty_table(rows, columns, options)
|
101
|
+
print reset
|
102
|
+
print_results_pagination(json_response, {:label => "datastore", :n_label => "datastores"})
|
103
|
+
end
|
104
|
+
print reset,"\n"
|
105
|
+
return 0
|
106
|
+
rescue RestClient::Exception => e
|
107
|
+
print_rest_exception(e, options)
|
108
|
+
exit 1
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def get(args)
|
113
|
+
cloud_id = nil
|
114
|
+
options = {}
|
115
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
116
|
+
opts.banner = subcommand_usage("[datastore]")
|
117
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
|
118
|
+
cloud_id = val
|
119
|
+
end
|
120
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
121
|
+
opts.footer = "Get details about a datastore." + "\n" +
|
122
|
+
"[datastore] is required. This is the name or id of a datastore." + "\n" +
|
123
|
+
"-c [cloud] is required. This is the name or id of the cloud."
|
124
|
+
end
|
125
|
+
optparse.parse!(args)
|
126
|
+
if args.count != 1
|
127
|
+
print_error Morpheus::Terminal.angry_prompt
|
128
|
+
puts_error "#{command_name} missing argument: [datastore]\n#{optparse}"
|
129
|
+
return 1
|
130
|
+
end
|
131
|
+
connect(options)
|
132
|
+
begin
|
133
|
+
# load cloud
|
134
|
+
if cloud_id.nil?
|
135
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: [cloud]\n#{optparse}"
|
136
|
+
return 1
|
137
|
+
end
|
138
|
+
cloud = find_cloud_by_name_or_id(cloud_id)
|
139
|
+
return 1 if cloud.nil?
|
140
|
+
|
141
|
+
if options[:dry_run]
|
142
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
143
|
+
print_dry_run @cloud_datastores_interface.dry.get(cloud['id'], args[0].to_i)
|
144
|
+
else
|
145
|
+
print_dry_run @cloud_datastores_interface.dry.list(cloud['id'], {name:args[0]})
|
146
|
+
end
|
147
|
+
return
|
148
|
+
end
|
149
|
+
datastore = find_datastore_by_name_or_id(cloud['id'], args[0])
|
150
|
+
return 1 if datastore.nil?
|
151
|
+
json_response = {'datastore' => datastore} # skip redundant request
|
152
|
+
# json_response = @datastores_interface.get(datastore['id'])
|
153
|
+
datastore = json_response['datastore']
|
154
|
+
if options[:json]
|
155
|
+
puts as_json(json_response, options, "datastore")
|
156
|
+
return 0
|
157
|
+
elsif options[:yaml]
|
158
|
+
puts as_yaml(json_response, options, "datastore")
|
159
|
+
return 0
|
160
|
+
elsif options[:csv]
|
161
|
+
puts records_as_csv([datastore], options)
|
162
|
+
return 0
|
163
|
+
end
|
164
|
+
print_h1 "Datastore Details"
|
165
|
+
print cyan
|
166
|
+
description_cols = {
|
167
|
+
"ID" => 'id',
|
168
|
+
"Name" => 'name',
|
169
|
+
"Type" => lambda {|it| it['type'].to_s.capitalize },
|
170
|
+
"Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
|
171
|
+
"Capacity" => lambda {|it| it['freeSpace'] ? Filesize.from("#{it['freeSpace']} B").pretty.strip : "Unknown" },
|
172
|
+
"Online" => lambda {|it| format_boolean(it['online']) },
|
173
|
+
"Active" => lambda {|it| format_boolean(it['active']) },
|
174
|
+
"Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
|
175
|
+
"Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' },
|
176
|
+
# "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
|
177
|
+
}
|
178
|
+
print_description_list(description_cols, datastore)
|
179
|
+
|
180
|
+
if datastore['resourcePermission'].nil?
|
181
|
+
print "\n", "No group access found", "\n"
|
182
|
+
else
|
183
|
+
print_h2 "Group Access"
|
184
|
+
rows = []
|
185
|
+
if datastore['resourcePermission']['all']
|
186
|
+
rows.push({"name" => 'All'})
|
187
|
+
end
|
188
|
+
if datastore['resourcePermission']['sites']
|
189
|
+
datastore['resourcePermission']['sites'].each do |site|
|
190
|
+
rows.push(site)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
rows = rows.collect do |site|
|
194
|
+
# {group: site['name'], default: site['default'] ? 'Yes' : ''}
|
195
|
+
{group: site['name']}
|
196
|
+
end
|
197
|
+
# columns = [:group, :default]
|
198
|
+
columns = [:group]
|
199
|
+
print cyan
|
200
|
+
print as_pretty_table(rows, columns)
|
201
|
+
end
|
202
|
+
|
203
|
+
print reset,"\n"
|
204
|
+
return 0
|
205
|
+
rescue RestClient::Exception => e
|
206
|
+
print_rest_exception(e, options)
|
207
|
+
return 1
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def update(args)
|
212
|
+
options = {}
|
213
|
+
cloud_id = nil
|
214
|
+
tenants = nil
|
215
|
+
group_access_all = nil
|
216
|
+
group_access_list = nil
|
217
|
+
group_defaults_list = nil
|
218
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
219
|
+
opts.banner = subcommand_usage("[datastore] -c [cloud] [options]")
|
220
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
|
221
|
+
cloud_id = val
|
222
|
+
end
|
223
|
+
opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
|
224
|
+
group_access_all = val.to_s == 'on' || val.to_s == 'true'
|
225
|
+
end
|
226
|
+
opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
|
227
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
228
|
+
group_access_list = []
|
229
|
+
else
|
230
|
+
group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
231
|
+
end
|
232
|
+
end
|
233
|
+
# opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
|
234
|
+
# if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
235
|
+
# group_defaults_list = []
|
236
|
+
# else
|
237
|
+
# group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
238
|
+
# end
|
239
|
+
# end
|
240
|
+
opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
|
241
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
242
|
+
options['tenants'] = []
|
243
|
+
else
|
244
|
+
options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
245
|
+
end
|
246
|
+
end
|
247
|
+
opts.on('--visibility [private|public]', String, "Visibility") do |val|
|
248
|
+
options['visibility'] = val
|
249
|
+
end
|
250
|
+
opts.on('--active [on|off]', String, "Can be used to disable a datastore") do |val|
|
251
|
+
options['active'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
252
|
+
end
|
253
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
254
|
+
opts.footer = "Update a datastore." + "\n" +
|
255
|
+
"[datastore] is required. This is the id of a datstore."
|
256
|
+
end
|
257
|
+
optparse.parse!(args)
|
258
|
+
if args.count != 1
|
259
|
+
print_error Morpheus::Terminal.angry_prompt
|
260
|
+
puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
|
261
|
+
return 1
|
262
|
+
end
|
263
|
+
connect(options)
|
264
|
+
|
265
|
+
begin
|
266
|
+
# load cloud
|
267
|
+
if cloud_id.nil?
|
268
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: [cloud]\n#{optparse}"
|
269
|
+
return 1
|
270
|
+
end
|
271
|
+
cloud = find_cloud_by_name_or_id(cloud_id)
|
272
|
+
return 1 if cloud.nil?
|
273
|
+
|
274
|
+
datastore = find_datastore_by_name_or_id(cloud['id'], args[0])
|
275
|
+
return 1 if datastore.nil?
|
276
|
+
|
277
|
+
# merge -O options into normally parsed options
|
278
|
+
options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
279
|
+
|
280
|
+
# construct payload
|
281
|
+
payload = nil
|
282
|
+
if options[:payload]
|
283
|
+
payload = options[:payload]
|
284
|
+
else
|
285
|
+
# prompt for datastore options
|
286
|
+
payload = {
|
287
|
+
'datastore' => {
|
288
|
+
}
|
289
|
+
}
|
290
|
+
|
291
|
+
# allow arbitrary -O options
|
292
|
+
payload['datastore'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
293
|
+
|
294
|
+
|
295
|
+
# Group Access
|
296
|
+
if group_access_all != nil
|
297
|
+
payload['resourcePermissions'] ||= {}
|
298
|
+
payload['resourcePermissions']['all'] = group_access_all
|
299
|
+
end
|
300
|
+
if group_access_list != nil
|
301
|
+
payload['resourcePermissions'] ||= {}
|
302
|
+
payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
|
303
|
+
site = {"id" => site_id.to_i}
|
304
|
+
if group_defaults_list && group_defaults_list.include?(site_id)
|
305
|
+
site["default"] = true
|
306
|
+
end
|
307
|
+
site
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
# Tenants
|
312
|
+
if options['tenants']
|
313
|
+
payload['tenantPermissions'] = {}
|
314
|
+
payload['tenantPermissions']['accounts'] = options['tenants']
|
315
|
+
end
|
316
|
+
|
317
|
+
# Active
|
318
|
+
if options['active'] != nil
|
319
|
+
payload['datastore']['active'] = options['active']
|
320
|
+
end
|
321
|
+
|
322
|
+
# Visibility
|
323
|
+
if options['visibility'] != nil
|
324
|
+
payload['datastore']['visibility'] = options['visibility']
|
325
|
+
end
|
326
|
+
|
327
|
+
end
|
328
|
+
|
329
|
+
if options[:dry_run]
|
330
|
+
print_dry_run @cloud_datastores_interface.dry.update(cloud['id'], datastore["id"], payload)
|
331
|
+
return
|
332
|
+
end
|
333
|
+
json_response = @cloud_datastores_interface.update(cloud['id'], datastore["id"], payload)
|
334
|
+
if options[:json]
|
335
|
+
puts as_json(json_response)
|
336
|
+
else
|
337
|
+
datastore = json_response['datastore']
|
338
|
+
print_green_success "Updated datastore #{datastore['name']}"
|
339
|
+
get([datastore['id'], "-c", cloud['id'].to_s]) # argh, to_s needed on option values..
|
340
|
+
end
|
341
|
+
return 0
|
342
|
+
rescue RestClient::Exception => e
|
343
|
+
print_rest_exception(e, options)
|
344
|
+
return 1
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
private
|
349
|
+
|
350
|
+
|
351
|
+
def find_datastore_by_name_or_id(cloud_id, val)
|
352
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
353
|
+
return find_datastore_by_id(cloud_id, val)
|
354
|
+
else
|
355
|
+
return find_datastore_by_name(cloud_id, val)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def find_datastore_by_id(cloud_id, id)
|
360
|
+
begin
|
361
|
+
json_response = @cloud_datastores_interface.get(cloud_id, id.to_i)
|
362
|
+
return json_response['datastore']
|
363
|
+
rescue RestClient::Exception => e
|
364
|
+
if e.response && e.response.code == 404
|
365
|
+
print_red_alert "Datastore not found by id #{id}"
|
366
|
+
return nil
|
367
|
+
else
|
368
|
+
raise e
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
def find_datastore_by_name(cloud_id, name)
|
374
|
+
json_response = @cloud_datastores_interface.list(cloud_id, {name: name.to_s})
|
375
|
+
datastores = json_response['datastores']
|
376
|
+
if datastores.empty?
|
377
|
+
print_red_alert "Datastore not found by name #{name}"
|
378
|
+
return nil
|
379
|
+
elsif datastores.size > 1
|
380
|
+
print_red_alert "#{datastores.size} datastores found by name #{name}"
|
381
|
+
# print_datastores_table(datastores, {color: red})
|
382
|
+
rows = datastores.collect do |datastore|
|
383
|
+
{id: it['id'], name: it['name']}
|
384
|
+
end
|
385
|
+
print red
|
386
|
+
tp rows, [:id, :name]
|
387
|
+
print reset,"\n"
|
388
|
+
return nil
|
389
|
+
else
|
390
|
+
datastore = datastores[0]
|
391
|
+
# merge in tenants map
|
392
|
+
if json_response['tenants'] && json_response['tenants'][datastore['id']]
|
393
|
+
datastore['tenants'] = json_response['tenants'][datastore['id']]
|
394
|
+
end
|
395
|
+
return datastore
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|