RaaS 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/bin/RaaSCLI +3 -0
- data/lib/RaaSmain.rb +361 -0
- data/lib/modules/RaaSCore.rb +404 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ODQyMTc2NTU0YmJhNTkzZDcwNjRhNzljY2Y5NThhODczMDNiMDQwMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjA3MWJlZmYzNTMzY2EzZjY4NDgyMWMxOTI2ZTM3NjAxOGU1NjA5NQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
M2Y3ZDQzYmY4YzcwOGIzMTdkZDk0NmJhNjU3YjE0MWYyMmQyNWFjZjc0MGRj
|
10
|
+
NmU0ZDkwM2M5OTNmOTFkZjYyYzg0MThkZWFjOTI3YjhmYjhhZDliOWM1NzYz
|
11
|
+
ZDExMjExOTcwNjZhZTg5ZWUxZmNiNGIxNDBjODg2ZTEyNmM4MDg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZmE2NTNhMzI1Y2RjMjk1MWJiYzc1YzFiNmRhNzE2YjZmNjJmYjhlYTE5NGU2
|
14
|
+
YTc1MjcxZTM0ZDRkMjg3ODA0OWY5N2M5ZTliMjZhYzRhODc3YmEyM2Q3NzE4
|
15
|
+
OTY1ZWI5ZjU3MmU3Yjk5OTAwNzg5ZGEyMDBmOTZmMWQ1MzQ3Njg=
|
data/bin/RaaSCLI
ADDED
data/lib/RaaSmain.rb
ADDED
@@ -0,0 +1,361 @@
|
|
1
|
+
#################################################################################
|
2
|
+
#### Massimo Re Ferre' ####
|
3
|
+
#### www.it20.info ####
|
4
|
+
#### RaaSCLI, a tool that allows you to interact with a DRaaS subscription ####
|
5
|
+
#################################################################################
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
#################################################################################
|
10
|
+
#### RaaSmain.rb is the front end program that presents the CLI interface ####
|
11
|
+
#### It leverages the RaaSCore library ####
|
12
|
+
#### Per best practices I keep the logic separate from the presentation ####
|
13
|
+
#################################################################################
|
14
|
+
|
15
|
+
|
16
|
+
# These are the additional modules/gems required to run the program
|
17
|
+
|
18
|
+
require 'httparty'
|
19
|
+
require 'yaml'
|
20
|
+
require 'xml-fu'
|
21
|
+
require 'pp'
|
22
|
+
require 'awesome_print' #optional - useful for debugging
|
23
|
+
|
24
|
+
require 'modules/RaaSCore'
|
25
|
+
|
26
|
+
|
27
|
+
# We stole this piece of code (silence_warnings) from the Internet.
|
28
|
+
# We am using it to silence the warnings of the certificates settings (below)
|
29
|
+
|
30
|
+
def silence_warnings(&block)
|
31
|
+
warn_level = $VERBOSE
|
32
|
+
$VERBOSE = nil
|
33
|
+
result = block.call
|
34
|
+
$VERBOSE = warn_level
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# This bypass certification checks... NOT a great idea for production but ok
|
40
|
+
# for test / dev This will be handy for when this script will work with vanilla
|
41
|
+
# vCD setups (not just vCHS)
|
42
|
+
|
43
|
+
silence_warnings do
|
44
|
+
OpenSSL::SSL::VERIFY_NONE = OpenSSL::SSL::VERIFY_NONE
|
45
|
+
end
|
46
|
+
|
47
|
+
# This is what the program accepts as input
|
48
|
+
|
49
|
+
def usage
|
50
|
+
puts "\nUsage: #{$PROGRAM_NAME} operation [option1] [option2]\n"
|
51
|
+
puts "\n\toperations: peers|replications|testfailover|testcleanup|failover"
|
52
|
+
puts "\n\te.g. #{$PROGRAM_NAME} peers"
|
53
|
+
puts "\te.g. #{$PROGRAM_NAME} replications ALL"
|
54
|
+
puts "\te.g. #{$PROGRAM_NAME} replications <VM name>"
|
55
|
+
puts "\te.g. #{$PROGRAM_NAME} testfailover <VM name>"
|
56
|
+
puts "\te.g. #{$PROGRAM_NAME} testfailover ALL"
|
57
|
+
puts "\te.g. #{$PROGRAM_NAME} testcleanup <VM name>"
|
58
|
+
puts "\te.g. #{$PROGRAM_NAME} testcleanup ALL"
|
59
|
+
puts "\te.g. #{$PROGRAM_NAME} failover <VM name>"
|
60
|
+
puts "\te.g. #{$PROGRAM_NAME} failover ALL"
|
61
|
+
puts "\n"
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# These are the variables the program accept as inputs (see the usage section for more info)
|
66
|
+
|
67
|
+
$operation = ARGV[0]
|
68
|
+
$details = ARGV[1]
|
69
|
+
$VM = ARGV[2]
|
70
|
+
|
71
|
+
# The if checks if the user called an operation. If not the case, we print the text on how to use the CLI
|
72
|
+
|
73
|
+
if $operation
|
74
|
+
|
75
|
+
# Here we instantiate the RaaS class in RaaSCore
|
76
|
+
|
77
|
+
raas = RaaS.new
|
78
|
+
|
79
|
+
|
80
|
+
# We login (the login method is in RaaSCore)
|
81
|
+
|
82
|
+
puts "Logging in ...\n\n"
|
83
|
+
raas.login
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
# Here we check what operations a user wants the CLI to execute. Every operations calls a particular method
|
88
|
+
# and prints the result returned from the method
|
89
|
+
# In general, the way RaaSmain works is that it calls specific methods available in RaaSCore.
|
90
|
+
# Some of these methods requires argument(s). Some do not.
|
91
|
+
# Usually these methods returns one or more arrays with information related to the operation being called.
|
92
|
+
# For more detailed info on these methods please refer to RaaSCore.
|
93
|
+
|
94
|
+
case $operation.chomp
|
95
|
+
|
96
|
+
|
97
|
+
# The peers operation calls the peers method and prints the results
|
98
|
+
# The method doesn't require an argument and it returns three arrays that includes information re the peers
|
99
|
+
|
100
|
+
|
101
|
+
when 'peers'
|
102
|
+
peerURI, siteName, siteID = raas.peers
|
103
|
+
puts "Currently active peer(s):\n".green
|
104
|
+
peerURI.length.times do |i|
|
105
|
+
puts "Site Name : " + siteName[i]
|
106
|
+
puts "Site Id : " + siteID[i]
|
107
|
+
puts "\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# The replications operation calls the replications method and prints the results.
|
112
|
+
# The replications method requires an argument (the details entered by the user) and returns
|
113
|
+
# a number of arrays whose rows describe the characteristics and status of each active replication
|
114
|
+
|
115
|
+
when 'replications'
|
116
|
+
if $details
|
117
|
+
foundVM, vmname, rpo, replicationState, quiesceGuestEnabled, paused, currentRpoViolation, testRecoveryState, recoveryState, vmhref = raas.replications($details)
|
118
|
+
puts foundVM
|
119
|
+
puts 'Detailed information for currently active replication(s):'.green
|
120
|
+
puts "\n"
|
121
|
+
if foundVM == false
|
122
|
+
puts "Sorry, I could not find the VM(s)".red
|
123
|
+
puts "\n"
|
124
|
+
else
|
125
|
+
vmname.length.times do |i|
|
126
|
+
puts 'VM name : ' + vmname[i].blue
|
127
|
+
puts 'RPO : ' + rpo[i]
|
128
|
+
puts 'Replication State : ' + replicationState[i]
|
129
|
+
puts 'Quiesce Enabled : ' + quiesceGuestEnabled[i]
|
130
|
+
puts 'Paused : ' + paused[i]
|
131
|
+
puts 'Current RPO Violation : ' + currentRpoViolation[i]
|
132
|
+
puts 'Test Recovery State : ' + testRecoveryState[i]
|
133
|
+
puts 'Recovery State : ' + recoveryState[i]
|
134
|
+
puts 'VM URL : ' + vmhref[i]
|
135
|
+
puts "\n"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
else
|
139
|
+
usage
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
# The testfailover operation calls one of the testfailover methods and prints the results.
|
145
|
+
# We check wether the user either wants to testfailover ALL VMs (in which case we call the testfailoverALL method)
|
146
|
+
# and print results or wants to testfailover one specific VM (in which case we call the testfailoverVM method)
|
147
|
+
# and print results
|
148
|
+
|
149
|
+
when 'testfailover'
|
150
|
+
#if the keyword name "ALL is specified we test failover ALL VMs
|
151
|
+
if $details == "ALL"
|
152
|
+
print "Are you REALLY SURE you want to test failover ALL the VMs? (yes/no): ".red
|
153
|
+
puts "\n"
|
154
|
+
puts "\n"
|
155
|
+
input = STDIN.gets.chomp
|
156
|
+
if input == "yes"
|
157
|
+
puts 'Performing a test failover of all VMs. This may be a long task. Please wait.'.green
|
158
|
+
puts "\n"
|
159
|
+
vmname, testfailover = raas.testfailoverALL
|
160
|
+
end
|
161
|
+
# Here we iterarte through the two arrays returned and print the VMs name and whether the testfailover was executed or not
|
162
|
+
vmname.length.times do |i|
|
163
|
+
if testfailover[i] == false
|
164
|
+
puts "Sorry, the VM ".red + vmname[i] + " is not in the proper state to test a failover".red
|
165
|
+
puts "\n"
|
166
|
+
else
|
167
|
+
puts "Performing a test failover of VM ".green + vmname[i] + ". Please wait.".green
|
168
|
+
puts "\n"
|
169
|
+
end # if
|
170
|
+
end #do
|
171
|
+
else
|
172
|
+
if $details
|
173
|
+
# if the details parameter is specified we assume it's a VM name and we run testfailoverVM
|
174
|
+
puts 'Performing a test failover of VM '.green + $details + '. Please wait.'.green
|
175
|
+
puts "\n"
|
176
|
+
foundVM, testfailover = raas.testfailoverVM($details)
|
177
|
+
# Here we check whether the VM name in input actually maps a VM name in the service
|
178
|
+
if foundVM == false
|
179
|
+
puts "Sorry, I couldn not find the VM ".red + $details
|
180
|
+
puts "\n"
|
181
|
+
else
|
182
|
+
# If the VM name matches, here we check if the testfailover has actually occurred
|
183
|
+
if testfailover == false
|
184
|
+
puts "Sorry, the VM ".red + $details + " is not in the proper state to test a failover".red
|
185
|
+
puts "\n"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
else usage
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
# The testcleanup operation calls one of the testcleanup methods and prints the results.
|
194
|
+
# We check wether the user either wants to testcleanup ALL VMs (in which case we call the testcleanupALL method)
|
195
|
+
# and print results or wants to testcleanup one specific VM (in which case we call the testcleanupVM method)
|
196
|
+
# and print results
|
197
|
+
|
198
|
+
when 'testcleanup'
|
199
|
+
#if the keyword name "ALL is specified we test cleanup ALL VMs
|
200
|
+
if $details == "ALL"
|
201
|
+
print "Are you REALLY SURE you want to clean up ALL the VMs? (yes/no): ".red
|
202
|
+
puts "\n"
|
203
|
+
puts "\n"
|
204
|
+
input = STDIN.gets.chomp
|
205
|
+
if input == "yes"
|
206
|
+
puts 'Performing a test cleanup of all VMs. This may be a long task. Please wait.'.green
|
207
|
+
puts "\n"
|
208
|
+
vmname, testcleanup = raas.testcleanupALL
|
209
|
+
end
|
210
|
+
# Here we iterarte through the two arrays returned and print the VMs name and whether the testcleanup was executed or not
|
211
|
+
vmname.length.times do |i|
|
212
|
+
if testcleanup[i] == false
|
213
|
+
puts "Sorry, the VM ".red + vmname[i] + " is not in a test failover state that allows a clean up".red
|
214
|
+
puts "\n"
|
215
|
+
else
|
216
|
+
puts "Performing a testcleanup of VM ".green + vmname[i] + ". Please wait.".green
|
217
|
+
puts "\n"
|
218
|
+
end #if
|
219
|
+
end #do
|
220
|
+
else
|
221
|
+
if $details
|
222
|
+
# if the details parameter is specified we assume it's a VM name and we run testcleanupVM
|
223
|
+
puts "Performing a testcleanup of VM ".green + $details + '. Please wait.'.green
|
224
|
+
puts "\n"
|
225
|
+
foundVM, testcleanup = raas.testcleanupVM($details)
|
226
|
+
# Here we check whether the VM name in input actually maps a VM name in the service
|
227
|
+
if foundVM == false
|
228
|
+
puts "Sorry, I couldn't not find the VM ".red + $details
|
229
|
+
puts "\n"
|
230
|
+
else
|
231
|
+
# If the VM name matches, here we check if the testcleanup has actually occurred
|
232
|
+
if testcleanup == false
|
233
|
+
puts "Sorry, the VM ".red + $details + " is not in a test failover state that allows a clean up".red
|
234
|
+
puts "\n"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
else usage
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
# The failover operation calls one of the failover methods and prints the results.
|
243
|
+
# We check wether the user either wants to failover ALL VMs (in which case we call the failoverALL method)
|
244
|
+
# and print results or wants to failover one specific VM (in which case we call the failoverVM method)
|
245
|
+
# and print results
|
246
|
+
|
247
|
+
when 'failover'
|
248
|
+
#if the keyword name "ALL is specified we failover ALL VMs
|
249
|
+
if $details == "ALL"
|
250
|
+
print "Are you REALLY SURE you want to failover ALL the VMs for production usage? (yes/no): ".red
|
251
|
+
input = STDIN.gets.chomp
|
252
|
+
if input == "yes"
|
253
|
+
puts 'Performing a failover of all VMs. This may be a long task. Please wait.'.green
|
254
|
+
puts "\n"
|
255
|
+
vmname, failover = raas.failoverALL
|
256
|
+
end
|
257
|
+
# Here we iterarte through the two arrays returned and print the VMs name and whether the failover was executed or not
|
258
|
+
vmname.length.times do |i|
|
259
|
+
if failover[i] == false
|
260
|
+
puts "Sorry, the VM ".red + vmname[i] + " is not in the proper state to failover".red
|
261
|
+
puts "\n"
|
262
|
+
else
|
263
|
+
puts "Performing a failover of VM ".green + vmname[i] + ". Please wait.".green
|
264
|
+
puts "\n"
|
265
|
+
end # if
|
266
|
+
end #do
|
267
|
+
else
|
268
|
+
if $details
|
269
|
+
# if the details parameter is specified we assume it's a VM name and we run failoverVM
|
270
|
+
print "Are you REALLY SURE you want to failover the VM ".red + $details + " for production usage? (yes/no): ".red
|
271
|
+
input = STDIN.gets.chomp
|
272
|
+
if input == "yes"
|
273
|
+
puts 'Performing the failover of VM '.green + $details + ' for production usage. Please wait.'.green
|
274
|
+
puts "\n"
|
275
|
+
# Here we check whether the VM name in input actually maps a VM name in the service
|
276
|
+
foundVM, failover = raas.failoverVM($details)
|
277
|
+
if foundVM == false
|
278
|
+
puts "Sorry, I couldn't not find the VM ".red + $details
|
279
|
+
puts "\n"
|
280
|
+
else
|
281
|
+
# If the VM name matches, here we check if the failover has actually occurred
|
282
|
+
if failover == false
|
283
|
+
puts "Sorry, the VM ".red + $details + " is not in the proper state to perform a failover".red
|
284
|
+
puts "\n"
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
else usage
|
289
|
+
end
|
290
|
+
end #if
|
291
|
+
|
292
|
+
# If the user specified a wrong operation we suggest how to use the CLI
|
293
|
+
|
294
|
+
else #case
|
295
|
+
puts "\n"
|
296
|
+
puts "Wrong operation!".red
|
297
|
+
usage
|
298
|
+
puts "\n"
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
# At this stage RaaSmain will have executed an operation per the "case" above" and it logs out
|
303
|
+
|
304
|
+
puts "Logging out ...\n\n"
|
305
|
+
raas.logout
|
306
|
+
|
307
|
+
|
308
|
+
# If the user did not specify an operation at all we suggest how to properly use the CLI
|
309
|
+
|
310
|
+
else #if
|
311
|
+
puts "\n"
|
312
|
+
puts "Missing operation!".red
|
313
|
+
puts "\n"
|
314
|
+
usage
|
315
|
+
|
316
|
+
end #main if
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
|
345
|
+
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
|
350
|
+
|
351
|
+
|
352
|
+
|
353
|
+
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
|
360
|
+
|
361
|
+
|
@@ -0,0 +1,404 @@
|
|
1
|
+
#################################################################################
|
2
|
+
#### Massimo Re Ferre' ####
|
3
|
+
#### www.it20.info ####
|
4
|
+
#### RaaSCLI, a tool that allows you to interact with a DRaaS subscription ####
|
5
|
+
#################################################################################
|
6
|
+
|
7
|
+
class RaaS
|
8
|
+
include HTTParty
|
9
|
+
format :xml
|
10
|
+
|
11
|
+
#################################################################################
|
12
|
+
#### The following functions are standard functions to login ####
|
13
|
+
#### and logout from the tenant ####
|
14
|
+
#### They can be used to interact generically with vCloud Air ####
|
15
|
+
#################################################################################
|
16
|
+
|
17
|
+
#################################################################################
|
18
|
+
#### IMPORTANT !! ####
|
19
|
+
#### The program reads a file called RaaSCLI.yml in the working directory ####
|
20
|
+
#### If the file does not exist the program will abort ####
|
21
|
+
#### The file is used to provide the program with connectivity parameters ####
|
22
|
+
#################################################################################
|
23
|
+
|
24
|
+
|
25
|
+
# This is the format of the RaaSCLI.yml file:
|
26
|
+
# :username: email@domain@OrgName
|
27
|
+
# :password: password
|
28
|
+
# :site: https://vcd-url
|
29
|
+
|
30
|
+
|
31
|
+
def initialize(file_path = 'RaaSCLI.yml')
|
32
|
+
fail "no file #{file_path}" unless File.exists? file_path
|
33
|
+
configuration = YAML.load_file(file_path)
|
34
|
+
self.class.basic_auth configuration[:username], configuration[:password]
|
35
|
+
self.class.base_uri configuration[:site]
|
36
|
+
self.class.default_options[:headers] = { 'Accept' => 'application/*+xml;version=5.6' }
|
37
|
+
end
|
38
|
+
|
39
|
+
def login
|
40
|
+
response = self.class.post('/api/sessions')
|
41
|
+
# setting global cookie var to be used later on
|
42
|
+
@cookie = response.headers['set-cookie']
|
43
|
+
self.class.default_options[:headers] = { 'Accept' => 'application/*+xml;version=5.6', 'Cookie' => @cookie }
|
44
|
+
end
|
45
|
+
|
46
|
+
def logout
|
47
|
+
self.class.delete('/api/session')
|
48
|
+
end
|
49
|
+
|
50
|
+
def links
|
51
|
+
response = self.class.get('/api/session')
|
52
|
+
response['Session']['Link'].each do |link|
|
53
|
+
puts link['href']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
############################################################################
|
60
|
+
##### RaaSCore starts here ######
|
61
|
+
############################################################################
|
62
|
+
|
63
|
+
|
64
|
+
#################################################################################
|
65
|
+
#### The following methods are used internally and should ####
|
66
|
+
#### not be called from outside this module ####
|
67
|
+
#################################################################################
|
68
|
+
|
69
|
+
|
70
|
+
# This internal method queries the vDCs and returns its HREF
|
71
|
+
|
72
|
+
def vDChref
|
73
|
+
response = self.class.get('/api/admin/vdcs/query/')
|
74
|
+
vDC = response['QueryResultRecords']['OrgVdcRecord']
|
75
|
+
vDChref = vDC['href'][46..81]
|
76
|
+
return vDChref
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# This internal method retrieves all the active replications in the DR VPC
|
81
|
+
# It returns an array of HREFs for the replications
|
82
|
+
|
83
|
+
def replicationshref
|
84
|
+
vDC = vDChref
|
85
|
+
response = self.class.get("/api/vdc/#{vDC}/replications")
|
86
|
+
replicationshref = [response['References']['Reference']].flatten
|
87
|
+
return replicationshref
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
# This internal method issues the test failover action against the VM ID passed
|
92
|
+
# It doesn't return anything, it just executes the testfailover
|
93
|
+
|
94
|
+
def testfailover(replicaURI, replicadetailsname)
|
95
|
+
self.class.default_options[:headers] = {"Accept" => "application/*+xml;version=5.6", "Cookie" => @cookie, "Content-Type" => "application/vnd.vmware.hcs.testFailoverParams+xml"}
|
96
|
+
testFailoverParam = XmlFu.xml("TestFailoverParams" => {
|
97
|
+
"@xmlns" => "http://www.vmware.com/vr/v6.0",
|
98
|
+
"@xmlns:vcloud_v1.5" => "http://www.vmware.com/vcloud/v1.5",
|
99
|
+
"@name" => "xs:string",
|
100
|
+
"Synchronize" => " false "
|
101
|
+
})
|
102
|
+
response = self.class.post("/api/vr/replications/#{replicaURI}/action/testFailover", :body => testFailoverParam)
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# This internal method issues the failover action against the VM ID passed
|
107
|
+
# It doesn't return anything, it just executes the failover
|
108
|
+
|
109
|
+
def failover(replicaURI, replicadetailsname)
|
110
|
+
self.class.default_options[:headers] = {"Accept" => "application/*+xml;version=5.6", "Cookie" => @cookie, "Content-Type" => "application/vnd.vmware.hcs.failoverParams+xml"}
|
111
|
+
failoverParam = XmlFu.xml("FailoverParams" => {
|
112
|
+
"@xmlns" => "http://www.vmware.com/vr/v6.0",
|
113
|
+
"@xmlns:vcloud_v1.5" => "http://www.vmware.com/vcloud/v1.5",
|
114
|
+
"@name" => "xs:string",
|
115
|
+
})
|
116
|
+
response = self.class.post("/api/vr/replications/#{replicaURI}/action/failover", :body => failoverParam)
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# This internal method issues the test cleanup action against the VM ID passed
|
121
|
+
# It doesn't return anything, it just executes the testcleanup
|
122
|
+
|
123
|
+
def testcleanup(replicaURI, replicadetailsname)
|
124
|
+
response = self.class.post("/api/vr/replications/#{replicaURI}/action/testCleanup")
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
#################################################################################
|
130
|
+
#### The following methods can be used externally. ####
|
131
|
+
#### They implement functions that maps the public API calls ####
|
132
|
+
#### I'll avoid calling this an SDK for vCloud Air RaaS (but it's an attempt)####
|
133
|
+
#################################################################################
|
134
|
+
|
135
|
+
|
136
|
+
#this method queries the peers associated to the DR VPC and
|
137
|
+
#it returns an array with the peers URIs, an array of site names
|
138
|
+
#and an array of site IDs
|
139
|
+
|
140
|
+
def peers
|
141
|
+
vDC = vDChref
|
142
|
+
response = self.class.get("/api/vdc/#{vDC}/peers")
|
143
|
+
peersarray = [response['References']['Reference']].flatten
|
144
|
+
peerURI = Array.new
|
145
|
+
siteName = Array.new
|
146
|
+
siteID = Array.new
|
147
|
+
i = 0
|
148
|
+
peersarray.each do |peer|
|
149
|
+
peerhref = peer['href']
|
150
|
+
peerURI[i] = peerhref[51..124]
|
151
|
+
response = self.class.get("/api/vr/peers/#{peerURI[i]}")
|
152
|
+
peerinfo = response['Peer']
|
153
|
+
siteName[i] = peerinfo['SiteName']
|
154
|
+
siteID[i] = peerinfo['SiteUuid']
|
155
|
+
i+= 1
|
156
|
+
end
|
157
|
+
return peerURI, siteName, siteID
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
# This method queries active replications for the DR VPC
|
162
|
+
# It accept a target as an input. It can be "ALL" or an arbitrary name.
|
163
|
+
# If it's an arbitrary name the method will search for a VM with that name
|
164
|
+
# It returns a number of arrays that contains the/all replication/s HREFs
|
165
|
+
|
166
|
+
|
167
|
+
def replications(target)
|
168
|
+
replicationsarray = replicationshref
|
169
|
+
foundVM = false
|
170
|
+
vmname = Array.new
|
171
|
+
rpo = Array.new
|
172
|
+
replicationState = Array.new
|
173
|
+
quiesceGuestEnabled = Array.new
|
174
|
+
paused = Array.new
|
175
|
+
currentRpoViolation = Array.new
|
176
|
+
testRecoveryState = Array.new
|
177
|
+
recoveryState = Array.new
|
178
|
+
vmhref = Array.new
|
179
|
+
i = 0
|
180
|
+
if replicationsarray !nil
|
181
|
+
if target == 'ALL'
|
182
|
+
replicationsarray.each do |replica|
|
183
|
+
replicahref = replica['href']
|
184
|
+
replicaURI = replicahref[58..136]
|
185
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
186
|
+
replicadetails = response['ReplicationGroup']
|
187
|
+
vmname[i] = replicadetails['name']
|
188
|
+
rpo[i] = replicadetails['Rpo']
|
189
|
+
replicationState[i] = replicadetails['ReplicationState']
|
190
|
+
quiesceGuestEnabled[i] = replicadetails['QuiesceGuestEnabled']
|
191
|
+
paused[i] = replicadetails['Paused']
|
192
|
+
currentRpoViolation[i] = replicadetails['CurrentRpoViolation']
|
193
|
+
testRecoveryState[i] = replicadetails['TestRecoveryState']
|
194
|
+
recoveryState[i] = replicadetails['RecoveryState']
|
195
|
+
vmhref[i] = replicadetails['href']
|
196
|
+
foundVM = true
|
197
|
+
i+= 1
|
198
|
+
end #do
|
199
|
+
else
|
200
|
+
replicationsarray.each do |replica|
|
201
|
+
replicahref = replica['href']
|
202
|
+
replicaURI = replicahref[58..136]
|
203
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
204
|
+
replicadetails = response['ReplicationGroup']
|
205
|
+
if replicadetails['name'] == target
|
206
|
+
vmname[i] = replicadetails['name']
|
207
|
+
rpo[i] = replicadetails['Rpo']
|
208
|
+
replicationState[i] = replicadetails['ReplicationState']
|
209
|
+
quiesceGuestEnabled[i] = replicadetails['QuiesceGuestEnabled']
|
210
|
+
paused[i] = replicadetails['Paused']
|
211
|
+
currentRpoViolation[i] = replicadetails['CurrentRpoViolation']
|
212
|
+
testRecoveryState[i] = replicadetails['TestRecoveryState']
|
213
|
+
recoveryState[i] = replicadetails['RecoveryState']
|
214
|
+
vmhref[i] = replicadetails['href']
|
215
|
+
foundVM = true
|
216
|
+
end #if
|
217
|
+
end #do
|
218
|
+
end #if replications = ALL
|
219
|
+
end # if !nil
|
220
|
+
return foundVM, vmname, rpo, replicationState, quiesceGuestEnabled, paused, currentRpoViolation, testRecoveryState, recoveryState, vmhref
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
# This method issues the testfailover action against the VM name passed as input.
|
225
|
+
# This method scrolls the array of replications, query the HREFs and search for the VM name
|
226
|
+
# If it finds the VM name, it calls the testfailover method to test failover the VM.
|
227
|
+
# It returns two variables. FoundVM is set to true or false depending if the VM was found or not.
|
228
|
+
# Testfailover is set to true or false depending if the test failover command was issued or not.
|
229
|
+
|
230
|
+
def testfailoverVM(target)
|
231
|
+
replicationsarray = replicationshref
|
232
|
+
testfailover = false
|
233
|
+
foundVM = false
|
234
|
+
replicationsarray.each do |replica|
|
235
|
+
replicahref = replica['href']
|
236
|
+
replicaURI = replicahref[58..136]
|
237
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
238
|
+
replicadetails = response['ReplicationGroup']
|
239
|
+
if replicadetails['name'] == target
|
240
|
+
foundVM = true
|
241
|
+
if replicadetails['TestRecoveryState'] == 'none'
|
242
|
+
if replicadetails['RecoveryState'] == 'notStarted'
|
243
|
+
testfailover = true
|
244
|
+
testfailover(replicaURI, replicadetails['name'])
|
245
|
+
end #if
|
246
|
+
end #if
|
247
|
+
end
|
248
|
+
end
|
249
|
+
return foundVM, testfailover
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
# This method issues the failover action against the VM name passed as input.
|
254
|
+
# This method scrolls the array of replications, query the HREFs and search for the VM name
|
255
|
+
# If it finds the VM name, it calls the failover method to failover the VM.
|
256
|
+
# It returns two variables. FoundVM is set to true or false depending if the VM was found or not.
|
257
|
+
# Failover is set to true or false depending if the failover command was issued or not.
|
258
|
+
|
259
|
+
def failoverVM(target)
|
260
|
+
replicationsarray = replicationshref
|
261
|
+
failover = false
|
262
|
+
foundVM = false
|
263
|
+
replicationsarray.each do |replica|
|
264
|
+
replicahref = replica['href']
|
265
|
+
replicaURI = replicahref[58..136]
|
266
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
267
|
+
replicadetails = response['ReplicationGroup']
|
268
|
+
if replicadetails['name'] == target
|
269
|
+
foundVM = true
|
270
|
+
if replicadetails['TestRecoveryState'] == 'none'
|
271
|
+
if replicadetails['RecoveryState'] == 'notStarted'
|
272
|
+
failover = true
|
273
|
+
failover(replicaURI, replicadetails['name'])
|
274
|
+
end #if
|
275
|
+
end #if
|
276
|
+
end #if
|
277
|
+
end #eachdo
|
278
|
+
return foundVM, failover
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
# This method issues the test cleanup action against the VM name passed as input.
|
283
|
+
# This method scrolls the array of replications, query the HREFs and search for the VM name
|
284
|
+
# If it finds the VM name, it calls the testcleanup function to clean up the test.
|
285
|
+
# It returns two variables. FoundVM is set to true or false depending if the VM was found or not.
|
286
|
+
# Testcleanup is set to true or false depending if the testcleanup command was issued or not.
|
287
|
+
|
288
|
+
def testcleanupVM(target)
|
289
|
+
replicationsarray = replicationshref
|
290
|
+
testcleanup = false
|
291
|
+
foundVM = false
|
292
|
+
replicationsarray.each do |replica|
|
293
|
+
replicahref = replica['href']
|
294
|
+
replicaURI = replicahref[58..136]
|
295
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
296
|
+
replicadetails = response['ReplicationGroup']
|
297
|
+
if replicadetails['name'] == target
|
298
|
+
foundVM = true
|
299
|
+
if replicadetails['TestRecoveryState'] == "complete" or replicadetails['TestRecoveryState'] == "testError"
|
300
|
+
testcleanup(replicaURI, replicadetails['name'])
|
301
|
+
testcleanup = true
|
302
|
+
else end
|
303
|
+
end #if
|
304
|
+
end #each do
|
305
|
+
return foundVM, testcleanup
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
# This method issues the testfailover action against ALL VMs. There is no input.
|
310
|
+
# This method scrolls the array of replications and calls the testfailover method to test failover all VMs.
|
311
|
+
# It returns two arrays. Vmname contains the name of the VMs.
|
312
|
+
# Testfailover contains true or false depending if the test failover command was issued or not for the VMs.
|
313
|
+
|
314
|
+
def testfailoverALL
|
315
|
+
replicationsarray = replicationshref
|
316
|
+
vmname = Array.new
|
317
|
+
testfailover = Array.new
|
318
|
+
i = 0
|
319
|
+
replicationsarray.each do |replica|
|
320
|
+
replicahref = replica['href']
|
321
|
+
replicaURI = replicahref[58..136]
|
322
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
323
|
+
replicadetails = response['ReplicationGroup']
|
324
|
+
vmname[i] = replicadetails['name']
|
325
|
+
if replicadetails['TestRecoveryState'] == 'none'
|
326
|
+
if replicadetails['RecoveryState'] == 'notStarted'
|
327
|
+
testfailover[i] = true
|
328
|
+
testfailover(replicaURI, replicadetails['name'])
|
329
|
+
else testfailover[i] = false
|
330
|
+
end
|
331
|
+
else testfailover[i] = false
|
332
|
+
end #if
|
333
|
+
i+= 1
|
334
|
+
end #each do
|
335
|
+
return vmname, testfailover
|
336
|
+
end
|
337
|
+
|
338
|
+
|
339
|
+
# This method issues the testcleanup action against ALL VMs. There is no input.
|
340
|
+
# This method scrolls the array of replications and calls the testcleanup method to testcleanup all VMs.
|
341
|
+
# It returns two arrays. Vmname contains the name of the VMs.
|
342
|
+
# Testcleanup contains true or false depending if the testcleanup command was issued or not for the VMs.
|
343
|
+
|
344
|
+
def testcleanupALL
|
345
|
+
replicationsarray = replicationshref
|
346
|
+
vmname = Array.new
|
347
|
+
testcleanup = Array.new
|
348
|
+
i = 0
|
349
|
+
replicationsarray.each do |replica|
|
350
|
+
replicahref = replica['href']
|
351
|
+
replicaURI = replicahref[58..136]
|
352
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
353
|
+
replicadetails = response['ReplicationGroup']
|
354
|
+
vmname[i] = replicadetails['name']
|
355
|
+
if replicadetails['TestRecoveryState'] == "complete" or replicadetails['TestRecoveryState'] == "testError"
|
356
|
+
testcleanup[i] = true
|
357
|
+
testcleanup(replicaURI, replicadetails['name'])
|
358
|
+
else testcleanup[i] = false
|
359
|
+
end #if
|
360
|
+
i+= 1
|
361
|
+
end #each do
|
362
|
+
return vmname, testcleanup
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
# This method issues the failover action against ALL VMs. There is no input.
|
367
|
+
# This method scrolls the array of replications and calls the failover method to failover all VMs.
|
368
|
+
# It returns two arrays. Vmname contains the name of the VMs.
|
369
|
+
# Failover contains true or false depending if the failover command was issued or not for the VMs.
|
370
|
+
|
371
|
+
def failoverALL
|
372
|
+
replicationsarray = replicationshref
|
373
|
+
vmname = Array.new
|
374
|
+
failover = Array.new
|
375
|
+
i = 0
|
376
|
+
replicationsarray.each do |replica|
|
377
|
+
replicahref = replica['href']
|
378
|
+
replicaURI = replicahref[58..136]
|
379
|
+
response = self.class.get("/api/vr/replications/#{replicaURI}")
|
380
|
+
replicadetails = response['ReplicationGroup']
|
381
|
+
vmname[i] = replicadetails['name']
|
382
|
+
if replicadetails['TestRecoveryState'] == 'none'
|
383
|
+
if replicadetails['RecoveryState'] == 'notStarted'
|
384
|
+
failover[i] = true
|
385
|
+
failover(replicaURI, replicadetails['name'])
|
386
|
+
else failover[i] = false
|
387
|
+
end
|
388
|
+
else failover[i] = false
|
389
|
+
end #if
|
390
|
+
i+= 1
|
391
|
+
end #each do
|
392
|
+
return vmname, failover
|
393
|
+
end
|
394
|
+
|
395
|
+
|
396
|
+
|
397
|
+
end # class RaaS
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
|
402
|
+
|
403
|
+
|
404
|
+
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: RaaS
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Massimo Re Ferrè
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.12.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.12.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: xml-fu
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: awesome_print
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.2.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.2.0
|
55
|
+
description: A set of tools that allows VMware vCloud Air customers to interact programmatically
|
56
|
+
with RaaS - Recovery as a Service
|
57
|
+
email: massimo@it20.info
|
58
|
+
executables:
|
59
|
+
- RaaSCLI
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/RaaSmain.rb
|
64
|
+
- lib/modules/RaaSCore.rb
|
65
|
+
- bin/RaaSCLI
|
66
|
+
homepage: http://it20.info
|
67
|
+
licenses:
|
68
|
+
- GPL
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.1.11
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: VMware vCloud Air RaaS program
|
90
|
+
test_files: []
|