Revision ad5c908a

b/dnshook
1
#!/bin/sh
1
#!/bin/bash
2 2

  
3 3
set -e
4 4

  
5
# Configuration Fallbacks. All can(must for some of them) be overwritten by /etc/ganeti/dnshook.conf
5
# Configuration Fallbacks. All can(must for some of them) be overwritten by /etc/default/snf-network
6 6
TTL=300
7
# the bind server IP/FQDN
7 8
SERVER=""
8
FZONE="" # Leave empty if only reverse dns management is needed. Don't forget the trailing dot
9
# this is the .vm.synnefo.live.
10
# Leave empty if only reverse dns management is needed.
11
# TODO: make this zone to be instance specific!!!
12
FZONE=""
13
# the file with dns authorization keys
9 14
KEYFILE=""
10 15
MAC2EUI64="/usr/bin/mac2eui64"
11 16

  
12
if [ -e /etc/ganeti/dnshook.conf ]; then
13
	. /etc/ganeti/dnshook.conf 
14
else
15
	exit 0
17
source /etc/default/snf-network
18

  
19
if [ -z "$SERVER" -o -z "$FZONE" -o -z "$KEYFILE" ]; then
20
  exit 0
16 21
fi
17 22

  
18 23
update () {
......
26 31
EOF
27 32
}
28 33

  
29
addremove () {
30
	local action=$1
31
	local REVZONE=$2
32
	local REV6ZONE=$3
33
	local REVLPART=$4
34
	local REV6LPART=$5
35

  
36
	update $REVZONE "update $action $REVLPART.$REVZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
37
	update $REV6ZONE "update $action $REV6LPART$REV6ZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
38

  
39
	if [ ! -z "$7" ]; then
40
		EUI64=$6
41
		FORZONE=$7
42
		update $FORZONE "update $action $GANETI_INSTANCE_NAME.$FORZONE $TTL A $GANETI_INSTANCE_NIC0_IP"
43
		update $FORZONE "update $action $GANETI_INSTANCE_NAME.$FORZONE $TTL AAAA $EUI64" 
44
	fi
34

  
35
# ommit zone statement
36
# nsupdate  will attempt determine the correct zone to update based on the rest of the input
37
send_command () {
38

  
39
	local command="$1"
40
	nsupdate -k $KEYFILE > /dev/null << EOF
41
	server $SERVER
42
	$command
43
	send
44
EOF
45

  
45 46
}
46 47

  
48

  
49
addremove_arecord () {
50

  
51
  local action=$1
52
  local command=
53
  if [ -n "$IP" ]; then
54
    command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL A $IP"
55
    send_command "$command"
56
  fi
57
  if [ -n "$EUI64" ]; then
58
    command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL AAAA $EUI64"
59
    send_command "$command"
60
  fi
61

  
62
}
63

  
64
addremove_ptrrecord () {
65

  
66
  local action=$1
67
  local command=
68
  if [ -n "$IP" ]; then
69
	  command="update $action $RLPART.$RZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
70
    send_command "$command"
71
  fi
72
  if [ -n "$EUI64" ]; then
73
	  command="update $action $R6LPART.$R6ZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
74
    send_command "$command"
75
  fi
76

  
77
}
78

  
79

  
80
# first argument is an eui64 (IPv6)
81
# sets GLOBAL args R6REC, R6ZONE, R6LPART
82
# lets assume eui64=eui64=2001:648:2ffc:1::1
83
# the following commands produce:
84
# R6REC=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
85
# R6ZONE=1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
86
# R6LPART=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
87
get_rev6_info () {
88

  
89
  local eui64=$1
90
  if [ -z "$eui64" ]; then
91
    R6REC= ; R6ZONE= ; R6LPART= ;
92
  else
93
    R6REC=$(host $eui64 | egrep -o '([[:alnum:]]\.){32}ip6.arpa' )
94
    R6ZONE=$(echo $R6REC | awk -F. 'BEGIN{rpart="";} { for (i=32;i>16;i=i-1) rpart=$i "." rpart; } END{print rpart "ip6.arpa";}')
95
    R6LPART=$(echo $R6REC | awk -F. 'BEGIN{lpart="";} { for (i=16;i>0;i=i-1) lpart=$i "." lpart; } END{print lpart;}')
96
  fi
97

  
98
}
99

  
100

  
101
# first argument is an ipv4
102
# sets args RZONE, RLPART
103
# lets assume IP=203.0.113.1
104
# RZONE="113.0.203.in-add.arpa"
105
# RLPART="1"
106
get_rev4_info () {
107

  
108
  local ip=$1
109
  if [ -z "$ip" ]; then
110
    RZONE= ; RLPART= ;
111
  else
112
    OLDIFS=$IFS
113
    IFS=". "
114
    set -- $ip
115
    a=$1 ; b=$2; c=$3; d=$4;
116
    IFS=$OLDIFS
117
    RZONE="$c.$b.$a.in-addr.arpa"
118
    RLPART="$d"
119
  fi
120

  
121
}
122

  
123

  
124
update_dns () {
125

  
126
  if [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_CREATE" ]; then
127
    update_arecord add
128
    update_ptrrecord add
129
  elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_REMOVE" ]; then
130
    update_arecord delete
131
    update_ptrrecord delete
132
  elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_RENAME" ]; then
133
    update_arecord delete
134
    update_ptrrecord delete
135
    # Let's override a variable and add ourselves
136
    GANETI_INSTANCE_NAME=$GANETI_INSTANCE_NEW_NAME
137
    update_arecord add
138
    update_ptrrecord add
139
  elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_STARTUP" ]; then
140
    update_arecord add
141
    update_ptrrecord add
142
  elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_SHUTDOWN" ]; then
143
    update_arecord delete
144
    update_ptrrecord delete
145
  elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_REBOOT" ]; then
146
    update_arecord add
147
    update_ptrrecord add
148
  elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_SET_PARAMS" ]; then
149
    update_arecord add
150
    update_ptrrecord add
151
  fi
152

  
153
}
154

  
155

  
156
# Query nameserver for entries related to the specific instance
157
# An example output is the following:
158
# www.google.com has address 173.194.113.114
159
# www.google.com has address 173.194.113.115
160
# www.google.com has address 173.194.113.116
161
# www.google.com has address 173.194.113.112
162
# www.google.com has address 173.194.113.113
163
# www.google.com has IPv6 address 2a00:1450:4001:80b::1012
164
query_dns () {
165

  
166
  HOSTQ="host -s -R 3 -W 3"
167
  HOST_IP_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has address //p')
168
  HOST_IP6_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has IPv6 address //p')
169

  
170
}
171

  
172

  
173
# Reset all entries related to the specific instance
174
# This should be invoced only during instance modification
175
# because we do not know which nics have been modify
176
reset_dns () {
177

  
178
  if [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_SET_PARAMS" ]; then
179
    query_dns
180
    # This should remove the A, AAAA, CNAME entries
181
    run_action "update delete $GANETI_INSTANCE_NAME.$FZONE"
182
    for ip in $HOST_IP_ALL; do
183
      get_rev4_info $ip
184
      # This should remove the IPv4 reverse entry
185
      run_action "update delete $RLPART.$RZONE"
186
    done
187
    for ip6 in $HOST_IP6_ALL; do
188
      get_rev6_info $ip6
189
      # This should remove the IPv6 reverse entry
190
      run_action "update delete $R6LPART$R6ZONE."
191
    done
192
  fi
193

  
194
}
195

  
196

  
197
# Because we do not have IPv6 value in our environment
198
# we caclulate it based on the NIC's MAC and the IPv6 subnet (if any)
199
# first argument MAC second IPv6 subnet
200
# Changes global value EUI64
201
get_eui64 () {
202

  
203
  local mac=$1
204
  local prefix=$2
205

  
206
  if [ -z "$prefix" ]; then
207
    EUI64=
208
  else
209
    EUI64=$($MAC2EUI64 $MAC $SUBNET6)
210
  fi
211

  
212
}
213

  
214

  
47 215
# Main starts here
48
if [ "x" = "x$GANETI_INSTANCE_NIC0_IP" ]; then
49
	exit 1
50
else
51
	OLDIFS=$IFS
52
	IFS=". "
53
	set -- $GANETI_INSTANCE_NIC0_IP
54
	a=$1 ; b=$2; c=$3; d=$4;
55
	IFS=$OLDIFS
56
	RZONE="$c.$b.$a.in-addr.arpa"
57
	RLPART="$d"
58

  
59
	# NOTE: We are going to assume one simple thing. /64s ...
60
	# A mistake but good enough for alpha and autoconfiguration
61
	prefix=$(ip -6 route list table $GANETI_INSTANCE_NIC0_LINK | awk '/\/64/ {print $1; exit}')
62
	eui64=$($MAC2EUI64 $GANETI_INSTANCE_NIC0_MAC $prefix)
63
	R6REC=$(host $eui64 | egrep -o '([[:alnum:]]\.){32}ip6.arpa' )
64
	R6ZONE=$(echo $R6REC | awk -F. 'BEGIN{rpart="";} { for (i=32;i>16;i=i-1) rpart=$i "." rpart; } END{print rpart "ip6.arpa";}')
65
	R6LPART=$(echo $R6REC | awk -F. 'BEGIN{lpart="";} { for (i=16;i>0;i=i-1) lpart=$i "." lpart; } END{print lpart;}')
66
fi
67 216

  
68
if [ "x" = "x$GANETI_INSTANCE_NAME" ]; then
69
	exit 1
217
# Exit if we do not have instance name.
218
# It should be exported to hooks for instance related opcodes.
219
if [ -z "$GANETI_INSTNACE_NAME" ]; then
220
  exit 0
70 221
fi
71 222

  
72
if [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_CREATE" ]; then
73
	addremove add $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
74
elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_REMOVE" ]; then
75
	addremove delete $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
76
elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_RENAME" ]; then
77
	addremove delete $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
78
	# Let's override a variable and add ourselves
79
	GANETI_INSTANCE_NAME=$GANETI_INSTANCE_NEW_NAME
80
	addremove add $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
81
elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_STARTUP" ]; then
82
	addremove add $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
83
elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_SHUTDOWN" ]; then
84
	addremove delete $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
85
elif [ "x$GANETI_OP_CODE" = "xOP_INSTANCE_REBOOT" ]; then
86
	addremove delete $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
87
	addremove add $RZONE $R6ZONE $RLPART $R6LPART $eui64 $FZONE
88
fi
223
# This runs only for instance modification
224
reset_dns
225

  
226
# If GANETI_INSTANCE_NIC_COUNT is not set then nothing happens
227
FIRST=0
228
LAST=$((GANETI_INSTANCE_NIC_COUNT - 1))
229
for idx in $(seq $FIRST $LAST); do
230
  ip=GANETI_INSTANCE_NIC${idx}_IP
231
  mac=GANETI_INSTANCE_NIC${idx}_MAC
232
  mode=GANETI_INSTANCE_NIC${idx}_MODE
233
  link=GANETI_INSTANCE_NIC${idx}_LINK
234
  subnet=GANETI_INSTANCE_NIC${idx}_NETWORK_SUBNET
235
  subnet6=GANETI_INSTANCE_NIC${idx}_NETWORK_SUBNET6
236
  tags=GANETI_INSTANCE_NIC${idx}_NETWORK_TAGS
237
  eval IP=\$$ip
238
  eval MAC=\$$mac
239
  eval MODE=\$$mode
240
  eval LINK=\$$link
241
  eval SUBNET=\$$subnet
242
  eval SUBNET6=\$$subnet6
243
  eval TAGS=\$$tags
244

  
245
  for tag in $TAGS; do
246
    case $tag in
247
    $DNS_TAG)
248

  
249
      get_rev4_info "$IP"
250
      get_eui64 "$MAC" "$SUBNET6"
251
      get_rev6_info "$EUI64"
252
      update_dns
253

  
254
      ;;
255
    esac
256

  
257
  done
258

  
259
done
b/fix-net
14 14
  mac=GANETI_INSTANCE_NIC${idx}_MAC
15 15
  mode=GANETI_INSTANCE_NIC${idx}_MODE
16 16
  link=GANETI_INSTANCE_NIC${idx}_LINK
17
  network=GANETI_INSTANCE_NIC${idx}_NETWORK
17
  network=GANETI_INSTANCE_NIC${idx}_NETWORK_SUBNET
18 18
  subnet6=GANETI_INSTANCE_NIC${idx}_NETWORK_SUBNET6
19 19
  tags=GANETI_INSTANCE_NIC${idx}_NETWORK_TAGS
20 20
  eval IP=\$$ip

Also available in: Unified diff