added zoni-cli
Found here: https://svn.apache.org/repos/asf/incubator/tashi/import/zoni-intel-r843/
This commit is contained in:
parent
ec0003bfa8
commit
68b51c7a0a
22 changed files with 3547 additions and 0 deletions
265
ssh/zoni-cli/dhcpdns.py
Normal file
265
ssh/zoni-cli/dhcpdns.py
Normal file
|
@ -0,0 +1,265 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
import time
|
||||
#from instancehook import InstanceHook
|
||||
#from tashi.services.ttypes import Instance, NetworkConfiguration
|
||||
#from tashi import boolean
|
||||
|
||||
|
||||
class DhcpDns():
|
||||
def __init__(self, config, verbose=None):
|
||||
self.verbose = verbose
|
||||
self.dnsKeyFile = config['dnsKeyFile']
|
||||
self.dnsServer = config['dnsServer']
|
||||
self.dnsDomain = config['dnsDomain']
|
||||
self.dnsExpire = int(config['dnsExpire'])
|
||||
self.dhcpServer = config['dhcpServer']
|
||||
self.dhcpKeyName = config['dhcpKeyName']
|
||||
self.dhcpSecretKey = config['dhcpSecretKey']
|
||||
#exit()
|
||||
#items.sort()
|
||||
#self.ipRange = {}
|
||||
#for item in items:
|
||||
#(name, value) = item
|
||||
#name = name.lower()
|
||||
#if (name.startswith('iprange')):
|
||||
#network = name[7:]
|
||||
#try:
|
||||
#network = int(network)
|
||||
#except:
|
||||
#continue
|
||||
#self.ipRange[network] = value
|
||||
self.reverseDns = True
|
||||
#self.log = logging.getLogger(__file__)
|
||||
#self.ipMin = {}
|
||||
#self.ipMax = {}
|
||||
#self.currentIP = {}
|
||||
#self.usedIPs = {}
|
||||
#for k in self.ipRange:
|
||||
#ipRange = self.ipRange[k]
|
||||
#(min, max) = ipRange.split("-")
|
||||
#min = min.strip()
|
||||
#max = max.strip()
|
||||
#ipNum = self.strToIp(min)
|
||||
#self.ipMin[k] = self.strToIp(min)
|
||||
#self.ipMax[k] = self.strToIp(max)
|
||||
#self.currentIP[k] = self.ipMin[k]
|
||||
#instances = self.client.getInstances()
|
||||
#for i in instances:
|
||||
#for nic in i.nics:
|
||||
#try:
|
||||
#ip = nic.ip
|
||||
#ipNum = self.strToIp(ip)
|
||||
#self.log.info('Added %s->%s during reinitialization' % (i.name, ip))
|
||||
#self.usedIPs[ipNum] = ip
|
||||
#except Exception, e:
|
||||
#pass
|
||||
#
|
||||
def strToIp(self, s):
|
||||
ipNum = -1
|
||||
try:
|
||||
ipNum = reduce(lambda x, y: x*256+y, map(int, s.split(".")))
|
||||
except:
|
||||
pass
|
||||
return ipNum
|
||||
|
||||
def ipToStr(self, ip):
|
||||
return "%d.%d.%d.%d" % (ip>>24, (ip>>16)%256, (ip>>8)%256, ip%256)
|
||||
|
||||
def allocateIP(self, nic):
|
||||
network = nic.network
|
||||
allocatedIP = None
|
||||
requestedIP = self.strToIp(nic.ip)
|
||||
if (requestedIP <= self.ipMax[network] and requestedIP >= self.ipMin[network] and (requestedIP not in self.usedIPs)):
|
||||
allocatedIP = requestedIP
|
||||
while (allocatedIP == None):
|
||||
if (self.currentIP[network] > self.ipMax[network]):
|
||||
self.currentIP[network] = self.ipMin[network]
|
||||
elif (self.currentIP[network] in self.usedIPs):
|
||||
self.currentIP[network] = self.currentIP[network] + 1
|
||||
else:
|
||||
allocatedIP = self.currentIP[network]
|
||||
ipString = self.ipToStr(allocatedIP)
|
||||
self.usedIPs[allocatedIP] = ipString
|
||||
return ipString
|
||||
|
||||
def addDhcp(self, name, ipaddr, hwaddr):
|
||||
try:
|
||||
self.removeDhcp(name)
|
||||
self.removeDhcp(name, ipaddr)
|
||||
except:
|
||||
pass
|
||||
cmd = "omshell"
|
||||
(stdin, stdout) = os.popen2(cmd)
|
||||
stdin.write("server %s\n" % (self.dhcpServer))
|
||||
if (self.dhcpSecretKey != ""):
|
||||
stdin.write("key %s %s\n" % (self.dhcpKeyName, self.dhcpSecretKey))
|
||||
stdin.write("connect\n")
|
||||
stdin.write("new \"host\"\n")
|
||||
stdin.write("set name = \"%s\"\n" % (name))
|
||||
stdin.write("set ip-address = %s\n" % (ipaddr))
|
||||
stdin.write("set hardware-address = %s\n" % (hwaddr))
|
||||
stdin.write("set hardware-type = 00:00:00:01\n") # Ethernet
|
||||
stdin.write("create\n")
|
||||
stdin.close()
|
||||
output = stdout.read()
|
||||
print output
|
||||
stdout.close()
|
||||
|
||||
def removeDhcp(self, name, ipaddr=None):
|
||||
cmd = "omshell"
|
||||
(stdin, stdout) = os.popen2(cmd)
|
||||
stdin.write("server %s\n" % (self.dhcpServer))
|
||||
if (self.dhcpSecretKey != ""):
|
||||
stdin.write("key %s %s\n" % (self.dhcpKeyName, self.dhcpSecretKey))
|
||||
stdin.write("connect\n")
|
||||
stdin.write("new \"host\"\n")
|
||||
if (ipaddr == None):
|
||||
stdin.write("set name = \"%s\"\n" % (name))
|
||||
else:
|
||||
stdin.write("set ip-address = %s\n"%(ipaddr))
|
||||
stdin.write("open\n")
|
||||
stdin.write("remove\n")
|
||||
stdin.close()
|
||||
output = stdout.read()
|
||||
print output
|
||||
stdout.close()
|
||||
|
||||
def addDns(self, name, ip):
|
||||
try:
|
||||
self.removeDns(name)
|
||||
except Exception, e:
|
||||
pass
|
||||
#print "Removal of DNS entry failed. Did you use sudo? "
|
||||
#return 1
|
||||
|
||||
if (self.dnsKeyFile != ""):
|
||||
cmd = "nsupdate -k %s" % (self.dnsKeyFile)
|
||||
else:
|
||||
cmd = "nsupdate"
|
||||
child = subprocess.Popen(args=cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
try:
|
||||
(stdin, stdout) = (child.stdin, child.stdout)
|
||||
stdin.write("server %s\n" % (self.dnsServer))
|
||||
stdin.write("update add %s.%s %d A %s\n" % (name, self.dnsDomain, self.dnsExpire, ip))
|
||||
stdin.write("\n")
|
||||
if (self.reverseDns):
|
||||
ipSegments = map(int, ip.split("."))
|
||||
ipSegments.reverse()
|
||||
reverseIpStr = ("%d.%d.%d.%d.in-addr.arpa" % (ipSegments[0], ipSegments[1], ipSegments[2], ipSegments[3]))
|
||||
stdin.write("update add %s %d IN PTR %s.%s.\n" % (reverseIpStr, self.dnsExpire, name, self.dnsDomain))
|
||||
stdin.write("\n")
|
||||
stdin.close()
|
||||
output = stdout.read()
|
||||
stdout.close()
|
||||
finally:
|
||||
os.kill(child.pid, signal.SIGTERM)
|
||||
(pid, status) = os.waitpid(child.pid, os.WNOHANG)
|
||||
while (pid == 0):
|
||||
time.sleep(0.5)
|
||||
os.kill(child.pid, signal.SIGTERM)
|
||||
(pid, status) = os.waitpid(child.pid, os.WNOHANG)
|
||||
|
||||
def removeDns(self, name):
|
||||
if (self.dnsKeyFile != ""):
|
||||
cmd = "nsupdate -k %s" % (self.dnsKeyFile)
|
||||
else:
|
||||
cmd = "nsupdate"
|
||||
child = subprocess.Popen(args=cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
try:
|
||||
(stdin, stdout) = (child.stdin, child.stdout)
|
||||
stdin.write("server %s\n" % (self.dnsServer))
|
||||
if (self.reverseDns):
|
||||
ip = socket.gethostbyname(name)
|
||||
ipSegments = map(int, ip.split("."))
|
||||
ipSegments.reverse()
|
||||
reverseIpStr = ("%d.%d.%d.%d.in-addr.arpa" % (ipSegments[0], ipSegments[1], ipSegments[2], ipSegments[3]))
|
||||
stdin.write("update delete %s IN PTR\n" % (reverseIpStr))
|
||||
stdin.write("\n")
|
||||
stdin.write("update delete %s.%s A\n" % (name, self.dnsDomain))
|
||||
stdin.write("\n")
|
||||
stdin.close()
|
||||
output = stdout.read()
|
||||
stdout.close()
|
||||
finally:
|
||||
os.kill(child.pid, signal.SIGTERM)
|
||||
(pid, status) = os.waitpid(child.pid, os.WNOHANG)
|
||||
while (pid == 0):
|
||||
time.sleep(0.5)
|
||||
os.kill(child.pid, signal.SIGTERM)
|
||||
(pid, status) = os.waitpid(child.pid, os.WNOHANG)
|
||||
|
||||
def doUpdate(self, instance):
|
||||
newInstance = Instance()
|
||||
newInstance.id = instance.id
|
||||
newInstance.nics = instance.nics
|
||||
self.client.vmUpdate(instance.id, newInstance, None)
|
||||
|
||||
def preCreate(self, instance):
|
||||
if (len(instance.nics) < 1):
|
||||
return
|
||||
for i in range(0, len(instance.nics)):
|
||||
nic = instance.nics[i]
|
||||
ip = self.allocateIP(nic)
|
||||
nic.ip = ip
|
||||
try:
|
||||
if (i == 0):
|
||||
self.log.info("Adding %s:{%s->%s} to DNS" % (instance.name, instance.name, ip))
|
||||
self.addDns(instance.name, ip)
|
||||
if (i == 0):
|
||||
dhcpName = instance.name
|
||||
else:
|
||||
dhcpName = instance.name + "-nic%d" % (i)
|
||||
self.log.info("Adding %s:{%s->%s} to DHCP" % (dhcpName, nic.mac, ip))
|
||||
self.addDhcp(dhcpName, ip, nic.mac)
|
||||
except Exception, e:
|
||||
self.log.exception("Failed to add host %s to DHCP/DNS" % (instance.name))
|
||||
self.doUpdate(instance)
|
||||
|
||||
def postDestroy(self, instance):
|
||||
if (len(instance.nics) < 1):
|
||||
return
|
||||
self.log.info("Removing %s from DHCP/DNS" % (instance.name))
|
||||
for i in range(0, len(instance.nics)):
|
||||
nic = instance.nics[i]
|
||||
ip = nic.ip
|
||||
try:
|
||||
ipNum = self.strToIp(ip)
|
||||
del self.usedIPs[ipNum]
|
||||
except Exception, e:
|
||||
self.log.exception("Failed to remove host %s, ip %s from pool of usedIPs" % (instance.name, ip))
|
||||
try:
|
||||
if (i == 0):
|
||||
dhcpName = instance.name
|
||||
else:
|
||||
dhcpName = instance.name + "-nic%d" % (i)
|
||||
self.removeDhcp(dhcpName)
|
||||
except Exception, e:
|
||||
self.log.exception("Failed to remove host %s from DHCP" % (instance.name))
|
||||
try:
|
||||
self.removeDns(instance.name)
|
||||
except Exception, e:
|
||||
self.log.exception("Failed to remove host %s from DNS" % (instance.name))
|
Loading…
Add table
Add a link
Reference in a new issue