morpheus-cli 3.3.2.7 → 3.4.0
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/account_groups_interface.rb +54 -0
- data/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/virtual_images_interface.rb +14 -9
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/cli/account_groups_command.rb +555 -0
- data/lib/morpheus/cli/accounts.rb +8 -0
- data/lib/morpheus/cli/groups.rb +1 -1
- data/lib/morpheus/cli/policies_command.rb +3 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +236 -123
- 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: 20e78e38f9bcbdad9a49fd08311ad25c96472067
|
4
|
+
data.tar.gz: cf420de6d192d9c5514eccd78f17aa4850df4c4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85eb7b4fd8b3a901884495d0b9049c42896ed7f5e2e9292359a936f2895571c0a09527b8324149f9ad211733e18cc9ffb9add5a965ee9619a4bc46e9e0fc182d
|
7
|
+
data.tar.gz: 06982a9e0a0564147a6781709954c5f55df16438a26652125b8346ee3dc51f95f487d54b153c844038a7f6cfe718d79dde62bc3768f74dea8f25635cad39bc51
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
|
3
|
+
class Morpheus::AccountGroupsInterface < 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(account_id, id, params={})
|
12
|
+
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
13
|
+
url = "#{@base_url}/api/accounts/#{account_id}/groups/#{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(account_id, params={})
|
20
|
+
url = "#{@base_url}/api/accounts/#{account_id}/groups"
|
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(account_id, payload)
|
27
|
+
url = "#{@base_url}/api/accounts/#{account_id}/groups"
|
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(account_id, id, payload)
|
34
|
+
url = "#{@base_url}/api/accounts/#{account_id}/groups/#{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(account_id, id, params={})
|
41
|
+
url = "#{@base_url}/api/accounts/#{account_id}/groups/#{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
|
+
def update_zones(account_id, id, payload)
|
48
|
+
url = "#{@base_url}/api/accounts/#{account_id}/groups/#{id}/update-zones"
|
49
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
50
|
+
opts = {method: :put, url: url, timeout: 30, headers: headers, payload: payload.to_json}
|
51
|
+
execute(opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -69,6 +69,10 @@ class Morpheus::APIClient
|
|
69
69
|
Morpheus::GroupsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
70
70
|
end
|
71
71
|
|
72
|
+
def account_groups
|
73
|
+
Morpheus::AccountGroupsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
74
|
+
end
|
75
|
+
|
72
76
|
def clouds
|
73
77
|
Morpheus::CloudsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
74
78
|
end
|
@@ -20,7 +20,6 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
|
|
20
20
|
def get(options=nil)
|
21
21
|
url = "#{@base_url}/api/virtual-images"
|
22
22
|
headers = { params: {}, authorization: "Bearer #{@access_token}" }
|
23
|
-
|
24
23
|
if options.is_a?(Hash)
|
25
24
|
headers[:params].merge!(options)
|
26
25
|
elsif options.is_a?(Numeric)
|
@@ -31,20 +30,25 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
|
|
31
30
|
execute(method: :get, url: url, headers: headers)
|
32
31
|
end
|
33
32
|
|
34
|
-
def
|
35
|
-
url = "#{@base_url}/api/virtual-images
|
36
|
-
headers = { :authorization
|
37
|
-
|
33
|
+
def list(options=nil)
|
34
|
+
url = "#{@base_url}/api/virtual-images"
|
35
|
+
headers = { params: {}, authorization: "Bearer #{@access_token}" }
|
36
|
+
headers[:params].merge!(options)
|
37
|
+
execute(method: :get, url: url, headers: headers)
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
def create(options)
|
40
|
+
def create(payload)
|
42
41
|
url = "#{@base_url}/api/virtual-images"
|
43
42
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
44
|
-
payload = options
|
45
43
|
execute(method: :post, url: url, headers: headers, payload: payload.to_json)
|
46
44
|
end
|
47
45
|
|
46
|
+
def update(id, payload)
|
47
|
+
url = "#{@base_url}/api/virtual-images/#{id}"
|
48
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
49
|
+
execute(method: :put, url: url, headers: headers, payload: payload.to_json)
|
50
|
+
end
|
51
|
+
|
48
52
|
def destroy(id)
|
49
53
|
url = "#{@base_url}/api/virtual-images/#{id}"
|
50
54
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
@@ -71,10 +75,11 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
|
|
71
75
|
execute(method: :post, url: url, headers: headers, payload: payload, timeout: 36000)
|
72
76
|
end
|
73
77
|
|
74
|
-
def upload_by_url(id, file_url)
|
78
|
+
def upload_by_url(id, file_url, filename=nil)
|
75
79
|
url = "#{@base_url}/api/virtual-images/#{id}/upload"
|
76
80
|
headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/octet-stream'}
|
77
81
|
headers[:params][:url] = file_url
|
82
|
+
headers[:params][:filename] = filename if filename
|
78
83
|
execute(method: :post, url: url, headers: headers, timeout: 36000)
|
79
84
|
end
|
80
85
|
|
data/lib/morpheus/cli.rb
CHANGED
@@ -101,6 +101,7 @@ module Morpheus
|
|
101
101
|
load 'morpheus/cli/security_groups.rb'
|
102
102
|
load 'morpheus/cli/security_group_rules.rb'
|
103
103
|
load 'morpheus/cli/accounts.rb'
|
104
|
+
load 'morpheus/cli/account_groups_command.rb'
|
104
105
|
load 'morpheus/cli/users.rb'
|
105
106
|
load 'morpheus/cli/user_groups_command.rb'
|
106
107
|
load 'morpheus/cli/user_sources_command.rb'
|
@@ -0,0 +1,555 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
require 'io/console'
|
4
|
+
require 'rest_client'
|
5
|
+
require 'optparse'
|
6
|
+
require 'table_print'
|
7
|
+
require 'morpheus/cli/cli_command'
|
8
|
+
require 'morpheus/cli/mixins/accounts_helper'
|
9
|
+
require 'morpheus/cli/mixins/infrastructure_helper'
|
10
|
+
require 'morpheus/logging'
|
11
|
+
|
12
|
+
class Morpheus::Cli::AccountGroupsCommand
|
13
|
+
include Morpheus::Cli::CliCommand
|
14
|
+
include Morpheus::Cli::AccountsHelper
|
15
|
+
include Morpheus::Cli::InfrastructureHelper
|
16
|
+
|
17
|
+
|
18
|
+
register_subcommands :list, :get, :add, :update, :add_cloud, :remove_cloud, :remove
|
19
|
+
|
20
|
+
# lives under image-builder domain right now
|
21
|
+
set_command_hidden
|
22
|
+
def command_name
|
23
|
+
"account groups"
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize()
|
27
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
28
|
+
end
|
29
|
+
|
30
|
+
def connect(opts)
|
31
|
+
@api_client = establish_remote_appliance_connection(opts)
|
32
|
+
@account_groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).account_groups
|
33
|
+
@accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
|
34
|
+
|
35
|
+
@groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
|
36
|
+
@clouds_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).clouds
|
37
|
+
end
|
38
|
+
|
39
|
+
def handle(args)
|
40
|
+
handle_subcommand(args)
|
41
|
+
end
|
42
|
+
|
43
|
+
def list(args)
|
44
|
+
options = {}
|
45
|
+
params = {}
|
46
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
47
|
+
opts.banner = subcommand_usage()
|
48
|
+
build_common_options(opts, options, [:account, :list, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
49
|
+
opts.footer = "List groups for a tenant account."
|
50
|
+
end
|
51
|
+
optparse.parse!(args)
|
52
|
+
connect(options)
|
53
|
+
begin
|
54
|
+
# load account
|
55
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
56
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
57
|
+
return 1
|
58
|
+
end
|
59
|
+
account = find_account_from_options(options)
|
60
|
+
return 1 if account.nil?
|
61
|
+
account_id = account['id']
|
62
|
+
|
63
|
+
params.merge!(parse_list_options(options))
|
64
|
+
|
65
|
+
if options[:dry_run]
|
66
|
+
print_dry_run @account_groups_interface.dry.list(account['id'], params)
|
67
|
+
return
|
68
|
+
end
|
69
|
+
json_response = @account_groups_interface.list(account['id'], params)
|
70
|
+
if options[:json]
|
71
|
+
puts as_json(json_response, options, "groups")
|
72
|
+
return 0
|
73
|
+
elsif options[:yaml]
|
74
|
+
puts as_yaml(json_response, options, "groups")
|
75
|
+
return 0
|
76
|
+
elsif options[:csv]
|
77
|
+
puts records_as_csv(json_response["groups"], options)
|
78
|
+
return 0
|
79
|
+
end
|
80
|
+
groups = json_response['groups']
|
81
|
+
title = "Morpheus Groups - Account: #{account['name']}"
|
82
|
+
subtitles = []
|
83
|
+
subtitles += parse_list_subtitles(options)
|
84
|
+
print_h1 title, subtitles
|
85
|
+
if groups.empty?
|
86
|
+
print yellow,"No groups currently configured.",reset,"\n"
|
87
|
+
else
|
88
|
+
print_groups_table(groups)
|
89
|
+
print_results_pagination(json_response)
|
90
|
+
end
|
91
|
+
print reset,"\n"
|
92
|
+
rescue RestClient::Exception => e
|
93
|
+
print_rest_exception(e, options)
|
94
|
+
exit 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def get(args)
|
99
|
+
options = {}
|
100
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
101
|
+
opts.banner = subcommand_usage("[group]")
|
102
|
+
build_common_options(opts, options, [:account, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
103
|
+
opts.footer = "This outputs details about a specific group for a tenant account."
|
104
|
+
end
|
105
|
+
optparse.parse!(args)
|
106
|
+
if args.count < 1
|
107
|
+
puts optparse
|
108
|
+
exit 1
|
109
|
+
end
|
110
|
+
connect(options)
|
111
|
+
begin
|
112
|
+
# load account
|
113
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
114
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
115
|
+
return 1
|
116
|
+
end
|
117
|
+
account = find_account_from_options(options)
|
118
|
+
return 1 if account.nil?
|
119
|
+
account_id = account['id']
|
120
|
+
|
121
|
+
if options[:dry_run]
|
122
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
123
|
+
print_dry_run @account_groups_interface.dry.get(account_id, args[0].to_i)
|
124
|
+
else
|
125
|
+
print_dry_run @account_groups_interface.dry.get(account_id, {name: args[0]})
|
126
|
+
end
|
127
|
+
return
|
128
|
+
end
|
129
|
+
|
130
|
+
group = find_account_group_by_name_or_id(account_id, args[0])
|
131
|
+
return 1 if group.nil?
|
132
|
+
# skip redundant request
|
133
|
+
# json_response = @account_groups_interface.dry.get(account_id, args[0].to_i)
|
134
|
+
json_response = {"group" => group}
|
135
|
+
|
136
|
+
if options[:json]
|
137
|
+
puts as_json(json_response, options, "group")
|
138
|
+
return 0
|
139
|
+
elsif options[:yaml]
|
140
|
+
puts as_yaml(json_response, options, "group")
|
141
|
+
return 0
|
142
|
+
elsif options[:csv]
|
143
|
+
puts records_as_csv(json_response["group"], options)
|
144
|
+
return 0
|
145
|
+
end
|
146
|
+
|
147
|
+
print_h1 "Group Details"
|
148
|
+
print cyan
|
149
|
+
description_cols = {
|
150
|
+
"ID" => 'id',
|
151
|
+
"Name" => 'name',
|
152
|
+
"Code" => 'code',
|
153
|
+
"Location" => 'location',
|
154
|
+
"Clouds" => lambda {|it| it['zones'].collect {|z| z['name'] }.join(', ') },
|
155
|
+
"Hosts" => 'serverCount',
|
156
|
+
"Tenant" => lambda {|it| account['name'] },
|
157
|
+
}
|
158
|
+
print_description_list(description_cols, group)
|
159
|
+
# puts "ID: #{group['id']}"
|
160
|
+
# puts "Name: #{group['name']}"
|
161
|
+
# puts "Code: #{group['code']}"
|
162
|
+
# puts "Location: #{group['location']}"
|
163
|
+
# puts "Clouds: #{group['zones'].collect {|it| it['name'] }.join(', ')}"
|
164
|
+
# puts "Hosts: #{group['serverCount']}"
|
165
|
+
|
166
|
+
print reset,"\n"
|
167
|
+
|
168
|
+
#puts instance
|
169
|
+
rescue RestClient::Exception => e
|
170
|
+
print_rest_exception(e, options)
|
171
|
+
exit 1
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def add(args)
|
176
|
+
options = {}
|
177
|
+
params = {}
|
178
|
+
use_it = false
|
179
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
180
|
+
opts.banner = subcommand_usage("[name]")
|
181
|
+
build_option_type_options(opts, options, add_group_option_types())
|
182
|
+
# opts.on( '-l', '--location LOCATION', "Location" ) do |val|
|
183
|
+
# params[:location] = val
|
184
|
+
# end
|
185
|
+
|
186
|
+
build_common_options(opts, options, [:account, :options, :json, :dry_run, :remote])
|
187
|
+
opts.footer = "Create a new group for a tenant account."
|
188
|
+
end
|
189
|
+
optparse.parse!(args)
|
190
|
+
# if args.count < 1
|
191
|
+
# puts optparse
|
192
|
+
# exit 1
|
193
|
+
# end
|
194
|
+
connect(options)
|
195
|
+
begin
|
196
|
+
# load account
|
197
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
198
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
199
|
+
return 1
|
200
|
+
end
|
201
|
+
account = find_account_from_options(options)
|
202
|
+
return 1 if account.nil?
|
203
|
+
account_id = account['id']
|
204
|
+
|
205
|
+
group_payload = {}
|
206
|
+
if args[0]
|
207
|
+
group_payload[:name] = args[0]
|
208
|
+
options[:options]['name'] = args[0] # to skip prompt
|
209
|
+
end
|
210
|
+
if params[:location]
|
211
|
+
group_payload[:name] = params[:location]
|
212
|
+
options[:options]['location'] = params[:location] # to skip prompt
|
213
|
+
end
|
214
|
+
all_option_types = add_group_option_types()
|
215
|
+
params = Morpheus::Cli::OptionTypes.prompt(all_option_types, options[:options], @api_client, {})
|
216
|
+
group_payload.merge!(params)
|
217
|
+
payload = {group: group_payload}
|
218
|
+
|
219
|
+
if options[:dry_run]
|
220
|
+
print_dry_run @account_groups_interface.dry.create(account['id'], payload)
|
221
|
+
return
|
222
|
+
end
|
223
|
+
json_response = @account_groups_interface.create(account['id'], payload)
|
224
|
+
group = json_response['group']
|
225
|
+
|
226
|
+
if options[:json]
|
227
|
+
print JSON.pretty_generate(json_response)
|
228
|
+
print "\n"
|
229
|
+
else
|
230
|
+
print_green_success "Added group #{group['name']} to account #{account['name']}"
|
231
|
+
list(["-A", account['id'].to_s])
|
232
|
+
end
|
233
|
+
rescue RestClient::Exception => e
|
234
|
+
print_rest_exception(e, options)
|
235
|
+
exit 1
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def update(args)
|
240
|
+
options = {}
|
241
|
+
params = {}
|
242
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
243
|
+
opts.banner = subcommand_usage("[group] [options]")
|
244
|
+
build_option_type_options(opts, options, update_group_option_types())
|
245
|
+
# opts.on( '-l', '--location LOCATION', "Location" ) do |val|
|
246
|
+
# params[:location] = val
|
247
|
+
# end
|
248
|
+
build_common_options(opts, options, [:account, :options, :json, :dry_run, :remote])
|
249
|
+
opts.footer = "Update an existing group for a tenant account."
|
250
|
+
end
|
251
|
+
optparse.parse!(args)
|
252
|
+
if args.count < 1
|
253
|
+
puts optparse
|
254
|
+
exit 1
|
255
|
+
end
|
256
|
+
connect(options)
|
257
|
+
begin
|
258
|
+
# load account
|
259
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
260
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
261
|
+
return 1
|
262
|
+
end
|
263
|
+
account = find_account_from_options(options)
|
264
|
+
return 1 if account.nil?
|
265
|
+
account_id = account['id']
|
266
|
+
|
267
|
+
group = find_account_group_by_name_or_id(account_id, args[0])
|
268
|
+
return 1 if group.nil?
|
269
|
+
|
270
|
+
group_payload = {id: group['id']}
|
271
|
+
|
272
|
+
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
273
|
+
|
274
|
+
if params.empty?
|
275
|
+
puts optparse
|
276
|
+
return 1
|
277
|
+
end
|
278
|
+
|
279
|
+
group_payload.merge!(params)
|
280
|
+
|
281
|
+
payload = {group: group_payload}
|
282
|
+
|
283
|
+
if options[:dry_run]
|
284
|
+
print_dry_run @account_groups_interface.dry.update(account['id'], group['id'], payload)
|
285
|
+
return
|
286
|
+
end
|
287
|
+
json_response = @account_groups_interface.update(account['id'], group['id'], payload)
|
288
|
+
if options[:json]
|
289
|
+
print JSON.pretty_generate(json_response)
|
290
|
+
print "\n"
|
291
|
+
else
|
292
|
+
#list(["-A", account['id'].to_s])
|
293
|
+
get([group["id"].to_s, "-A", account['id'].to_s])
|
294
|
+
end
|
295
|
+
rescue RestClient::Exception => e
|
296
|
+
print_rest_exception(e, options)
|
297
|
+
exit 1
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def add_cloud(args)
|
302
|
+
options = {}
|
303
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
304
|
+
opts.banner = subcommand_usage("[group]", "[cloud]")
|
305
|
+
build_common_options(opts, options, [:account, :json, :dry_run, :remote])
|
306
|
+
opts.footer = "Add a cloud to a group."
|
307
|
+
end
|
308
|
+
optparse.parse!(args)
|
309
|
+
if args.count < 2
|
310
|
+
puts optparse
|
311
|
+
exit 1
|
312
|
+
end
|
313
|
+
connect(options)
|
314
|
+
begin
|
315
|
+
# load account
|
316
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
317
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
318
|
+
return 1
|
319
|
+
end
|
320
|
+
account = find_account_from_options(options)
|
321
|
+
return 1 if account.nil?
|
322
|
+
account_id = account['id']
|
323
|
+
|
324
|
+
group = find_account_group_by_name_or_id(account_id, args[0])
|
325
|
+
return 1 if group.nil?
|
326
|
+
|
327
|
+
# err, this is going to find public clouds only, not those in the subaccount
|
328
|
+
# good enough for now?
|
329
|
+
cloud = find_cloud_by_name_or_id(args[1])
|
330
|
+
current_zones = group['zones']
|
331
|
+
found_zone = current_zones.find {|it| it["id"] == cloud["id"] }
|
332
|
+
if found_zone
|
333
|
+
print_red_alert "Cloud #{cloud['name']} is already in group #{group['name']}."
|
334
|
+
exit 1
|
335
|
+
end
|
336
|
+
new_zones = current_zones + [{'id' => cloud['id']}]
|
337
|
+
payload = {group: {id: group["id"], zones: new_zones}}
|
338
|
+
if options[:dry_run]
|
339
|
+
print_dry_run @account_groups_interface.dry.update_zones(account['id'], group["id"], payload)
|
340
|
+
return
|
341
|
+
end
|
342
|
+
json_response = @account_groups_interface.update_zones(account['id'], group["id"], payload)
|
343
|
+
if options[:json]
|
344
|
+
print JSON.pretty_generate(json_response)
|
345
|
+
print "\n"
|
346
|
+
else
|
347
|
+
print_green_success "Added cloud #{cloud["name"]} to group #{group['name']}"
|
348
|
+
#list(["-A", account['id'].to_s])
|
349
|
+
get([group["id"].to_s, "-A", account['id'].to_s])
|
350
|
+
end
|
351
|
+
rescue RestClient::Exception => e
|
352
|
+
print_rest_exception(e, options)
|
353
|
+
exit 1
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def remove_cloud(args)
|
358
|
+
options = {}
|
359
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
360
|
+
opts.banner = subcommand_usage("[group]", "[cloud]")
|
361
|
+
build_common_options(opts, options, [:account, :json, :dry_run, :remote])
|
362
|
+
opts.footer = "Remove a cloud from a group."
|
363
|
+
end
|
364
|
+
optparse.parse!(args)
|
365
|
+
if args.count < 2
|
366
|
+
puts optparse
|
367
|
+
exit 1
|
368
|
+
end
|
369
|
+
connect(options)
|
370
|
+
begin
|
371
|
+
# load account
|
372
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
373
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
374
|
+
return 1
|
375
|
+
end
|
376
|
+
account = find_account_from_options(options)
|
377
|
+
return 1 if account.nil?
|
378
|
+
account_id = account['id']
|
379
|
+
|
380
|
+
group = find_account_group_by_name_or_id(account_id, args[0])
|
381
|
+
return 1 if group.nil?
|
382
|
+
|
383
|
+
# err, this is going to find public clouds only, not those in the subaccount
|
384
|
+
# good enough for now?
|
385
|
+
cloud = find_cloud_by_name_or_id(args[1])
|
386
|
+
current_zones = group['zones']
|
387
|
+
found_zone = current_zones.find {|it| it["id"] == cloud["id"] }
|
388
|
+
if !found_zone
|
389
|
+
print_red_alert "Cloud #{cloud['name']} is not in group #{group['name']}."
|
390
|
+
exit 1
|
391
|
+
end
|
392
|
+
new_zones = current_zones.reject {|it| it["id"] == cloud["id"] }
|
393
|
+
payload = {group: {id: group["id"], zones: new_zones}}
|
394
|
+
if options[:dry_run]
|
395
|
+
print_dry_run @account_groups_interface.dry.update_zones(account['id'], group["id"], payload)
|
396
|
+
return
|
397
|
+
end
|
398
|
+
json_response = @account_groups_interface.update_zones(account['id'], group["id"], payload)
|
399
|
+
if options[:json]
|
400
|
+
print JSON.pretty_generate(json_response)
|
401
|
+
print "\n"
|
402
|
+
else
|
403
|
+
print_green_success "Removed cloud #{cloud['name']} from group #{group['name']}"
|
404
|
+
# list(["-A", account['id'].to_s])
|
405
|
+
get([group["id"].to_s, "-A", account['id'].to_s])
|
406
|
+
end
|
407
|
+
rescue RestClient::Exception => e
|
408
|
+
print_rest_exception(e, options)
|
409
|
+
exit 1
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
def remove(args)
|
414
|
+
options = {}
|
415
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
416
|
+
opts.banner = subcommand_usage("[group]")
|
417
|
+
build_common_options(opts, options, [:account, :json, :dry_run, :auto_confirm, :remote])
|
418
|
+
opts.footer = "Delete a group."
|
419
|
+
# more info to display here
|
420
|
+
end
|
421
|
+
optparse.parse!(args)
|
422
|
+
if args.count < 1
|
423
|
+
puts optparse
|
424
|
+
exit 1
|
425
|
+
end
|
426
|
+
connect(options)
|
427
|
+
|
428
|
+
begin
|
429
|
+
# load account
|
430
|
+
if options[:account].nil? && options[:account_id].nil? && options[:account_name].nil?
|
431
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: -a [account]\n#{optparse}"
|
432
|
+
return 1
|
433
|
+
end
|
434
|
+
account = find_account_from_options(options)
|
435
|
+
return 1 if account.nil?
|
436
|
+
account_id = account['id']
|
437
|
+
|
438
|
+
group = find_account_group_by_name_or_id(account_id, args[0])
|
439
|
+
return 1 if group.nil?
|
440
|
+
|
441
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the group #{group['name']}?")
|
442
|
+
exit
|
443
|
+
end
|
444
|
+
if options[:dry_run]
|
445
|
+
print_dry_run @account_groups_interface.dry.destroy(account['id'], group['id'])
|
446
|
+
return
|
447
|
+
end
|
448
|
+
json_response = @account_groups_interface.destroy(account['id'], group['id'])
|
449
|
+
if options[:json]
|
450
|
+
print JSON.pretty_generate(json_response)
|
451
|
+
print "\n"
|
452
|
+
elsif !options[:quiet]
|
453
|
+
print_green_success "Removed group #{group['name']}"
|
454
|
+
#list(["-A", account['id']])
|
455
|
+
end
|
456
|
+
rescue RestClient::Exception => e
|
457
|
+
print_rest_exception(e, options)
|
458
|
+
exit 1
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
|
463
|
+
protected
|
464
|
+
|
465
|
+
def print_groups_table(groups, opts={})
|
466
|
+
table_color = opts[:color] || cyan
|
467
|
+
active_group_id = @active_group_id # Morpheus::Cli::Groups.active_group
|
468
|
+
rows = groups.collect do |group|
|
469
|
+
is_active = @active_group_id && (@active_group_id == group['id'])
|
470
|
+
{
|
471
|
+
active: (is_active ? "=>" : ""),
|
472
|
+
id: group['id'],
|
473
|
+
name: group['name'],
|
474
|
+
location: group['location'],
|
475
|
+
cloud_count: group['zones'] ? group['zones'].size : 0,
|
476
|
+
server_count: group['serverCount']
|
477
|
+
}
|
478
|
+
end
|
479
|
+
columns = [
|
480
|
+
{:active => {:display_name => ""}},
|
481
|
+
{:id => {:width => 10}},
|
482
|
+
{:name => {:width => 16}},
|
483
|
+
{:location => {:width => 32}},
|
484
|
+
{:cloud_count => {:display_name => "Clouds"}},
|
485
|
+
{:server_count => {:display_name => "Hosts"}}
|
486
|
+
]
|
487
|
+
print table_color
|
488
|
+
tp rows, columns
|
489
|
+
print reset
|
490
|
+
end
|
491
|
+
|
492
|
+
def add_group_option_types()
|
493
|
+
tmp_option_types = [
|
494
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
495
|
+
{'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
|
496
|
+
{'fieldName' => 'location', 'fieldLabel' => 'Location', 'type' => 'text', 'required' => false, 'displayOrder' => 3}
|
497
|
+
]
|
498
|
+
|
499
|
+
# Advanced Options
|
500
|
+
# TODO: Service Registry
|
501
|
+
|
502
|
+
return tmp_option_types
|
503
|
+
end
|
504
|
+
|
505
|
+
def update_group_option_types()
|
506
|
+
add_group_option_types().collect {|it| it['required'] = false; it }
|
507
|
+
end
|
508
|
+
|
509
|
+
|
510
|
+
def find_account_group_by_name_or_id(account_id, val)
|
511
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
512
|
+
return find_account_group_by_id(account_id, val)
|
513
|
+
else
|
514
|
+
return find_account_group_by_name(account_id, val)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
def find_account_group_by_id(account_id, id)
|
519
|
+
begin
|
520
|
+
json_response = @account_groups_interface.get(account_id, id.to_i)
|
521
|
+
return json_response['group']
|
522
|
+
rescue RestClient::Exception => e
|
523
|
+
if e.response && e.response.code == 404
|
524
|
+
print_red_alert "Group not found by id #{id}"
|
525
|
+
return nil
|
526
|
+
else
|
527
|
+
raise e
|
528
|
+
end
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
def find_account_group_by_name(account_id, name)
|
533
|
+
json_response = @account_groups_interface.list(account_id, {name: name.to_s})
|
534
|
+
account_groups = json_response['groups']
|
535
|
+
if account_groups.empty?
|
536
|
+
print_red_alert "Group not found by name #{name}"
|
537
|
+
return nil
|
538
|
+
elsif account_groups.size > 1
|
539
|
+
print_red_alert "#{account_groups.size} group found by name #{name}"
|
540
|
+
# print_account_groups_table(account_groups, {color: red})
|
541
|
+
rows = account_groups.collect do |account_group|
|
542
|
+
{id: it['id'], name: it['name']}
|
543
|
+
end
|
544
|
+
print red
|
545
|
+
tp rows, [:id, :name]
|
546
|
+
print reset,"\n"
|
547
|
+
return nil
|
548
|
+
else
|
549
|
+
account_group = account_groups[0]
|
550
|
+
return account_group
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
|
555
|
+
end
|