tiebreaker 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/classes/NaElement.rb +396 -0
- data/classes/NaErrno.rb +1170 -0
- data/classes/NaServer.rb +789 -0
- data/classes/common.rb +37 -0
- data/classes/confreader.rb +16 -0
- data/classes/main.rb +79 -0
- data/classes/ntap.rb +610 -0
- data/classes/worker.rb +265 -0
- data/config.json +90 -0
- data/logs/config0.log +0 -0
- data/pids/pid +0 -0
- data/tiebreaker.rb +12 -0
- metadata +136 -0
data/classes/common.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class ALLVARS
|
2
|
+
@@configisvlalid = true
|
3
|
+
@@configisvlalid = true
|
4
|
+
@@sitecrashed = ""
|
5
|
+
@@isseparated = false
|
6
|
+
@@mutex = Mutex.new
|
7
|
+
|
8
|
+
def mutex
|
9
|
+
return @@mutex
|
10
|
+
end
|
11
|
+
|
12
|
+
def configisvlalid
|
13
|
+
return @@configisvlalid
|
14
|
+
end
|
15
|
+
|
16
|
+
def setconfigisvalid(isvalid)
|
17
|
+
@@configisvlalid = isvalid
|
18
|
+
end
|
19
|
+
|
20
|
+
def sitecrashed
|
21
|
+
return @@sitecrashed
|
22
|
+
end
|
23
|
+
|
24
|
+
def setsitecrashed(site)
|
25
|
+
@@sitecrashed = site
|
26
|
+
end
|
27
|
+
|
28
|
+
def isseparated
|
29
|
+
return @@isseparated
|
30
|
+
end
|
31
|
+
|
32
|
+
def setseparated(separated)
|
33
|
+
@@isseparated = separated
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'json';
|
2
|
+
|
3
|
+
class CONFREADER
|
4
|
+
attr_reader :hashedjson, :error_in_parsing_json
|
5
|
+
@hashedjson = ""
|
6
|
+
def initialize(conf_file)
|
7
|
+
begin
|
8
|
+
@error_in_parsing_json = ""
|
9
|
+
rawcontent = File.read(conf_file)
|
10
|
+
@hashedjson = JSON.parse(rawcontent)
|
11
|
+
rescue Exception=>e
|
12
|
+
@error_in_parsing_json = e.message
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
data/classes/main.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
$:.unshift File.dirname(__FILE__)
|
3
|
+
require "confreader"
|
4
|
+
require "worker"
|
5
|
+
require "common"
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
logger = Logger.new(File.join(File.dirname(__FILE__),"../logs/tiebraker_main.log"), 'weekly')
|
9
|
+
logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
10
|
+
logger.info "Started"
|
11
|
+
|
12
|
+
allvariables = ALLVARS.new
|
13
|
+
# config check
|
14
|
+
conf = CONFREADER.new(File.join(File.dirname(__FILE__), '../config.json'));
|
15
|
+
if ! conf.error_in_parsing_json.empty? then
|
16
|
+
logger.fatal "Error at parsing json #{conf.error_in_parsing_json}"
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
conf.hashedjson["configs"].each {|x|
|
21
|
+
logger.info x
|
22
|
+
if allvariables.configisvlalid then
|
23
|
+
if (x.has_key?("config_name") & x.has_key?("primary_ip") & x.has_key?("secondary_ip") & x.has_key?("primary_svm") & x.has_key?("secondary_svm") &
|
24
|
+
x.has_key?("primary_user") & x.has_key?("primary_password") & x.has_key?("secondary_user") & x.has_key?("secondary_password") &
|
25
|
+
x.has_key?("primary_site_name") & x.has_key?("ips_to_check_on_primary_from_secondary") & x.has_key?("ips_to_check_on_primary") &
|
26
|
+
x.has_key?("ips_to_check_on_secondary") & x.has_key?("fc_topology_check") & x.has_key?("check_fc_switches_on_primary") &
|
27
|
+
x.has_key?("primary_svm_user") & x.has_key?("primary_svm_password") & x.has_key?("secondary_svm_user") & x.has_key?("secondary_svm_password")
|
28
|
+
) then
|
29
|
+
logger.info "The config has all the keys."
|
30
|
+
|
31
|
+
if ( (x["ips_to_check_on_primary"].class.name == 'Array') & (x["ips_to_check_on_secondary"].class.name == 'Array') &
|
32
|
+
(x["ips_to_check_on_primary_from_secondary"].class.name == 'Array') & (x["check_fc_switches_on_primary"].class.name == 'Array')) then
|
33
|
+
logger.info "Found all the array type keys."
|
34
|
+
if ( (x["ips_to_check_on_primary"].count>0) & (x["ips_to_check_on_secondary"].count>0) & (x["ips_to_check_on_primary_from_secondary"].count>0) &
|
35
|
+
( ( x["fc_topology_check"] & (x["check_fc_switches_on_primary"].count>0) ) || ! x["fc_topology_check"] )
|
36
|
+
|
37
|
+
) then
|
38
|
+
logger.info "The array types have more than zero elements in the config. It is Ok."
|
39
|
+
else
|
40
|
+
logger.fatal "There are keys with array type with no elements"
|
41
|
+
allvariables.setconfigisvalid(false)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
logger.fatal "Some keys must be type of array!"
|
45
|
+
allvariables.setconfigisvalid(false)
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
else
|
50
|
+
logger.fatal "There are missing keys in the config."
|
51
|
+
allvariables.setconfigisvalid(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
}
|
56
|
+
|
57
|
+
exit if !allvariables.configisvlalid
|
58
|
+
|
59
|
+
|
60
|
+
# start workers
|
61
|
+
threads = []
|
62
|
+
conf.hashedjson["configs"].each {|x|
|
63
|
+
logger.debug x
|
64
|
+
threads << Thread.new { WORKER.new(x) }
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
begin
|
69
|
+
anythreadalive = false
|
70
|
+
logger.info "Number of threads: #{threads.size}"
|
71
|
+
threads.each {|x|
|
72
|
+
# exit if not x.alive?
|
73
|
+
anythreadalive = anythreadalive | x.alive?
|
74
|
+
x.exit if not x.alive?
|
75
|
+
}
|
76
|
+
logger.info "Any thread alive: #{anythreadalive }"
|
77
|
+
sleep 10
|
78
|
+
end while anythreadalive
|
79
|
+
|
data/classes/ntap.rb
ADDED
@@ -0,0 +1,610 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require "NaServer"
|
4
|
+
require "common"
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
class NETAPP
|
8
|
+
|
9
|
+
attr_reader :primary_ip, :primary_user, :primary_password, :secondary_ip, :secondary_user, :secondary_password, :primary_svm, :secondary_svm
|
10
|
+
|
11
|
+
|
12
|
+
# def initialize(primary_ip, primary_user, primary_password, secondary_ip, secondary_user, secondary_password, primary_svm, secondary_svm, ips_to_check_on_primary_from_secondary)
|
13
|
+
def initialize(config, logger, vsms_properties)
|
14
|
+
@logger = logger
|
15
|
+
@primary_ip = config["primary_ip"]
|
16
|
+
@primary_user = config["primary_user"]
|
17
|
+
@primary_password = config["primary_password"]
|
18
|
+
@secondary_ip = config["secondary_ip"]
|
19
|
+
@secondary_user = config["secondary_user"]
|
20
|
+
@secondary_password = config["secondary_password"]
|
21
|
+
@primary_svm = config["primary_svm"]
|
22
|
+
@secondary_svm = config["secondary_svm"]
|
23
|
+
@ips_to_check_on_primary_from_secondary = config["ips_to_check_on_primary_from_secondary"]
|
24
|
+
@config_name = config['config_name']
|
25
|
+
|
26
|
+
@primary_svm_user = config["primary_svm_user"]
|
27
|
+
@primary_svm_password = config["primary_svm_password"]
|
28
|
+
@secondary_svm_user = config["secondary_svm_user"]
|
29
|
+
@secondary_svm_password = config["secondary_svm_password"]
|
30
|
+
|
31
|
+
@connection = NaServer.new(@secondary_ip, 1, 3)
|
32
|
+
@connection.set_admin_user(@secondary_user, @secondary_password)
|
33
|
+
|
34
|
+
@connection_primary = NaServer.new(@primary_ip, 1, 3)
|
35
|
+
@connection_primary.set_admin_user(@primary_user, @primary_password)
|
36
|
+
|
37
|
+
@fc_topology_check = config["fc_topology_check"]
|
38
|
+
@check_fc_switches_on_primary = config["check_fc_switches_on_primary"]
|
39
|
+
|
40
|
+
@all_nodes = list_nodes_on_secondary if vsms_properties.size != 0
|
41
|
+
|
42
|
+
@vsms_properties = vsms_properties
|
43
|
+
if vsms_properties.size > 0 then
|
44
|
+
@primary_svm_luns = @vsms_properties["primary_vsm_properties"]["luns"] #Array of HASH["path","online","serial-number"]
|
45
|
+
@secondary_svm_management_interfaces = @vsms_properties["secondary_vsm_properties"]["management_lifs"] # Array of HASH ["address", "interface-name", "administrative-status", "operational-status"]
|
46
|
+
@secondary_svm_data_interfaces = @vsms_properties["secondary_vsm_properties"]["data_lifs"] # Array of HASH ["interface-name", "administrative-status", "data-protocol"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# initialize
|
50
|
+
|
51
|
+
|
52
|
+
def ping_primary_from_secondary
|
53
|
+
@logger.info "#{@config_name}: Trying ping primary site from NetApp on secondary site.."
|
54
|
+
can_ping_primary_from_secondary = false
|
55
|
+
@logger.info "#{@config_name}: The following ips are used on secondary netapp to check wheter the primary is alive: #{@ips_to_check_on_primary_from_secondary}"
|
56
|
+
@all_nodes.each do |node|
|
57
|
+
@ips_to_check_on_primary_from_secondary.each do |ip_to_check_on_primary_from_secondary|
|
58
|
+
if not can_ping_primary_from_secondary then
|
59
|
+
@logger.info "#{@config_name}: Trying ping: #{node} -> #{ip_to_check_on_primary_from_secondary}"
|
60
|
+
xcommand = NaElement.new("net-cluster-ping")
|
61
|
+
xcommand.child_add_string("destination-address", ip_to_check_on_primary_from_secondary)
|
62
|
+
xcommand.child_add_string("node", node)
|
63
|
+
xcommand.child_add_string("retry-count","1");
|
64
|
+
result = @connection.invoke_elem(xcommand)
|
65
|
+
|
66
|
+
if (result.results_status() == "failed")
|
67
|
+
# do some logging
|
68
|
+
@logger.warn "#{@config_name}: Unable to ping: #{node} -> #{ip_to_check_on_primary_from_secondary} #{result.results_reason()}"
|
69
|
+
else
|
70
|
+
@logger.info "#{@config_name}: Ping is succes: #{node} -> #{ip_to_check_on_primary_from_secondary} "
|
71
|
+
can_ping_primary_from_secondary = true
|
72
|
+
end
|
73
|
+
end # if not can_ping_primary_from_secondary
|
74
|
+
end # ips_to_check_on_primary_from_secondary.each do
|
75
|
+
end # @all_nodes.each do
|
76
|
+
if (@fc_topology_check ) & !(can_ping_primary_from_secondary) then
|
77
|
+
fc_switches = @check_fc_switches_on_primary.uniq
|
78
|
+
@logger.info "#{@config_name}: Have to discover FC topology..."
|
79
|
+
Net::SSH.start(@secondary_ip , @secondary_user, :password => @secondary_password) do |ssh|
|
80
|
+
@all_nodes.each do |node|
|
81
|
+
if !can_ping_primary_from_secondary then
|
82
|
+
@logger.info "#{@config_name}: Trying to discover FC topology on node: #{node}"
|
83
|
+
result = ssh.exec!("system node run -node #{node} -command fcp topology show")
|
84
|
+
arr_of_result = result.split("\r\n")
|
85
|
+
arr_of_result.keep_if {|elem| elem.include?("Switch Name:")}
|
86
|
+
arr_of_result.each_index { |idx|
|
87
|
+
arr_of_result[idx].gsub!("Switch Name:","").strip!
|
88
|
+
}
|
89
|
+
arr_of_result.uniq!
|
90
|
+
aggr_arr = (arr_of_result + fc_switches).uniq
|
91
|
+
if aggr_arr.count < arr_of_result.count+fc_switches.count then
|
92
|
+
can_ping_primary_from_secondary = true
|
93
|
+
@logger.info "#{@config_name}: The FC topology contains switches from primary site: #{node}"
|
94
|
+
else
|
95
|
+
@logger.warn "#{@config_name}: The FC topology does not contain switches from primary site: #{node}"
|
96
|
+
end
|
97
|
+
|
98
|
+
end # if !can_ping_primary_from_secondary then
|
99
|
+
end # @all_nodes.each do |node|
|
100
|
+
end # Net::SSH.start("172.16.0.150", "admin", :password => "next1rapass1") do |ssh|
|
101
|
+
end # if (@fc_topology_check ) & !(can_ping_primary_from_secondary) then
|
102
|
+
|
103
|
+
return can_ping_primary_from_secondary
|
104
|
+
end # ping_primary_from_secondary
|
105
|
+
|
106
|
+
def list_nodes_on_secondary
|
107
|
+
xcommand = NaElement.new("cluster-node-get-iter")
|
108
|
+
xcommand.child_add_string("desired-attributes","node-name")
|
109
|
+
result = @connection.invoke_elem(xcommand)
|
110
|
+
|
111
|
+
if (result.results_status() == "failed")
|
112
|
+
@logger.fatal "#{@config_name}: Unable to retrieve nodes: #{result.results_reason()}"
|
113
|
+
# do some logging
|
114
|
+
else
|
115
|
+
@logger.info "#{@config_name}: Successfuly retrieved nodes"
|
116
|
+
end
|
117
|
+
|
118
|
+
nodeinfo = result.child_get("attributes-list")
|
119
|
+
result_list = nodeinfo.children_get()
|
120
|
+
nodes = []
|
121
|
+
result_list.each do |node|
|
122
|
+
nodes.push(node.child_get_string("node-name")) if node.child_get_string("is-node-healthy")
|
123
|
+
end
|
124
|
+
return nodes
|
125
|
+
end # list_nodes_on_secondary
|
126
|
+
|
127
|
+
def failover
|
128
|
+
success = true
|
129
|
+
if quiesce then
|
130
|
+
if smirror_break
|
131
|
+
if start_secondary_svm
|
132
|
+
else
|
133
|
+
success = false
|
134
|
+
end
|
135
|
+
else
|
136
|
+
success = false
|
137
|
+
end
|
138
|
+
|
139
|
+
else
|
140
|
+
success = false
|
141
|
+
end
|
142
|
+
return success
|
143
|
+
end
|
144
|
+
|
145
|
+
def quiesce
|
146
|
+
=begin
|
147
|
+
success = true
|
148
|
+
@logger.info "#{@config_name}:Trying to quiesce snapmirror relationship"
|
149
|
+
xcommand = NaElement.new("snapmirror-quiesce")
|
150
|
+
xcommand.child_add_string("destination-location", "#{@secondary_svm}:")
|
151
|
+
result = @connection.invoke_elem(xcommand)
|
152
|
+
if (result.results_status() == "failed")
|
153
|
+
@logger.fatal "#{@config_name}: Unable to quiesce snapmirror relationship: #{result.results_reason()}"
|
154
|
+
success = false
|
155
|
+
end
|
156
|
+
return success
|
157
|
+
=end
|
158
|
+
return true
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def smirror_break
|
163
|
+
success = true
|
164
|
+
smirror_abort
|
165
|
+
@logger.info "#{@config_name}:Trying to break snapmirror relationship"
|
166
|
+
xcommand = NaElement.new("snapmirror-break")
|
167
|
+
xcommand.child_add_string("destination-location", "#{@secondary_svm}:")
|
168
|
+
result = @connection.invoke_elem(xcommand)
|
169
|
+
if (result.results_status() == "failed")
|
170
|
+
@logger.fatal "#{@config_name}: Unable to break snapmirror relationship: #{result.results_reason()}"
|
171
|
+
success = false
|
172
|
+
end
|
173
|
+
waitforsnapmirror("broken-off") if success
|
174
|
+
return success
|
175
|
+
end
|
176
|
+
|
177
|
+
def smirror_abort
|
178
|
+
@logger.info "#{@config_name}:Trying to abort snapmirror transfer"
|
179
|
+
xcommand = NaElement.new("snapmirror-abort")
|
180
|
+
xcommand.child_add_string("destination-location", "#{@secondary_svm}:")
|
181
|
+
result = @connection.invoke_elem(xcommand)
|
182
|
+
if (result.results_status() == "failed")
|
183
|
+
@logger.fatal "#{@config_name}: Unable to abort snapmirror transfer: #{result.results_reason()}"
|
184
|
+
end
|
185
|
+
#
|
186
|
+
waitforsnapmirror("idle")
|
187
|
+
|
188
|
+
end
|
189
|
+
=begin
|
190
|
+
def waitforsnapmirror(required_state)
|
191
|
+
xcommand = NaElement.new("snapmirror-get")
|
192
|
+
xcommand.child_add_string("destination-location", "#{@secondary_svm}:")
|
193
|
+
|
194
|
+
output = @connection.invoke_elem(xcommand).children_get()[0].children_get()[0].child_get("relationship-status").content if required_state.eql?("idle")
|
195
|
+
|
196
|
+
output = @connection.invoke_elem(xcommand).children_get()[0].children_get()[0].child_get("mirror-state").content if required_state.eql?("broken-off")
|
197
|
+
|
198
|
+
#while not @connection.invoke_elem(xcommand).children_get()[0].children_get()[0].child_get("relationship-status").content.eql?("idle")
|
199
|
+
while not output.eql?(required_state)
|
200
|
+
@logger.warn "#{@config_name}: Waiting to #{required_state} state... Currently: #{output}"
|
201
|
+
sleep 1
|
202
|
+
output = @connection.invoke_elem(xcommand).children_get()[0].children_get()[0].child_get("relationship-status").content
|
203
|
+
end
|
204
|
+
end
|
205
|
+
=end
|
206
|
+
|
207
|
+
|
208
|
+
def waitforsnapmirror(state)
|
209
|
+
result_out = ""
|
210
|
+
while not result_out.eql?(state)
|
211
|
+
xcommand = NaElement.new("snapmirror-get")
|
212
|
+
xcommand.child_add_string("destination-location", "SVM-S1-SAPHANA01-DR:")
|
213
|
+
smattribs_desired = NaElement.new("desired-attributes")
|
214
|
+
sminfo_desired = NaElement.new("snapmirror-info")
|
215
|
+
relationship_status_desired = NaElement.new("relationship-status")
|
216
|
+
mirror_state_desired = NaElement.new("mirror-state")
|
217
|
+
|
218
|
+
sminfo_desired.child_add(relationship_status_desired)
|
219
|
+
sminfo_desired.child_add(mirror_state_desired)
|
220
|
+
smattribs_desired.child_add(sminfo_desired)
|
221
|
+
xcommand.child_add(smattribs_desired)
|
222
|
+
sm_elements = @connection.invoke_elem(xcommand)
|
223
|
+
#puts sm_elements.inspect
|
224
|
+
sm_elements.children_get.each{ |sminfo|
|
225
|
+
sminfo.children_get.each { | smi |
|
226
|
+
if state.eql?("broken-off") then
|
227
|
+
result_out = smi.child_get_string("mirror-state")
|
228
|
+
else
|
229
|
+
result_out = smi.child_get_string("relationship-status")
|
230
|
+
end
|
231
|
+
}
|
232
|
+
|
233
|
+
}
|
234
|
+
@logger.warn "#{@config_name}: Waiting for #{state} state... Currently: #{result_out}"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def start_secondary_svm
|
239
|
+
success = true
|
240
|
+
set_admin_state_of_data_lifs_on_secondary_svm("down")
|
241
|
+
|
242
|
+
@logger.info "#{@config_name}:Trying to start svm: #{@secondary_svm}"
|
243
|
+
xcommand = NaElement.new("vserver-start")
|
244
|
+
xcommand.child_add_string("vserver-name", @secondary_svm)
|
245
|
+
result = @connection.invoke_elem(xcommand)
|
246
|
+
if (result.results_status() == "failed")
|
247
|
+
@logger.fatal "#{@config_name}: Unable to start SVM #{@secondary_svm}: #{result.results_reason()}"
|
248
|
+
success = false
|
249
|
+
else
|
250
|
+
@logger.info "#{@config_name}: Successfuly start SVM: #{@secondary_svm}"
|
251
|
+
end
|
252
|
+
sleep 10
|
253
|
+
set_state_of_luns_on_secondary_svm("offline")
|
254
|
+
change_serial_of_luns_on_secondary_svm
|
255
|
+
set_state_of_luns_on_secondary_svm("online")
|
256
|
+
set_admin_state_of_data_lifs_on_secondary_svm("up")
|
257
|
+
|
258
|
+
return success
|
259
|
+
end
|
260
|
+
|
261
|
+
def set_admin_state_of_data_lifs_on_secondary_svm(state)
|
262
|
+
success = true
|
263
|
+
@logger.info "#{@config_name}:Trying to #{state} data interfaces"
|
264
|
+
@secondary_svm_data_interfaces.each{ |lif|
|
265
|
+
xcommand = NaElement.new("net-interface-modify")
|
266
|
+
xcommand.child_add_string("interface-name", lif["interface-name"])
|
267
|
+
xcommand.child_add_string("vserver", @secondary_svm)
|
268
|
+
|
269
|
+
if state.eql?("up") then
|
270
|
+
xcommand.child_add_string("administrative-status", lif["administrative-status"])
|
271
|
+
else
|
272
|
+
xcommand.child_add_string("administrative-status", state)
|
273
|
+
end # state.eql?("up") then
|
274
|
+
|
275
|
+
result = @connection.invoke_elem(xcommand)
|
276
|
+
|
277
|
+
if (result.results_status() == "failed")
|
278
|
+
@logger.fatal "#{@config_name}: Unable to #{state} data lif #{lif['interface-name']}: #{result.results_reason()}"
|
279
|
+
success = false
|
280
|
+
else
|
281
|
+
if state.eql?("up") then
|
282
|
+
@logger.info "#{@config_name}: Successfuly #{lif['administrative-status']} data lif #{lif['interface-name']}"
|
283
|
+
else
|
284
|
+
@logger.info "#{@config_name}: Successfuly #{state} data lif #{lif['interface-name']}"
|
285
|
+
end #if state.eql?("up") then
|
286
|
+
|
287
|
+
end
|
288
|
+
}
|
289
|
+
end # set_admin_state_of_data_lifs_on_secondary_svm(state)
|
290
|
+
|
291
|
+
|
292
|
+
def set_state_of_luns_on_secondary_svm(state)
|
293
|
+
success = true
|
294
|
+
@logger.info "#{@config_name}:Trying to change the state of luns to #{state}"
|
295
|
+
con_success = false
|
296
|
+
#puts @secondary_svm_management_interfaces.inspect
|
297
|
+
@secondary_svm_management_interfaces.each{ |lif|
|
298
|
+
|
299
|
+
if ! con_success & lif["administrative-status"].eql?("up") then
|
300
|
+
|
301
|
+
vconnection_secondary = NaServer.new(lif["address"], 1, 3)
|
302
|
+
# puts lif.inspect
|
303
|
+
vconnection_secondary.set_admin_user(@secondary_svm_user, @secondary_svm_password)
|
304
|
+
xcommand = NaElement.new("system-get-version")
|
305
|
+
result = vconnection_secondary.invoke_elem(xcommand)
|
306
|
+
if (result.results_status() == "failed")
|
307
|
+
@logger.fatal "#{@config_name}: Unable to connect secondary SVM #{@secondary_svm} for changing luns state to #{state}: #{result.results_reason()}"
|
308
|
+
#success = false
|
309
|
+
else
|
310
|
+
con_success = true
|
311
|
+
end
|
312
|
+
|
313
|
+
if con_success then
|
314
|
+
@primary_svm_luns.each{ |lun|
|
315
|
+
xcommand = NaElement.new("lun-#{state}") #lun-online / lun-offline
|
316
|
+
xcommand.child_add_string("path", lun["path"])
|
317
|
+
|
318
|
+
if state.eql?("online") then
|
319
|
+
if lun["online"].eql?("true") then
|
320
|
+
result = vconnection_secondary.invoke_elem(xcommand)
|
321
|
+
if (result.results_status() == "failed")
|
322
|
+
@logger.error "#{@config_name}: Unable to #{state} lun #{lun['path']} #{@secondary_svm}: #{result.results_reason()}"
|
323
|
+
else
|
324
|
+
@logger.info "#{@config_name}: Successfuly set #{state} lun #{lun['path']} #{@secondary_svm} "
|
325
|
+
end
|
326
|
+
end
|
327
|
+
else # state.eql?("online") --> offline
|
328
|
+
result = vconnection_secondary.invoke_elem(xcommand)
|
329
|
+
if (result.results_status() == "failed")
|
330
|
+
@logger.error "#{@config_name}: Unable to #{state} lun #{lun['path']} #{@secondary_svm}: #{result.results_reason()}"
|
331
|
+
else
|
332
|
+
@logger.info "#{@config_name}: Successfuly set #{state} lun #{lun['path']} #{@secondary_svm} "
|
333
|
+
end
|
334
|
+
end # state.eql?("online")
|
335
|
+
}
|
336
|
+
end
|
337
|
+
end
|
338
|
+
}
|
339
|
+
end # end def set_state_of_luns_on_secondary_svm(state)
|
340
|
+
|
341
|
+
|
342
|
+
def change_serial_of_luns_on_secondary_svm
|
343
|
+
success = true
|
344
|
+
@logger.info "#{@config_name}:Trying to change serial-number of luns"
|
345
|
+
con_success = false
|
346
|
+
@secondary_svm_management_interfaces.each{ |lif|
|
347
|
+
if ! con_success & lif["administrative-status"].eql?("up") then
|
348
|
+
vconnection_secondary = NaServer.new(lif["address"], 1, 3)
|
349
|
+
vconnection_secondary.set_admin_user(@secondary_svm_user, @secondary_svm_password)
|
350
|
+
xcommand = NaElement.new("system-get-version")
|
351
|
+
result = vconnection_secondary.invoke_elem(xcommand)
|
352
|
+
if (result.results_status() == "failed")
|
353
|
+
@logger.fatal "#{@config_name}: Unable to connect secondary SVM #{@secondary_svm}: #{result.results_reason()}"
|
354
|
+
#success = false
|
355
|
+
else
|
356
|
+
con_success = true
|
357
|
+
end
|
358
|
+
if con_success then
|
359
|
+
@primary_svm_luns.each{ |lun|
|
360
|
+
xcommand = NaElement.new("lun-set-serial-number")
|
361
|
+
xcommand.child_add_string("path", lun["path"])
|
362
|
+
xcommand.child_add_string("serial-number", lun["serial-number"])
|
363
|
+
|
364
|
+
result = vconnection_secondary.invoke_elem(xcommand)
|
365
|
+
if (result.results_status() == "failed")
|
366
|
+
@logger.error "#{@config_name}: Unable to change the serial of lun #{lun['path']} #{@secondary_svm}: #{result.results_reason()}"
|
367
|
+
else
|
368
|
+
@logger.info "#{@config_name}: Successfuly changed the serial of lun #{lun['path']} #{@secondary_svm}"
|
369
|
+
end
|
370
|
+
}
|
371
|
+
end
|
372
|
+
end
|
373
|
+
}
|
374
|
+
end # end def set_state_of_luns_on_secondary_svm(state)
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
def get_management_interfaces(primary_or_secondary)
|
379
|
+
management_interfaces=[]
|
380
|
+
|
381
|
+
xcommand = NaElement.new("net-interface-get-iter")
|
382
|
+
netattribs_desired = NaElement.new("desired-attributes")
|
383
|
+
interfaceinfo_desired = NaElement.new("net-interface-info")
|
384
|
+
vserver_name_desired = NaElement.new("vserver")
|
385
|
+
firewallpolicy_desired = NaElement.new("firewall-policy")
|
386
|
+
dataprotocols_desired = NaElement.new("data-protocols")
|
387
|
+
|
388
|
+
dataprotocols_array_desired = NaElement.new("data-protocol")
|
389
|
+
dataprotocols_desired.child_add(dataprotocols_array_desired)
|
390
|
+
|
391
|
+
operationalstatus_desired = NaElement.new("operational-status")
|
392
|
+
administrativestatus_desired = NaElement.new("administrative-status")
|
393
|
+
|
394
|
+
address_desired = NaElement.new("address")
|
395
|
+
|
396
|
+
interfaceinfo_desired.child_add(vserver_name_desired)
|
397
|
+
interfaceinfo_desired.child_add(firewallpolicy_desired)
|
398
|
+
interfaceinfo_desired.child_add(dataprotocols_desired)
|
399
|
+
interfaceinfo_desired.child_add(operationalstatus_desired)
|
400
|
+
interfaceinfo_desired.child_add(administrativestatus_desired)
|
401
|
+
interfaceinfo_desired.child_add(address_desired)
|
402
|
+
|
403
|
+
netattribs_desired.child_add(interfaceinfo_desired)
|
404
|
+
|
405
|
+
netattribs_query = NaElement.new("query")
|
406
|
+
interfaceinfo_query = NaElement.new("net-interface-info")
|
407
|
+
svm = ""
|
408
|
+
if primary_or_secondary.eql?("primary") then
|
409
|
+
svm = @primary_svm
|
410
|
+
else
|
411
|
+
svm = @secondary_svm
|
412
|
+
end
|
413
|
+
|
414
|
+
interfaceinfo_query.child_add_string("vserver",svm)
|
415
|
+
|
416
|
+
#interfaceinfo_query.child_add_string("administrative-status","up") #if primary_or_secondary.eql?("primary")
|
417
|
+
dataprotocols_query = NaElement.new("data-protocols")
|
418
|
+
dataprotocols_query.child_add_string("data-protocol","none")
|
419
|
+
interfaceinfo_query.child_add(dataprotocols_query)
|
420
|
+
|
421
|
+
netattribs_query.child_add(interfaceinfo_query)
|
422
|
+
|
423
|
+
xcommand.child_add(netattribs_desired)
|
424
|
+
xcommand.child_add(netattribs_query)
|
425
|
+
|
426
|
+
if primary_or_secondary.eql?("primary") then
|
427
|
+
output = @connection_primary.invoke_elem(xcommand)
|
428
|
+
else
|
429
|
+
output = @connection.invoke_elem(xcommand)
|
430
|
+
end
|
431
|
+
|
432
|
+
if (output.results_status() == "failed") then
|
433
|
+
@logger.fatal "#{@config_name}: Unable to connect to #{svm} for getting management interfaces: #{output.results_reason()}"
|
434
|
+
return nil
|
435
|
+
end
|
436
|
+
|
437
|
+
result_count = output.child_get_int("num-records")
|
438
|
+
#puts output.inspect
|
439
|
+
if result_count>0 then
|
440
|
+
info_interfaces = output.children_get()
|
441
|
+
info_interfaces.each { |interface_element_info|
|
442
|
+
if interface_element_info.class.name.eql?("NaElement") then
|
443
|
+
interface_info = interface_element_info.children_get()
|
444
|
+
interface_info.each{|interface|
|
445
|
+
management_interface = Hash.new
|
446
|
+
management_interface["address"] = interface.child_get_string("address")
|
447
|
+
management_interface["interface-name"] = interface.child_get_string("interface-name")
|
448
|
+
management_interface["administrative-status"] = interface.child_get_string("administrative-status")
|
449
|
+
management_interface["operational-status"] = interface.child_get_string("operational-status")
|
450
|
+
management_interfaces.push(management_interface)
|
451
|
+
}
|
452
|
+
end
|
453
|
+
}
|
454
|
+
else
|
455
|
+
end # result_count>0 then
|
456
|
+
@logger.info "#{@config_name}: Retrieved management interfaces from #{svm}: #{management_interfaces.inspect}"
|
457
|
+
return management_interfaces
|
458
|
+
end #get_management_interfaces
|
459
|
+
|
460
|
+
def get_data_interfaces(primary_or_secondary,protocol)
|
461
|
+
data_interfaces=[]
|
462
|
+
|
463
|
+
xcommand = NaElement.new("net-interface-get-iter")
|
464
|
+
netattribs_desired = NaElement.new("desired-attributes")
|
465
|
+
interfaceinfo_desired = NaElement.new("net-interface-info")
|
466
|
+
vserver_name_desired = NaElement.new("vserver")
|
467
|
+
dataprotocols_desired = NaElement.new("data-protocols")
|
468
|
+
|
469
|
+
dataprotocols_array_desired = NaElement.new("data-protocol")
|
470
|
+
dataprotocols_desired.child_add(dataprotocols_array_desired)
|
471
|
+
|
472
|
+
administrativestatus_desired = NaElement.new("administrative-status")
|
473
|
+
|
474
|
+
interfaceinfo_desired.child_add(vserver_name_desired)
|
475
|
+
interfaceinfo_desired.child_add(dataprotocols_desired)
|
476
|
+
interfaceinfo_desired.child_add(administrativestatus_desired)
|
477
|
+
|
478
|
+
netattribs_desired.child_add(interfaceinfo_desired)
|
479
|
+
|
480
|
+
netattribs_query = NaElement.new("query")
|
481
|
+
interfaceinfo_query = NaElement.new("net-interface-info")
|
482
|
+
|
483
|
+
svm = ""
|
484
|
+
if primary_or_secondary.eql?("primary") then
|
485
|
+
svm = @primary_svm
|
486
|
+
else
|
487
|
+
svm = @secondary_svm
|
488
|
+
end
|
489
|
+
|
490
|
+
interfaceinfo_query.child_add_string("vserver",svm)
|
491
|
+
|
492
|
+
dataprotocols_query = NaElement.new("data-protocols")
|
493
|
+
dataprotocols_query.child_add_string("data-protocol",protocol)
|
494
|
+
interfaceinfo_query.child_add(dataprotocols_query)
|
495
|
+
|
496
|
+
netattribs_query.child_add(interfaceinfo_query)
|
497
|
+
|
498
|
+
xcommand.child_add(netattribs_desired)
|
499
|
+
xcommand.child_add(netattribs_query)
|
500
|
+
|
501
|
+
output = @connection.invoke_elem(xcommand)
|
502
|
+
if (output.results_status() == "failed") then
|
503
|
+
@logger.fatal "#{@config_name}: Unable to connect to #{svm} for getting data interfaces: #{output.results_reason()}"
|
504
|
+
return nil
|
505
|
+
end
|
506
|
+
|
507
|
+
result_count = output.child_get_int("num-records")
|
508
|
+
|
509
|
+
if result_count>0 then
|
510
|
+
=begin
|
511
|
+
vsconnection = NaServer.new("172..0.", 1, 3)
|
512
|
+
vsconnection.set_admin_user("vsadmin", "")
|
513
|
+
vsxcommand = NaElement.new("system-get-version")
|
514
|
+
puts vsconnection.invoke_elem(vsxcommand).inspect
|
515
|
+
=end
|
516
|
+
info_interfaces = output.children_get()
|
517
|
+
info_interfaces.each { |interface_element_info|
|
518
|
+
if interface_element_info.class.name.eql?("NaElement") then
|
519
|
+
interface_info = interface_element_info.children_get()
|
520
|
+
interface_info.each{|interface|
|
521
|
+
data_interface = Hash.new
|
522
|
+
data_interface["interface-name"] = interface.child_get_string("interface-name")
|
523
|
+
data_interface["administrative-status"] = interface.child_get_string("administrative-status")
|
524
|
+
data_interface["data-protocol"] = protocol
|
525
|
+
data_interfaces.push(data_interface)
|
526
|
+
}
|
527
|
+
end
|
528
|
+
}
|
529
|
+
else
|
530
|
+
end # result_count>0 then
|
531
|
+
@logger.info "#{@config_name}: Retrieved data interfaces from #{svm} (#{primary_or_secondary}): #{data_interfaces.inspect}"
|
532
|
+
return data_interfaces
|
533
|
+
end # get_data_interfaces(primary_or_secondary)
|
534
|
+
|
535
|
+
def get_primary_luns
|
536
|
+
primary_luns=[]
|
537
|
+
xcommand = NaElement.new("lun-get-iter")
|
538
|
+
lunattribs_desired = NaElement.new("desired-attributes")
|
539
|
+
luninfo_desired = NaElement.new("lun-info")
|
540
|
+
|
541
|
+
vserver_name_desired = NaElement.new("vserver")
|
542
|
+
lun_path_desired = NaElement.new("path")
|
543
|
+
lun_online_desired = NaElement.new("online")
|
544
|
+
lun_serialnumber_desired = NaElement.new("serial-number")
|
545
|
+
|
546
|
+
luninfo_desired.child_add(vserver_name_desired)
|
547
|
+
luninfo_desired.child_add(lun_path_desired)
|
548
|
+
luninfo_desired.child_add(lun_online_desired)
|
549
|
+
luninfo_desired.child_add(lun_serialnumber_desired)
|
550
|
+
|
551
|
+
lunattribs_desired.child_add(luninfo_desired)
|
552
|
+
|
553
|
+
lunattribs_query = NaElement.new("query")
|
554
|
+
luninfo_query = NaElement.new("lun-info")
|
555
|
+
luninfo_query.child_add_string("vserver", @primary_svm)
|
556
|
+
lunattribs_query.child_add(luninfo_query)
|
557
|
+
xcommand.child_add(lunattribs_desired)
|
558
|
+
xcommand.child_add(lunattribs_query)
|
559
|
+
#puts xcommand.inspect
|
560
|
+
result = @connection_primary.invoke_elem(xcommand)
|
561
|
+
#puts result.inspect
|
562
|
+
if (result.results_status() == "failed") then
|
563
|
+
@logger.fatal "#{@config_name}: Unable to connect to #{@primary_svm} for getting luns: #{result.results_reason()}"
|
564
|
+
return nil
|
565
|
+
end
|
566
|
+
|
567
|
+
lun_elements = result.children_get()
|
568
|
+
|
569
|
+
lun_elements.each{ | lun_element |
|
570
|
+
if lun_element.class.name.eql?("NaElement") then
|
571
|
+
luns_info = lun_element.children_get()
|
572
|
+
luns_info.each{|lun_info|
|
573
|
+
lun = Hash.new
|
574
|
+
lun["path"] = lun_info.child_get_string("path")
|
575
|
+
lun["online"] = lun_info.child_get_string("online")
|
576
|
+
lun["serial-number"] = lun_info.child_get_string("serial-number")
|
577
|
+
primary_luns.push(lun)
|
578
|
+
}
|
579
|
+
end # lun_element.class.name.eql?("NaElement") then
|
580
|
+
}
|
581
|
+
|
582
|
+
@logger.info "#{@config_name}: Retrieved luns from #{@primary_svm}: #{primary_luns.inspect}"
|
583
|
+
|
584
|
+
return primary_luns
|
585
|
+
#puts result.inspect
|
586
|
+
end # end get_primary_luns
|
587
|
+
|
588
|
+
def test_connection(destination, caller)
|
589
|
+
##################
|
590
|
+
con_success = true
|
591
|
+
xcommand = NaElement.new("system-get-version")
|
592
|
+
if destination.eql?("primary_cluster")
|
593
|
+
result = @connection_primary.invoke_elem(xcommand)
|
594
|
+
elsif destination.eql?("secondary_cluster")
|
595
|
+
result = @connection.invoke_elem(xcommand)
|
596
|
+
else
|
597
|
+
end #destination.eql?("primary_cluster")
|
598
|
+
|
599
|
+
if (result.results_status() == "failed")
|
600
|
+
@logger.fatal "#{@config_name}: Unable to connect #{destination} while attempting to check connection for #{caller}: #{result.results_reason()}"
|
601
|
+
con_success = false
|
602
|
+
else
|
603
|
+
@logger.info "#{@config_name}: Successfuly connect #{destination} while attempting to check connection for #{caller}"
|
604
|
+
end
|
605
|
+
|
606
|
+
return con_success
|
607
|
+
end # end test connection
|
608
|
+
|
609
|
+
end #class end
|
610
|
+
|