RaaS 0.0.1
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 +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: []
|