summaryrefslogtreecommitdiffstats
path: root/heartbeat/VIPArip
blob: 688237d9d277fd4b8cd9cf537fc571d0cc842698 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#!/bin/sh
#
# 	License:	GNU General Public License (GPL) 
# 	Support:	users@clusterlabs.org
#	Author: 	Huang Zhen <zhenhltc@cn.ibm.com>
# 	Copyright (c) 	2006 International Business Machines
#
#	Virtual IP Address by RIP2 protocol.
#	This script manages IP alias in different subnet with quagga/ripd.
#	It can add an IP alias, or remove one.
#	
#	The quagga package should be installed to run this RA
#
#	usage: $0 {start|stop|status|monitor|validate-all|meta-data}
#
#	The "start" arg adds an IP alias.
#	Surprisingly, the "stop" arg removes one. :-)
#
#       OCF parameters are as below
#       OCF_RESKEY_ip	The IP address in different subnet
#       OCF_RESKEY_nic	The nic for broadcast the route information
#
#######################################################################
# Initialization:

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs

RIPDCONF=$HA_RSCTMP/VIPArip-ripd.conf
ZEBRA=/usr/sbin/zebra
RIPD=/usr/sbin/ripd
USAGE="usage: $0 {start|stop|status|monitor|validate-all|meta-data}";

# Parameter defaults

OCF_RESKEY_ip_default=""
OCF_RESKEY_nic_default="eth0"
OCF_RESKEY_zebra_binary_default="${ZEBRA}"
OCF_RESKEY_ripd_binary_default="${RIPD}"

: ${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}}
: ${OCF_RESKEY_nic=${OCF_RESKEY_nic_default}}
: ${OCF_RESKEY_zebra_binary=${OCF_RESKEY_zebra_binary_default}}
: ${OCF_RESKEY_ripd_binary=${OCF_RESKEY_ripd_binary_default}}

#######################################################################

meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="VIPArip" version="1.0">
<version>1.0</version>

<longdesc lang="en">
Virtual IP Address by RIP2 protocol.
This script manages IP alias in different subnet with quagga/ripd.
It can add an IP alias, or remove one.
</longdesc>
<shortdesc lang="en">Manages a virtual IP address through RIP2</shortdesc>

<parameters>

<parameter name="ip" unique="1" required="1">
<longdesc lang="en">
The IPv4 address in different subnet, for example "192.168.1.1".
</longdesc>
<shortdesc lang="en">The IP address in different subnet</shortdesc>
<content type="string" default="${OCF_RESKEY_ip_default}" />
</parameter>

<parameter name="nic" unique="0">
<longdesc lang="en">
The nic for broadcast the route information.
The ripd uses this nic to broadcast the route information to others
</longdesc>
<shortdesc lang="en">The nic for broadcast the route information</shortdesc>
<content type="string" default="${OCF_RESKEY_nic_default}"/>
</parameter>

<parameter name="zebra_binary" unique="0">
<longdesc lang="en">
Absolute path to the zebra binary.
</longdesc>
<shortdesc lang="en">zebra binary</shortdesc>
<content type="string" default="${OCF_RESKEY_zebra_binary_default}"/>
</parameter>

<parameter name="ripd_binary" unique="0">
<longdesc lang="en">
Absolute path to the ripd binary.
</longdesc>
<shortdesc lang="en">ripd binary</shortdesc>
<content type="string" default="${OCF_RESKEY_ripd_binary_default}"/>
</parameter>

</parameters>

<actions>
<action name="start"   timeout="20s" />
<action name="stop"    timeout="20s" />
<action name="monitor" depth="0"  timeout="20s" interval="5s" />
<action name="validate-all"  timeout="20s" />
<action name="meta-data"  timeout="5s" />
</actions>
</resource-agent>
END
exit $OCF_SUCCESS
}

usage() {
  echo $USAGE >&2
}

new_config_file() {
	echo new_config_file $1 $2 $3
	cat >$RIPDCONF <<END
hostname ripd
password zebra
debug rip events
debug rip packet
debug rip zebra
log file /var/log/quagga/quagga.log
router rip
!nic_tag
 no passive-interface $2
 network $2
 distribute-list private out $2
 distribute-list private in $2
!metric_tag
 redistribute connected metric $3
!ip_tag
access-list private permit $1/32
access-list private deny any
END
}
check_params() {
	if [ x"$OCF_RESKEY_ip" = x ]
	then
		ocf_log err "ip is a required parameter"
		exit $OCF_ERR_CONFIGURED
	fi
}
set_metric() {
	echo set_metric $1
	sed "s/redistribute connected metric .*/redistribute connected metric $1/g" $RIPDCONF > $RIPDCONF.tmp
	cp $RIPDCONF.tmp $RIPDCONF
}

add_ip() {
	echo add_ip $1
	sed "s/ip_tag/ip_tag\naccess-list private permit $1\/32/g" $RIPDCONF > $RIPDCONF.tmp
	cp $RIPDCONF.tmp $RIPDCONF
}

del_ip() {
	echo del_ip $1
	sed "/$1/d" $RIPDCONF > $RIPDCONF.tmp
	cp $RIPDCONF.tmp $RIPDCONF
	if $GREP "access-list private permit" $RIPDCONF>/dev/null 
	then
		echo some other IP is running
		reload_config
	else
		stop_quagga
		echo remove $RIPDCONF
		rm $RIPDCONF
	fi
	
}

add_nic() {
	echo add_nic $1
	if $GREP "network $1" $RIPDCONF >/dev/null 
	then
		echo the nic is already in the config file
	else
		sed "s/nic_tag/nic_tag\n no passive-interface $1\n network $1\n distribute-list private out $1\n distribute-list private in $1/g" $RIPDCONF > $RIPDCONF.tmp
		cp $RIPDCONF.tmp $RIPDCONF
	fi
}

reload_config() {
	echo reload_config
	echo $RIPDCONF:
	cat $RIPDCONF
	echo killall -SIGHUP ripd
	killall -SIGHUP ripd
}

start_quagga() {
	echo start_quagga
	echo $RIPDCONF:
	cat $RIPDCONF
	echo $ZEBRA -d
	$ZEBRA -d
	echo $RIPD -d -f $RIPDCONF
	$RIPD -d -f $RIPDCONF
}

stop_quagga() {
	echo stop_quagga
	echo $RIPDCONF:
	cat $RIPDCONF
	echo killall -SIGTERM ripd
	killall -SIGTERM ripd
	echo killall -SIGTERM zebra
	killall -SIGTERM zebra
}

start_rip_ip() {
	echo start_rip_ip
	check_params	

	if [ x"$OCF_RESKEY_nic" = x ]
	then
		echo OCF_RESKEY_nic is null, set to ${OCF_RESKEY_nic_default}
		OCF_RESKEY_nic="${OCF_RESKEY_nic_default}"
	fi
	
	status_rip_ip
	case $? in
	$OCF_SUCCESS)
		ocf_log info "already running"
		exit $OCF_SUCCESS
		;;
	$OCF_NOT_RUNNING)
		;;
	*)
		ocf_log info "state undefined, stopping first"
		stop_rip_ip
		;;
	esac

	$IP2UTIL addr add $OCF_RESKEY_ip/32 dev lo          
	if [ -f "$RIPDCONF" ]
	then
		# there is a config file, add new data(IP,nic,metric) 
		# to the existing config file.
		add_ip $OCF_RESKEY_ip
		add_nic $OCF_RESKEY_nic
		set_metric 1
		reload_config
		echo sleep 3
		sleep 3
		set_metric 3
		reload_config
	else
		new_config_file $OCF_RESKEY_ip $OCF_RESKEY_nic 1
		start_quagga
		echo sleep 3
		sleep 3
		set_metric 3
		reload_config
	fi
	return $OCF_SUCCESS
}

stop_rip_ip() {
	echo stop_rip_ip
	check_params
	status_rip_ip
	if [ $? = $OCF_NOT_RUNNING ]
	then
		exit $OCF_SUCCESS
	fi
	$IP2UTIL addr del $OCF_RESKEY_ip dev lo
	echo sleep 2
	sleep 2
	del_ip	$OCF_RESKEY_ip
	return $OCF_SUCCESS
}

status_rip_ip() {
	check_params
	if $IP2UTIL addr | $GREP $OCF_RESKEY_ip >/dev/null 
	then
		if $GREP $OCF_RESKEY_ip $RIPDCONF >/dev/null 
		then
			if pidof ripd >/dev/null
			then
				return $OCF_SUCCESS
			fi
		fi
		return $OCF_ERR_GENERIC
	fi
	return $OCF_NOT_RUNNING
}

if
  [ $# -ne 1 ]
then
  usage
  exit $OCF_ERR_ARGS
fi

[ x != x"$OCF_RESKEY_zebra_binary" ] &&
	ZEBRA=$OCF_RESKEY_zebra_binary
[ x != x"$OCF_RESKEY_ripd_binary" ] &&
	RIPD=$OCF_RESKEY_ripd_binary

case $1 in
  start)	start_rip_ip;;
  stop)		stop_rip_ip;;
  status)	status_rip_ip;;
  monitor)	status_rip_ip;;
  validate-all)	check_binary $IP2UTIL
		exit $OCF_SUCCESS;;
  meta-data)	meta_data;;
  usage)	usage; exit $OCF_SUCCESS;;
  *)		usage
 		exit $OCF_ERR_UNIMPLEMENTED
		;;
esac