added zoni-cli

Found here: https://svn.apache.org/repos/asf/incubator/tashi/import/zoni-intel-r843/
This commit is contained in:
Peter Baumann 2015-02-24 14:31:23 +01:00
parent ec0003bfa8
commit 68b51c7a0a
22 changed files with 3547 additions and 0 deletions

24
ssh/zoni-cli/Makefile Normal file
View file

@ -0,0 +1,24 @@
# 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$
#
clean:
if [ `find . -name "*.pyc" | wc -l` -gt 0 ]; then echo Removing python byte-code...; rm `find . -name "*.pyc"`; fi
@echo Done

View file

@ -0,0 +1,64 @@
# 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$
#
# Logfile
[logging]
LOG_FILE = /tmp/prs_logfile.txt
# DB host
[dbConnection]
DB_HOST = xx_hostname_or_ip_
DB_PORT = 3306
DB_USER = xx_db_username_xx
DB_INST = xx_db_inst_xx
DB_PASSWORD = "xx_db_password_xx"
# TFTP
[tftp]
TFTP_ROOT_DIR = /var/lib/tftpboot
TFTP_IMAGE_DIR = /var/lib/tftpboot/pxelinux.cfg
TFTP_BOOT_OPTIONS_DIR = /var/lib/tftpboot/pxelinux.cfg/boot_options_prs
TFTP_UPDATE_FILE = /var/lib/tftpboot/pxelinux.cfg/update.prs
TFTP_BASE_FILE = /var/lib/tftpboot/pxelinux.cfg/base.prs
TFTP_BASE_MENU_FILE = /var/lib/tftpboot/pxelinux.cfg/base-menu
[snmp]
SNMP_COMMUNITY = xx_snmp_community_name_xx
# Vlan Config
[vlan]
VLAN_RESERVED = {10, {"name", internal}, 999,{"name", "tashi-vm"}, 1000, {"name", "management"}, 1001, {"name", "dmz"}}
VLAN_MAX = 4095
[hardware]
HARDWARE_CONTROL = ["ipmi", "drac", "pdu"]
HARDWARE_PDU = "raritan"
HARDWARE_DRAC = "DELL DRAC"
[DhcpDns]
# Key file must be in the same directory or this will get denied
dnsKeyFile = xx_Kname.+157+36480.private_xx
dnsServer = xx_dns_server_ip_xx xx_port_xx
dnsDomain = xx_fqdn_xx
dnsExpire = 60
dhcpServer = xx_dhcpserver_host_or_ip_xx
dhcpKeyName = xx_dhcpservername_xx
dhcpSecretKey = xx_secretkey_xx

21
ssh/zoni-cli/__init__.py Normal file
View file

@ -0,0 +1,21 @@
# 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.
import os
import sys
from util import *

View file

@ -0,0 +1,38 @@
# 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 sys
import os
import optparse
class BootManagementInterface(object):
""" Interface description for booting
"""
def __init__(self, config):
self.config = config
#def updateDatabase(self, query):
#raise NotImplementedError
def createPxeConfig(self):
''' Create the pxe config file'''
raise NotImplementedError

207
ssh/zoni-cli/delldrac.py Normal file
View file

@ -0,0 +1,207 @@
# 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 sys
import os
import pexpect
import time
from systemmanagementinterface import SystemManagementInterface
#class systemmagement():
#def __init__(self, proto):
#self.proto = proto
def log(f):
def myF(*args, **kw):
print "calling %s%s" % (f.__name__, str(args))
res = f(*args, **kw)
print "returning from %s -> %s" % (f.__name__, str(res))
return res
myF.__name__ = f.__name__
return myF
import time
def timeF(f):
def myF(*args, **kw):
start = time.time()
res = f(*args, **kw)
end = time.time()
print "%s took %f" % (f.__name__, end-start)
return res
myF.__name__ = f.__name__
return myF
class dellDrac(SystemManagementInterface):
def __init__(self, host):
self.hostname = host['location']
self.host = host['drac_name']
self.user = host['drac_userid']
self.password = host['drac_password']
self.port = host['drac_port']
self.powerStatus = None
self.verbose = 0
self.server = "Server-" + str(self.port)
def setVerbose(self, verbose):
self.verbose = verbose
def __login(self):
switchIp = "telnet " + self.host
child = pexpect.spawn(switchIp)
if self.verbose:
child.logfile = sys.stdout
opt = child.expect(['Login:', pexpect.EOF, pexpect.TIMEOUT])
#XXX Doesn't seem to do what I want:(
child.setecho(False)
if opt == 0:
child.sendline(self.user)
time.sleep(.5)
child.sendline(self.password)
time.sleep(.5)
i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
else:
mesg = "Error"
sys.stderr.write(mesg)
exit(1)
return child
@timeF
@log
def getPowerStatus(self):
child = self.__login()
cmd = "getmodinfo -m " + self.server
child.sendline(cmd)
#i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
#exit()
val = child.readline()
val = child.readline()
while self.server not in val:
val = child.readline()
if "ON" in val:
mesg = self.hostname + " Power is on\n\n"
self.powerStatus = 1
if "OFF" in val:
mesg = self.hostname + " Power is off\n\n"
self.powerStatus = 0
sys.stdout.write(mesg)
#while status not in val:
#val = child.readline()
#
#print "val for", status, "is ", val
#i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
#val = child.readlines()
child.close()
child.terminate()
@timeF
def isPowered(self):
if self.powerStatus == None:
self.getPowerStatus()
if self.powerStatus:
return 1;
if not self.powerStatus:
return 0;
@timeF
def powerOn(self):
if self.powerStatus == 1:
mesg = self.hostname + " Power On\n\n"
exit(1)
child = self.__login()
cmd = "racadm serveraction -m " + self.server + " powerup"
child.sendline(cmd)
val = child.readline()
val = child.readline()
if "OK" in val:
mesg = self.hostname + " Power On\n\n"
else:
mesg = self.hostname + " Power On Fail\n\n"
sys.stdout.write(mesg)
#i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
child.terminate()
@timeF
def powerOff(self):
child = self.__login()
cmd = "racadm serveraction -m " + self.server + " powerdown"
child.sendline(cmd)
val = child.readline()
val = child.readline()
if "OK" in val:
mesg = self.hostname + " Power Off\n\n"
else:
mesg = self.hostname + " Power Off Fail\n\n"
sys.stdout.write(mesg)
#i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
child.terminate()
@timeF
def powerCycle(self):
child = self.__login()
cmd = "racadm serveraction -m " + self.server + " powercycle"
child.sendline(cmd)
val = child.readline()
val = child.readline()
if "OK" in val:
mesg = self.hostname + " Power Cycle\n\n"
else:
mesg = self.hostname + " Power Cycle Fail\n\n"
sys.stdout.write(mesg)
#i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
child.terminate()
@timeF
def powerReset(self):
child = self.__login()
cmd = "racadm serveraction -m " + self.server + " hardreset"
child.sendline(cmd)
val = child.readline()
val = child.readline()
if "OK" in val:
mesg = self.hostname + " Power Reset\n\n"
else:
mesg = self.hostname + " Power Reset Fail\n\n"
sys.stdout.write(mesg)
#i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
child.terminate()
def activateConsole(self):
child = self.__login()
cmd = "connect -F " + self.server
child.sendline(cmd)
i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT])
child.terminate()
#ipmitool -I lanplus -E -H r2r1c3b0-ipmi -U root chassis power status

265
ssh/zoni-cli/dhcpdns.py Normal file
View 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))

277
ssh/zoni-cli/hpswitch.py Normal file
View file

@ -0,0 +1,277 @@
# 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$
#
# What HP switches is this for? The configuration syntax does not
# not appear like it would work for Procurves. - stroucki 20100224
import os
import sys
import pexpect
import datetime
import thread
import time
import threading
from hwswitchinterface import HwSwitchInterface
from resourcequerysql import ResourceQuerySql
from util import logit
''' Using pexpect to control switches because couldn't get snmp to work
'''
class HwHPSwitch(HwSwitchInterface):
def __init__(self, config, host=None):
self.host = host
self.verbose = False
self.logFile = config['logFile']
def setVerbose(self, verbose):
self.verbose = verbose
def __login(self):
switchIp = "telnet " + self.host['hw_name']
child = pexpect.spawn(switchIp)
opt = child.expect(['Name:', 'password:', pexpect.EOF, pexpect.TIMEOUT])
#XXX Doesn't seem to do what I want:(
child.setecho(False)
if opt == 0:
child.sendline(self.host['hw_userid'])
# Be Verbose and print everything
if self.verbose:
child.logfile = sys.stdout
child.sendline(self.host['hw_password'])
i=child.expect(['Main#', pexpect.EOF, pexpect.TIMEOUT])
if i == 2:
mesg = "ERROR: Login failed\n"
logit(self.logFile, mesg)
sys.stderr.write()
exit(1)
return child
def __getPrsLabel(self):
dadate = datetime.datetime.now().strftime("%Y%m%d-%H%M-%S")
return "ZONI_" + dadate
def __saveConfig(self, child):
#child.logfile = sys.stdout
cmd = "save"
child.sendline(cmd)
opt = child.expect(["Confirm(.*)", "No save(.*)", pexpect.EOF, pexpect.TIMEOUT])
if opt == 0:
print "saving to flash"
child.sendline("y\n")
if opt == 1:
print "no save needed"
child.sendline('exit')
child.terminate()
def enableHostPort(self):
child = self.__login()
cmd = "/cfg/port " + str(self.host['hw_port']) + " /ena/apply "
child.sendline(cmd)
# testing this thread... Looks like this works ...
threading.Thread(target=self.__saveConfig(child)).start()
def disableHostPort(self):
child = self.__login()
cmd = "/cfg/port " + str(self.host['hw_port']) + " /dis/apply "
child.sendline(cmd)
threading.Thread(target=self.__saveConfig(child)).start()
def removeVlan(self, num):
print "removing vlan"
# Check for important vlans
child = self.__login()
cmd = "/cfg / l2 / vlan " + num + " / del / apply"
child.sendline(cmd)
opt = child.expect(["Confirm(.*)", pexpect.EOF, pexpect.TIMEOUT])
if opt == 0:
child.sendline("y\n")
threading.Thread(target=self.__saveConfig(child)).start()
def addVlanToTrunk(self, vlan):
print "NOT IMPLEMENTED"
print "No trunks to test @ MIMOS"
def createVlansThread(self, vlan, switch,host):
mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch)
print "host is ", host
logit(self.logFile, mesg)
print "create"
self.createVlan(vlan)
print "cend"
self.addVlanToTrunk(vlan);
thread.exit()
def createVlans(self, vlan, switchlist, query):
for switch in switchlist:
#print "working on switch ", switch
#self.host = query.getSwitchInfo(switch)
#thread.start_new_thread(self.createVlansThread, (vlan, switch, self.host))
mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch)
logit(self.logFile, mesg)
self.host = query.getSwitchInfo(switch)
self.createVlan(vlan)
self.addVlanToTrunk(vlan);
def removeVlans(self, vlan, switchlist, query):
for switch in switchlist:
mesg = "Deleting vlan " + str(vlan) + " on switch " + str(switch)
logit(self.logFile, mesg)
self.host = query.getSwitchInfo(switch)
self.removeVlan(vlan)
def createVlan(self, val):
vlanname = False
if ":" in val:
num = int(val.split(":")[0])
vlanname = val.split(":")[1]
else:
vlanname = self.__getPrsLabel()
num = int(val)
#if type(num) != int:
#mesg = "ERROR: Vlan must be a number (0-4095)\n"
#sys.stderr.write(mesg)
#exit(1)
if num > 4095 or num < 0:
mesg = "ERROR: Vlan out of range. Must be < 4095"
logit(self.logFile, mesg)
exit(1)
child = self.__login()
cmd = "/cfg / l2 / vlan " + str(num) + " / ena/ apply"
child.sendline(cmd)
cmd = "name " + str(vlanname) + " / apply"
child.sendline(cmd)
threading.Thread(target=self.__saveConfig(child)).start()
# Raw Switch commands. DEBUG ONLY!, Doesn't work!
def sendSwitchCommand(self, cmds):
if len(cmds) > 0:
child = self.__login()
child.logfile = sys.stdout
for cmd in cmds.split(";"):
child.sendline(cmd)
try:
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
except EOF:
print "EOF", i
#child.sendline()
except TIMEOUT:
print "TIMEOUT", i
#child.interact(escape_character='\x1d', input_filter=None, output_filter=None)
child.terminate()
#print "before", child.before
#print "after", child.after
def addNodeToVlan(self, vlan):
child = self.__login()
cmd = "/cfg/l2/vlan " + str(vlan) + " /add " + str(self.host['hw_port']) + " /apply "
child.sendline(cmd)
opt = child.expect(['(.*)#','(.*)needs to be enabled', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
if opt == 1:
print "VLAN Created, Enabling..." + str(vlan)
cmd = "/cfg/l2/vlan " + str(vlan) + " /ena/apply "
child.sendline(cmd)
threading.Thread(target=self.__saveConfig(child)).start()
def removeNodeFromVlan(self, vlan):
child = self.__login()
cmd = "/cfg/l2/vlan " + str(vlan) + " /rem " + str(self.host['hw_port']) + "/apply"
child.sendline(cmd)
threading.Thread(target=self.__saveConfig(child)).start()
def setNativeVlan(self, vlan):
child = self.__login()
#child.logfile = sys.stdout
cmd = "/cfg/port " + str(self.host['hw_port']) + "/pvid " + str(vlan) + "/apply"
child.sendline(cmd)
threading.Thread(target=self.__saveConfig(child)).start()
# HP switches allow more free control. Example, if you set a port to a native vlan
# that doesn't exist, HP switches will happily create for you.
# However, if you delete a vlan that exists on many ports, it will still happily delete
# the vlan, forcing all the other ports to default to some other native vlan. Need
# to make sure we check before blasting vlans.
# Restore Native Vlan.
def restoreNativeVlan(self):
child = self.__login()
cmd = "/cfg/port " + str(self.host['hw_port']) + "/pvid 1/apply"
child.sendline(cmd)
threading.Thread(target=self.__saveConfig(child)).start()
# Setup the switch for node allocation
def allocateNode(self):
pass
# Remove all vlans from the interface
def removeAllVlans(self):
child = self.__login()
cmd = "/cfg/port " + str(self.host['hw_port']) + "/tag d/apply"
#child.logfile = sys.stdout
child.sendline(cmd)
def showInterfaceConfig(self):
print "\n---------------" + self.host['hw_make'] + "---------------------"
print "SWITCH - " + self.host['hw_name'] + "/" + str(self.host['hw_port'])
print "NODE - " + self.host['location']
print "------------------------------------\n"
# using run and parsing output. Still have issues an "rt" after the command. Fix later
#val = pexpect.run("telnet sw0-r4r1e1", withexitstatus=False, timeout=2, events=({'(?i)password:': "admin\r\n", "Main#": "info\r\n", "Info(.*)" : "port\r\n"})) #, "Info(.*)" : "exit\n"}))
# Just print everything for now, fix when back in the US
#print val
child = self.__login()
cmd = "/info/port " + str(self.host['hw_port'])
child.sendline(cmd)
child.logfile = sys.stdout
opt = child.expect(['Info(.*)', pexpect.EOF, pexpect.TIMEOUT])
# this needs to be removed or rewritten
def interactiveSwitchConfig(self):
switchIp = "telnet " + self.host['hw_name']
child = pexpect.spawn(switchIp)
child.setecho(False)
#child.expect('Name:')
#child.sendline(self.host['hw_userid'])
#i=child.expect(['test','password:','Password:', pexpect.EOF, pexpect.TIMEOUT])
#child.logfile = sys.stdout
child.sendline(self.host['hw_password'])
child.interact(escape_character='\x1d', input_filter=None, output_filter=None)

359
ssh/zoni-cli/hwswitch.py Normal file
View file

@ -0,0 +1,359 @@
# 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 os
import sys
import pexpect
import datetime
import thread
from hwswitchinterface import HwSwitchInterface
from resourcequerysql import ResourceQuerySql
from util import logit
''' Using pexpect to control switches because couldn't get snmp to work
'''
class HwDellSwitch(HwSwitchInterface):
def __init__(self, config, host=None):
self.host = host
self.verbose = False
self.logFile = config['logFile']
def setVerbose(self, verbose):
self.verbose = verbose
def __login(self):
switchIp = "ssh " + self.host['hw_userid'] + "@" + self.host['hw_name']
child = pexpect.spawn(switchIp)
opt = child.expect(['Name:', 'password:', pexpect.EOF, pexpect.TIMEOUT])
print "opt is ", opt
#XXX Doesn't seem to do what I want:(
child.setecho(False)
if opt == 0:
child.sendline(self.host['hw_userid'])
#i=child.expect(['test','password:','Password:', pexpect.EOF, pexpect.TIMEOUT])
# Be Verbose and print everything
if self.verbose:
child.logfile = sys.stdout
child.sendline(self.host['hw_password'])
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT])
if i == 2:
mesg = "ERROR: Login failed\n"
logit(self.logFile, mesg)
sys.stderr.write()
exit(1)
# on the 6448 dell, need to send enable
if opt == 1:
child.sendline('enable')
i=child.expect(['#', pexpect.EOF, pexpect.TIMEOUT])
return child
def __getPrsLabel(self):
dadate = datetime.datetime.now().strftime("%Y%m%d-%H%M-%S")
return "PRS_" + dadate
def enableHostPort(self):
child = self.__login()
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
cmd = "no shutdown"
child.sendline(cmd)
child.sendline('exit')
child.terminate()
def disableHostPort(self):
child = self.__login()
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
cmd = "shutdown"
child.sendline(cmd)
child.sendline('exit')
child.terminate()
def removeVlan(self, num):
# Check for important vlans
cmd = "no vlan " + num
child = self.__login()
child.sendline('config')
child.sendline('vlan database')
child.sendline(cmd)
child.sendline('exit')
child.terminate()
def addVlanToTrunk(self, vlan):
mesg = "Adding Vlan to trunks on switch"
logit(self.logFile, mesg)
child = self.__login()
child.sendline('config')
cmd = "interface range port-channel all"
child.sendline(cmd)
child.expect(["config-if", pexpect.EOF])
cmd = "switchport trunk allowed vlan add " + vlan
child.sendline(cmd)
child.sendline('exit')
def createVlansThread(self, vlan, switch,host):
mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch)
print "host is ", host
logit(self.logFile, mesg)
print "create"
self.createVlan(vlan)
print "cend"
self.addVlanToTrunk(vlan);
thread.exit()
def createVlans(self, vlan, switchlist, query):
for switch in switchlist:
#print "working on switch ", switch
#self.host = query.getSwitchInfo(switch)
#thread.start_new_thread(self.createVlansThread, (vlan, switch, self.host))
mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch)
logit(self.logFile, mesg)
self.host = query.getSwitchInfo(switch)
self.createVlan(vlan)
self.addVlanToTrunk(vlan);
def removeVlans(self, vlan, switchlist, query):
for switch in switchlist:
mesg = "Deleting vlan " + str(vlan) + " on switch " + str(switch)
logit(self.logFile, mesg)
self.host = query.getSwitchInfo(switch)
self.removeVlan(vlan)
def createVlan(self, val):
vlanname = False
if ":" in val:
num = int(val.split(":")[0])
vlanname = val.split(":")[1]
else:
vlanname = self.__getPrsLabel()
num = int(val)
#if type(num) != int:
#mesg = "ERROR: Vlan must be a number (0-4095)\n"
#sys.stderr.write(mesg)
#exit(1)
if num > 4095 or num < 0:
mesg = "ERROR: Vlan out of range. Must be < 4095"
logit(self.logFile, mesg)
exit(1)
child = self.__login()
child.sendline('config')
child.expect(["config",pexpect.EOF, pexpect.TIMEOUT])
child.sendline('vlan database')
child.expect(["config-vlan",pexpect.EOF, pexpect.TIMEOUT])
cmd = "vlan " + str(num)
child.sendline(cmd)
child.sendline('exit')
child.expect(["config",pexpect.EOF, pexpect.TIMEOUT])
if vlanname:
cmd = "interface vlan " + str(num)
child.sendline(cmd)
child.expect(["config-if",pexpect.EOF, pexpect.TIMEOUT])
cmd = "name " + vlanname
child.sendline(cmd)
child.expect(["config-if",pexpect.EOF, pexpect.TIMEOUT])
child.sendline('exit')
child.sendline('exit')
# Raw Switch commands. DEBUG ONLY!, Doesn't work!
def sendSwitchCommand(self, cmds):
if len(cmds) > 0:
child = self.__login()
child.logfile = sys.stdout
for cmd in cmds.split(";"):
child.sendline(cmd)
try:
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
except EOF:
print "EOF", i
#child.sendline()
except TIMEOUT:
print "TIMEOUT", i
#child.interact(escape_character='\x1d', input_filter=None, output_filter=None)
child.terminate()
#print "before", child.before
#print "after", child.after
def addNodeToVlan(self, vlan):
print "Adding Node to vlan ", vlan
child = self.__login()
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
child.expect(["config-if", pexpect.EOF])
cmd = "switchport trunk allowed vlan add " + vlan
child.sendline(cmd)
child.sendline('exit')
NOVLAN = "VLAN was not created by user."
i=child.expect(['config-if',NOVLAN, pexpect.EOF, pexpect.TIMEOUT])
# Vlan must exist in order to add a host to it.
# If it doesn't exist, try to create it
if i == 1:
sys.stderr.write("WARNING: Vlan doesn't exist, trying to create\n")
# Add a tag showing this was created by PRS
newvlan = vlan + ":" + self.__getPrsLabel()
self.createVlan(newvlan)
self.addNodeToVlan(vlan)
child.sendline('exit')
child.sendline('exit')
child.terminate()
sys.stdout.write("Success\n")
def removeNodeFromVlan(self, vlan):
child = self.__login()
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
cmd = "switchport trunk allowed vlan remove " + vlan
child.sendline(cmd)
child.sendline('exit')
child.sendline('exit')
child.terminate()
#def __checkVlan(self, child, vlan):
#NO_VLAN_EXISTS = "VLAN was not created by user."
#i=child.expect(['config',NO_VLAN_EXISTS, pexpect.EOF, pexpect.TIMEOUT])
#print "i is ", i
#if i == 1:
#sys.stderr.write("WARNING: Vlan doesn't exist, trying to create")
#i=child.expect(['config',NO_VLAN_EXISTS, pexpect.EOF, pexpect.TIMEOUT])
#return "NOVLAN"
##newvlan = vlan + ":CREATED_BY_PRS"
##self.createVlan(newvlan)
##self.setNativeVlan(vlan)
def setNativeVlan(self, vlan):
child = self.__login()
child.logfile = sys.stdout
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
i=child.expect(['config-if', pexpect.EOF, pexpect.TIMEOUT])
if i > 0:
sys.stderr.write("ERROR: setNativeVlan ", cmd, " failed\n")
NOVLAN = "VLAN was not created by user."
cmd = "switchport trunk native vlan " + vlan
child.sendline(cmd)
i=child.expect(['config-if', NOVLAN, pexpect.EOF, pexpect.TIMEOUT])
# Vlan must exist in order to add a host to it.
# If it doesn't exist, try to create it
if i == 1:
sys.stderr.write("WARNING: Vlan doesn't exist, trying to create")
# Add a tag showing this was created by PRS
newvlan = vlan + ":" + self.__getPrsLabel()
self.createVlan(newvlan)
self.setNativeVlan(vlan)
child.sendline('exit')
child.sendline('exit')
child.terminate()
# Restore Native Vlan. In Dell's case, this is vlan 1
def restoreNativeVlan(self):
child = self.__login()
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
cmd = "switchport trunk native vlan 1"
child.sendline(cmd)
child.sendline('exit')
child.sendline('exit')
#child.terminate()
child.terminate()
# Setup the switch for node allocation
def allocateNode(self):
pass
# Remove all vlans from the interface
def removeAllVlans(self):
child = self.__login()
child.logfile = sys.stdout
child.sendline('config')
cmd = "interface ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
i=child.expect(['config-if', pexpect.EOF, pexpect.TIMEOUT])
if i > 0:
sys.stderr.write("ERROR: setNativeVlan ", cmd, " failed\n")
NOVLAN = "VLAN was not created by user."
cmd = "switchport trunk allowed vlan remove all"
child.sendline(cmd)
i=child.expect(['config-if', NOVLAN, pexpect.EOF, pexpect.TIMEOUT])
# Vlan must exist in order to add a host to it.
# If it doesn't exist, try to create it
if i == 1:
pass
child.sendline('exit')
child.sendline('exit')
child.terminate()
def showInterfaceConfig(self):
child = self.__login()
print "\n------------------------------------"
print "SWITCH - " + self.host['hw_name'] + "/" + str(self.host['hw_port'])
print "NODE - " + self.host['location']
print "------------------------------------\n"
child.logfile = sys.stdout
cmd = "show interface switchport ethernet g" + str(self.host['hw_port'])
child.sendline(cmd)
i = child.expect(['sw(.*)', pexpect.EOF, pexpect.TIMEOUT])
i = child.expect(['sw(.*)', pexpect.EOF, pexpect.TIMEOUT])
child.terminate()
def interactiveSwitchConfig(self):
switchIp = "ssh " + self.host['hw_name']
child = pexpect.spawn(switchIp)
child.setecho(False)
#child.expect('Name:')
child.sendline(self.host['hw_userid'])
#i=child.expect(['test','password:','Password:', pexpect.EOF, pexpect.TIMEOUT])
#child.logfile = sys.stdout
child.sendline(self.host['hw_password'])
child.interact(escape_character='\x1d', input_filter=None, output_filter=None)

View file

@ -0,0 +1,65 @@
# 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 sys
import os
class HwSwitchInterface(object):
""" Interface description for hardware switches
- Dell
"""
def __init__(self, configFile, hostInst = None):
'''
hostInst is all data that makes up a host
hw_port - port number node is connected to
hw_userid - userid node uses to configure switch
hw_password - userid node uses to configure switch
hw_name - switch name node is connected to
'''
#self.host = hostInst
def enablePort(self):
raise NotImplementedError
def disablePort(self):
raise NotImplementedError
def removeVlan(self, vlan):
raise NotImplementedError
def createVlan(self, vlan):
raise NotImplementedError
def addNode2Vlan(self, vlan):
raise NotImplementedError
def removeNodeFromVlan(self, vlan):
raise NotImplementedError
def addNativeVlan(self, vlan):
raise NotImplementedError
def restoreNativeVlan(self):
raise NotImplementedError
def isolateNetwork(self):
raise NotImplementedError

58
ssh/zoni-cli/infostore.py Normal file
View file

@ -0,0 +1,58 @@
# 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 sys
import os
import optparse
class InfoStore (object):
""" Interface description for query system resources
"""
def __init__(self, config):
self.config = config
#def updateDatabase(self, query):
#raise NotImplementedError
def printAll(self):
raise NotImplementedError
def showResources(self, cmdargs):
raise NotImplementedError
def printResources(self):
raise NotImplementedError
def showAllocation(self):
raise NotImplementedError
def showPxeImages(self):
raise NotImplementedError
def showPxeImagesToSystemMap(self):
raise NotImplementedError
def getHwAccessMethod(self):
''' Get hardware access method and return a list
'''
raise NotImplementedError

105
ssh/zoni-cli/ipmi.py Normal file
View file

@ -0,0 +1,105 @@
# 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 sys
import os
from systemmanagementinterface import SystemManagementInterface
#class systemmagement():
#def __init__(self, proto):
#self.proto = proto
class Ipmi(SystemManagementInterface):
def __init__(self, host, user, password):
self.host = host + "-ipmi"
self.password = password
self.user = user
self.powerStatus = None
self.verbose = False
self.ipmicmd = "ipmitool -I lanplus -U" + self.user + " -H" + self.host + \
" -P " + self.password + " "
def setVerbose(self, verbose):
self.verbose = verbose
def getPowerStatus(self):
if self.verbose:
print self.ipmicmd
cmd = self.ipmicmd + "chassis power status"
a = os.popen(cmd)
output = a.read()
print "%s\n%s" % (self.host, output)
if "off" in output:
self.powerStatus = 0
if "on" in output:
self.powerStatus = 1
if "Unable" in output:
print "unable to get the status"
self.powerStatus = 0
return output
#return a.read()
#for line in a.readlines():
#print line
def isPowered(self):
if self.powerStatus == None:
self.getPowerStatus()
if self.powerStatus:
return 1;
if not self.powerStatus:
return 0;
def powerOn(self):
cmd = self.ipmicmd + "chassis power on"
a = os.popen(cmd)
output = a.read()
print "output is ", output
def powerOff(self):
cmd = self.ipmicmd + "chassis power off"
a = os.popen(cmd)
output = a.read()
print "output is ", output
def powerCycle(self):
cmd = self.ipmicmd + "chassis power cycle"
a = os.popen(cmd)
output = a.read()
print "output is ", output
def powerReset(self):
cmd = self.ipmicmd + "chassis power reset"
a = os.popen(cmd)
output = a.read()
print "output is ", output
def activateConsole(self):
cmd = self.ipmicmd + "sol activate"
a = os.popen(cmd)
output = a.read()
print "output is ", output
#ipmitool -I lanplus -E -H r2r1c3b0-ipmi -U root chassis power status

View file

@ -0,0 +1,39 @@
# 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 sys
import os
class PhyAssignInterface(object):
""" Interface description for query system resources
"""
def __init__(self, config):
self.config = config
def assignImage(self):
raise NotImplementedError
def reservePhy(self):
raise NotImplementedError
def uploadImage(self):
raise NotImplementedError

100
ssh/zoni-cli/pxe.py Normal file
View file

@ -0,0 +1,100 @@
# 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 os
import sys
import string
import datetime
import subprocess
import MySQLdb
import traceback
from util import logit
from bootmanagementinterface import BootManagementInterface
class Pxe(BootManagementInterface):
def __init__(self, config, verbose=None):
self.verbose = verbose
self.host = config['dbHost']
self.user = config['dbUser']
self.passwd = config['dbPassword']
self.db = config['dbInst']
self.tftpRootDir = config['tftpRootDir']
self.tftpImageDir = config['tftpImageDir']
self.tftpBootOptionsDir = config['tftpBootOptionsDir']
self.tftpUpdateFile = config['tftpUpdateFile']
self.tftpBaseFile = config['tftpBaseFile']
self.tftpBaseMenuFile = config['tftpBaseMenuFile']
self.logFile = config['logFile']
if config['dbPort'] == "":
config['dbPort'] = 3306
self.port = config['dbPort']
self.vlan_max = config['vlan_max']
self.vlan_reserved = config['vlan_reserved']
# Connect to DB
self.conn = MySQLdb.connect(host = self.host, port = self.port, user = self.user, passwd = self.passwd, db = self.db)
#cursor.execute ("SELECT VERSION()")
#print "server version:", row[0]
#mysql -Dirp-cluster -hrodimus -u reader -e "select * from hostinfo;"
''' This will create the update file tftpUpdateFile used to generate all the pxe boot files
pass in a list of available images
'''
def createPxeUpdateFile (self, images):
try:
f = open(self.tftpUpdateFile, "w")
except Exception:
traceback.print_exc(sys.exc_info())
dadate = datetime.datetime.now().strftime("%Y%m%d.%H%M.%S")
val = "# Generated by PRS : " + dadate
f.write(val)
for image in images:
val = "\n# IMAGE " + image + "\n"
f.write(val)
base = "cat " + self.tftpBaseFile + " | sed 's/MAGIC1/" + image + "/' > " + self.tftpBootOptionsDir + "/" + image + "\n"
basemenu= "cat " + self.tftpBaseMenuFile + " | sed 's/LABEL " + image + "/LABEL " + image + "\\n\\tMENU DEFAULT/' > " + self.tftpBootOptionsDir + "/" + image + "-menu\n"
f.write(base)
f.write(basemenu)
f.close()
def updatePxe(self):
cmd = "chmod 755 " + self.tftpUpdateFile
try:
os.system(cmd)
except Exception:
traceback.print_exc(sys.exc_info())
cmd = self.tftpUpdateFile
try:
os.system(cmd)
except Exception:
traceback.print_exc(sys.exc_info())

121
ssh/zoni-cli/raritanpdu.py Normal file
View file

@ -0,0 +1,121 @@
# 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 sys
import os
from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.proto import rfc1902
#import netsnmp
from systemmanagementinterface import SystemManagementInterface
#class systemmagement():
#def __init__(self, proto):
#self.proto = proto
class raritanDominionPx(SystemManagementInterface):
def __init__(self, host):
self.host = host['location']
self.pdu_name = host['pdu_name']
self.port = host['pdu_port']
self.user = host['pdu_userid']
self.password = host['pdu_password']
self.oid = "1,3,6,1,4,1,13742,4,1,2,2,1"
self.oid_name = ",2"
self.oid_set = ",3"
self.oid_status = ",3"
# this works
#errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData('my-agent', 'public', 0), cmdgen.UdpTransportTarget(('pdu0-r1r1', 161)), (1,3,6,1,4,1,13742,4,1,2,2,1,3,2))
#print varBinds
#oid = netsnmp.Varbind('sysDescr')
#result = netsnmp.snmpwalk(oid, Version = 2,DestHost="localhost",Community="public")
#print result
#var = netsnmp.Varbind('sysDescr.0')
#res = netsnmp.snmpget(var, ...:Version=1,...:DestHost = 'pdu0-r1r1',...: Community = 'prs-domain')
#print res
#print cmdgen
#set snmp = /usr/bin/snmpset -v 2c -c intel pdu .1.3.6.1.4.1.13742.4.1.2.2.1.3.$outletnumber i $state
#name snmp = /usr/bin/snmpset -v 2c -c intel pdu .1.3.6.1.4.1.13742.4.1.2.2.1.2.$outletnumber i $state
#status snmp = /usr/bin/snmpset -v 2c -c intel pdu .1.3.6.1.4.1.13742.4.1.2.2.1.1.$outletnumber i $state
#self.snmp_status_oid = ".1.3.6.1.4.1.13742.4.1.2.2.1.1."
#self.powerStatus = None
#print self.__dict__
def getPowerStatus(self):
thisoid = eval(str(self.oid) + str(self.oid_status) + "," + str(self.port))
errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd( \
cmdgen.CommunityData('my-agent', self.user, 0), \
cmdgen.UdpTransportTarget((self.pdu_name, 161)), thisoid)
output = varBinds[0][1]
if output == 1:
self.powerStatus = 1
powerstat = "on"
if output == 0:
self.powerStatus = 0
powerstat = "off"
print "PDU Power for %s is %s" % (self.host, powerstat)
if output:
return 1
return 0
def isPowered(self):
if self.powerStatus == None:
self.getPowerStatus()
if self.powerStatus:
return 1;
if not self.powerStatus:
return 0;
def powerOn(self):
thisoid = eval(str(self.oid) + str(self.oid_status) + "," + str(self.port))
errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().setCmd( \
cmdgen.CommunityData('my-agent', self.user, 1), \
cmdgen.UdpTransportTarget((self.pdu_name, 161)), \
(thisoid, rfc1902.Integer('1')))
self.getPowerStatus()
def powerOff(self):
thisoid = eval(str(self.oid) + str(self.oid_status) + "," + str(self.port))
errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().setCmd( \
cmdgen.CommunityData('my-agent', self.user, 1), \
cmdgen.UdpTransportTarget((self.pdu_name, 161)), \
(thisoid, rfc1902.Integer('0')))
self.getPowerStatus()
def powerCycle(self):
self.powerOff()
self.powerOn()
def powerReset(self):
self.powerCycle()

View file

@ -0,0 +1,961 @@
# 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 os
import sys
import string
import MySQLdb
import subprocess
import traceback
import usermanagement
from infostore import InfoStore
from util import logit
from dhcpdns import DhcpDns
def timeF(f):
def myF(*args, **kw):
start = time.time()
res = f(*args, **kw)
end = time.time()
print "%s took %f" % (f.__name__, end-start)
return res
myF.__name__ = f.__name__
return myF
def checkSuper(f):
def myF(*args, **kw):
if os.getuid() != 0:
print "Please use sudo!"
exit()
res = f(*args, **kw)
return res
return myF
class ResourceQuerySql(InfoStore):
def __init__(self, config, verbose=None):
self.config = config
self.verbose = verbose
self.host = config['dbHost']
self.user = config['dbUser']
self.passwd = config['dbPassword']
self.db = config['dbInst']
self.tftpRootDir = config['tftpRootDir']
self.tftpImageDir = config['tftpImageDir']
self.tftpBootOptionsDir = config['tftpBootOptionsDir']
self.logFile = config['logFile']
if config['dbPort'] == "":
config['dbPort'] = 3306
self.port = config['dbPort']
self.vlan_max = config['vlan_max']
self.vlan_reserved = config['vlan_reserved']
# Connect to DB
try:
self.conn = MySQLdb.connect(host = self.host, port = self.port, user = self.user, passwd = self.passwd, db = self.db)
except MySQLdb.OperationalError, e:
if e[0] == 2005:
print "ZONI ERROR:" + str(e[1])
exit(1)
#traceback.print_exc(sys.exc_info())
#cursor.execute ("SELECT VERSION()")
#print "server version:", row[0]
#mysql -Dirp-cluster -hrodimus -u reader -e "select * from hostinfo;"
#def gethost(self, host):
#obj = {}
#self.conn
#createConn()
#
def __create_queryopts(self, cmdargs, extra=None):
cmdlen = len(cmdargs)
queryopt = ""
if extra:
queryopt += extra
if cmdlen == 0:
pass
else:
num = cmdlen
if extra:
queryopt += " and "
for k, v in cmdargs.iteritems():
if k == "num_procs":
queryopt += k + " = " + v + " "
if k == "mem_total":
queryopt += k + " >= " + v + " "
if k == "clock_speed":
queryopt += k + " >= " + v + " "
if k == "num_cores":
queryopt += k + " = " + v + " "
if k == "cpu_flags":
queryopt += k + " like \"%" + v + "%\" "
if k == "node_id":
queryopt += " location = " + "\'" + v + "\' "
if num > 1:
queryopt += " and "
num -= 1
if queryopt:
tmp = " where " + queryopt
queryopt = tmp
return queryopt
def updateDatabase(self, table, query):
pass
def showResources(self, cmdargs):
queryopt = ""
defaultFields = "mac_addr, location, num_procs, num_cores, clock_speed, mem_total "
#defaultFields = "*"
queryopt = self.__create_queryopts(cmdargs)
#query = "show fields from sysinfo"
#results = self.__selectDb(query)
query = "select " + defaultFields + "from sysinfo " + queryopt
result = self.__selectDb(query)
line = ""
for i in defaultFields.split(","):
#line += string.strip(str(i)) + "\t"
line += str(i.center(20))
print line
for row in result.fetchall():
line = ""
for val in row:
line += str(val).center(20)
print line
print str(result.rowcount) + " systems returned"
#mysql -h rodimus -u reader irp-cluster -e "select * from sysinfo where location like 'r1%' and num_procs = 1"
def getLocationFromSysId (self, nodeId):
query = "select location from sysinfo where sys_id = \"" + str(nodeId) + "\""
result = self.__selectDb(query)
return result.fetchall()[0][0]
def getMacFromSysId(self, nodeId):
query = "select mac_addr from sysinfo where sys_id = \"" + str(nodeId) + "\""
result = self.__selectDb(query)
return result.fetchall()[0][0]
def getIpFromSysId(self, nodeId):
query = "select ip_addr from sysinfo where sys_id = \"" + str(nodeId) + "\""
result = self.__selectDb(query)
return result.fetchall()[0][0]
def getAllSwitches(self):
switchList = []
query = "select hw_name from hardwareinfo where hw_type = \"switch\""
result = self.__selectDb(query)
for switch in result.fetchall():
switchList.append(switch[0])
# Use static list until we get all switches installed
switchList = ['sw1-r1r2', 'sw0-r1r1', 'sw0-r1r2', 'sw0-r1r3', 'sw0-r1r4', 'sw0-r2r3', 'sw0-r3r3', 'sw0-r3r2', 'sw0-r2r1c3', 'sw2-r1r2']
#switchList = ['sw2-r1r2']
#switchList = ['sw1-r1r2']
print switchList
return switchList
def getAvailableVlan(self):
# Get list of available vlans
query = "select vlan_num from vlaninfo where domain = 'private'"
result = self.__selectDb(query)
for vlan in result.fetchall()[0]:
avail = self.isVlanAvailable(vlan)
if avail:
myvlan = vlan
break
if not myvlan:
mesg = "No Vlans for you! You Go Now\n"
logit(self.logFile, mesg)
return myvlan
def isVlanAvailable(self, vlan):
query = "select a.vlan_id, v.vlan_num from allocationinfo a, vlaninfo v where a.vlan_id = v.vlan_id and v.vlan_num = " + str(vlan)
result = self.__selectDb(query)
if result.rowcount > 1:
return 0
else:
return 1
def getVlanId(self, vlan):
query = "select vlan_id from vlaninfo where vlan_num = \"" + str(vlan) + "\""
result = self.__selectDb(query)
#print result.rowcount
if result.rowcount > 0:
return result.fetchall()[0][0]
else:
mesg = "ERROR: VLAN does not exist: " + str(vlan)
logit(self.logFile, mesg)
exit()
def isIpAvailable(self, ip_addr, vlan_id):
query = "select * from allocationinfo where ip_addr = \"" + str(ip_addr) + "\" and vlan_id = \"" + str(vlan_id) + "\""
#print "query ", query
result = self.__selectDb(query)
#print "select row count is ", result.rowcount
if result.rowcount > 0:
return 0
else:
return 1
def getDomainIp(self, vlan):
ip_start = 30
query = "select ip_network from vlaninfo where vlan_num = " + str(vlan)
result = self.__selectDb(query)
ip_network = result.fetchall()[0][0]
v = ip_network.split(".")
ip_base = v[0] + "." + v[1] + "." + v[2]
# Check for other allocations and assign IP address
query = "select a.vlan_id, v.vlan_num from allocationinfo a, vlaninfo v where a.vlan_id = v.vlan_id and v.vlan_num = " + str(vlan)
#print "ip is ", ip_network
query = "select a.ip_addr from allocationinfo a, vlaninfo v where a.vlan_id = v.vlan_id and v.vlan_num = " + str(vlan);
result = self.__selectDb(query)
#print "row count is ", result.rowcount
if result.rowcount > 0:
for ip in xrange(ip_start, 255):
ip_check = ip_base + "." + str(ip)
check = self.isIpAvailable(ip_check, self.getVlanId(vlan))
if check:
ip_addr = ip_check
break
else:
ip_addr = ip_base + "." + str(ip_start)
#print "ip_addr", ip_addr
return ip_addr
def showArchive(self):
query = "select * from allocationarchive"
result = self.__selectDb(query)
for i in result:
print i
def showAllocation(self, userId=None):
#from IPython.Shell import IPShellEmbed
#shell = IPShellEmbed(argv="")
#shell(local_ns=locals(), global_ns=globals())
# specify usermanagement - ldap or files
usermgt = usermanagement.ldap()
query = "select r.user_id, s.location, s.num_cores, s.mem_total, \
r.reservation_expiration, r.notes, r.reservation_id, v.vlan_num, a.ip_addr, a.hostname,\
a.notes, i.image_name \
from allocationinfo a, sysinfo s, reservationinfo r, vlaninfo v, imageinfo i, imagemap m where \
s.mac_addr = m.mac_addr and \
m.image_id = i.image_id and \
s.sys_id = a.node_id and \
v.vlan_id = a.vlan_id and \
r.reservation_id = a.reservation_id "
if userId:
myid = userId
if type(userId) == str:
# convert username to id
myid = usermgt.getUserId(userId)
query += " and user_id = " + myid + " "
query += "order by r.reservation_id asc, s.location"
result = self.__selectDb(query)
print "NODE ALLOCATION"
print "---------------------------------------------------------------------------------"
if self.verbose:
#print "Res_id\tUser \tNode \tCores\tMemory \tExpiration\t\tVLAN\tHOSTNAME \tIPADDR \t\tReservationNotes|AllocationNotes"
print "%-5s%-10s%-10s%-12s%-12s%-5s%-15s%-18s%-24s%s" % ("Res", "User", "Host", "Cores/Mem","Expiration", "Vlan", "Hostname", "IP Addr", "Boot Image Name", "Notes")
else:
print "%-10s%-10s%-12s%-12s%s" % ("User", "Node", "Cores/Mem","Expiration", "Notes")
for i in result.fetchall():
uid = i[0]
host = i[1]
cores = i[2]
memory = i[3]
expire = str(i[4])[0:10]
if expire == "None":
expire = "0000-00-00"
rnotes = i[5]
resId= i[6]
vlanId= i[7]
ip_addr = i[8]
hostname = i[9]
anotes = i[10]
image_name = i[11]
userName = usermgt.getUserName(uid)
combined_notes = str(rnotes) + "|" + str(anotes)
if self.verbose:
#print "%s\t%s \t%s \t%s\t%s \t%s\t%s\t%s \t%s \t%s" % (resId, userName, host, cores, memory,expire, vlanId, hostname, ip_addr, combined_notes)
print "%-5s%-10s%-10s%-2s%-10s%-12s%-5s%-15s%-18s%-24s%s" % (resId, userName, host, cores, memory,expire, vlanId, hostname, ip_addr, image_name, combined_notes)
else:
print "%-10s%-10s%-2s%-10s%-12s%s" % (userName, host, cores, memory,expire, combined_notes)
print "---------------------------------------------------------------------------------"
print str(result.rowcount) + " systems returned"
def showReservation(self, userId=None):
#from IPython.Shell import IPShellEmbed
#shell = IPShellEmbed(argv="")
#shell(local_ns=locals(), global_ns=globals())
# specify usermanagement - ldap or files
usermgt = usermanagement.ldap()
query = "select reservation_id, user_id, \
reservation_expiration, notes \
from reservationinfo order by reservation_id"
if self.verbose:
query = "select r.reservation_id, r.user_id, r.reservation_expiration, r.notes, count(a.reservation_id) \
from reservationinfo r, allocationinfo a \
where r.reservation_id = a.reservation_id \
group by r.reservation_id order by reservation_id"
#if userId:
#myid = userId
#if type(userId) == str:
## convert username to id
#myid = usermgt.getUserId(userId)
#query += " and user_id = " + myid + " "
#query += "order by r.user_id, s.location"
result = self.__selectDb(query)
print "RESERVATIONS"
print "---------------------------------------------------------------------------------"
if self.verbose:
print "%-7s%-10s%-12s%-7s%s" % ("ResId", "UserName", "Expire", "Total", "Notes")
else:
print "%-7s%-10s%-12s%s" % ("ResId", "UserName", "Expire", "Notes")
total = 0
for i in result.fetchall():
resId= i[0]
uid = i[1]
expire = str(i[2])[0:10]
if expire == "None":
expire = "0000-00-00"
notes = i[3]
userName = usermgt.getUserName(uid)
if self.verbose:
num_nodes = i[4]
total += num_nodes
#print "%s \t%s \t%s\t%s\t\t%s " % (resId, userName, expire, num_nodes, notes)
print "%-7s%-10s%-12s%-7s%s" % (resId, userName, expire, num_nodes, notes)
else:
print "%-7s%-10s%-12s%s" % (resId, userName, expire, notes)
if self.verbose:
print "---------------------------------------------------------------------------------"
print "Total number of nodes - %s" % (total)
def getPxeImages(self):
cursor = self.conn.cursor ()
line = "select image_name from imageinfo"
cursor.execute (line)
row = cursor.fetchall()
desc = cursor.description
imagelist = []
for i in row:
imagelist.append(i[0])
return imagelist
def showPxeImages(self):
cursor = self.conn.cursor ()
line = "select image_name, dist, dist_ver from imageinfo"
cursor.execute (line)
row = cursor.fetchall()
desc = cursor.description
for i in row:
print i
cursor.close ()
def showPxeImagesToSystemMap(self, cmdargs):
extra = "l.mac_addr = j.mac_addr and j.image_id = i.image_id"
queryopt = self.__create_queryopts(cmdargs, extra=extra)
print queryopt
query = "select l.location, j.mac_addr, i.image_name from sysinfo l , imageinfo i, imagemap j " + queryopt + " order by l.location"
#print query
result = self.__selectDb(query)
for i in result.fetchall():
print i
def close(self):
self.conn.close()
def getHwAccessMethod(self):
pass
mylist = []
return mylist
def getHostInfo(self, node):
host = {}
query = "select * from sysinfo where location = \"" + node + "\""
#print "query is ", query
result = self.__selectDb(query)
if result.rowcount > 1:
print "Mulitple entries for system exist. Please correct"
exit()
if result.rowcount < 1:
mesg = "node does not exist :" + str(node) + "\n"
sys.stderr.write(mesg)
exit()
for i in result.fetchall():
host['mac_addr'] = host.get("mac_addr", "")
host['node_id'] = int(i[0])
host['mac_addr'] = i[1]
host['num_procs'] = int(i[2])
host['num_cores'] = int(i[3])
host['mem_total'] = int(i[6])
host['clock_speed'] = int(i[8])
host['sys_vendor'] = i[9]
host['sys_model'] = i[10]
host['proc_vendor'] = i[11]
host['proc_model'] = i[12]
host['proc_cache'] = i[13]
host['cpu_flags'] = i[15]
host['bios_rev'] = i[17]
host['location'] = i[16]
host['dell_tag'] = host.get("dell_tag", "")
host['dell_tag'] = i[14]
'''
for k, v in host.iteritems():
print k, v, "\n"
'''
# Get IPMI info
query = "select * from ipmiinfo where node_id = " + str(host['node_id']) + ""
result = self.__selectDb(query)
if result.rowcount> 1:
print "Mulitple entries for system exist. Please correct"
exit()
for i in result.fetchall():
host['ipmi_user'] = i[2]
host['ipmi_password'] = i[3]
host['ipmi_addr'] = i[1]
# Get image info
query = "select image_name from imagemap i, imageinfo j where i.image_id = j.image_id and mac_addr = \"" + host['mac_addr'] + "\""
result = self.__selectDb(query)
if result.rowcount == 0:
host['pxe_image_name'] = "None"
else:
for i in result.fetchall():
host['pxe_image_name'] = i[0]
# Get switch info
query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password, p.port_num from hardwareinfo h, portmap p where p.hw_id = h.hw_id and hw_type = 'switch' and node_id = " + str(host['node_id'])
result = self.__selectDb(query)
for i in result.fetchall():
host['hw_id'] = int(i[0])
host['hw_name'] = i[1]
host['hw_model'] = i[2]
host['hw_ipaddr'] = i[3]
host['hw_userid'] = i[4]
host['hw_password'] = i[5]
host['hw_port'] = int(i[6])
# Get drac info
query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password, p.port_num from hardwareinfo h, portmap p where p.hw_id = h.hw_id and hw_type = 'drac' and node_id = " + str(host['node_id'])
result = self.__selectDb(query)
if result.rowcount > 0:
for i in result.fetchall():
host['drac_id'] = int(i[0])
host['drac_name'] = i[1]
host['drac_model'] = i[2]
host['drac_ipaddr'] = i[3]
host['drac_userid'] = i[4]
host['drac_password'] = i[5]
host['drac_port'] = int(i[6])
# Get PDU info
query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password, p.port_num from hardwareinfo h, portmap p where p.hw_id = h.hw_id and hw_type = 'pdu' and node_id = " + str(host['node_id'])
result = self.__selectDb(query)
for i in result.fetchall():
host['pdu_id'] = int(i[0])
host['pdu_name'] = i[1]
host['pdu_model'] = i[2]
host['pdu_ipaddr'] = i[3]
host['pdu_userid'] = i[4]
host['pdu_password'] = i[5]
host['pdu_port'] = int(i[6])
#print "host is ", host
return host
def getSwitchInfo(self, switchName):
host = {}
# Get switch info
#switchList = self.getAllSwitches()
query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password from hardwareinfo h where h.hw_name = \"" + str(switchName) + "\""
#print "query is ", query
result = self.__selectDb(query)
#desc = cursor.description
for i in result.fetchall():
host['hw_id'] = int(i[0])
host['hw_name'] = i[1]
host['hw_model'] = i[2]
host['hw_ipaddr'] = i[3]
host['hw_userid'] = i[4]
host['hw_password'] = i[5]
return host
def __queryDb(self, query):
cursor = self.conn.cursor()
cursor.execute (query)
row = cursor.fetchall()
desc = cursor.description
return row
def execQuery(self, query):
cursor = self.conn.cursor()
try:
cursor.execute (query)
#except Exception:
#traceback.print_exc(sys.exc_info())
except MySQLdb.OperationalError, e:
msg = "ERROR: " + e[1]
sys.stderr.write(msg)
logit(self.logFile, msg)
#traceback.print_exc(sys.exc_info())
exit()
return cursor
def __selectDb(self, query):
cursor = self.conn.cursor()
try:
cursor.execute (query)
#except Exception:
#traceback.print_exc(sys.exc_info())
except MySQLdb.OperationalError, e:
msg = "ERROR: " + e[1]
sys.stderr.write(msg)
logit(self.logFile, msg)
#traceback.print_exc(sys.exc_info())
exit()
return cursor
def __updateDb(self, query):
cursor = self.conn.cursor()
try:
cursor.execute (query)
except MySQLdb.OperationalError, e:
msg = "ERROR: " + e[1]
sys.stderr.write(msg)
logit(self.logFile, msg)
#traceback.print_exc(sys.exc_info())
exit()
def __insertDb(self, query):
cursor = self.conn.cursor()
try:
cursor.execute (query)
#except Exception:
#traceback.print_exc(sys.exc_info())
except MySQLdb.OperationalError, e:
msg = "ERROR: " + e[1]
sys.stderr.write(msg)
logit(self.logFile, msg)
#traceback.print_exc(sys.exc_info())
exit()
def updateReservation (self, reservationId, userId=None, reservationDuration=None, vlanIsolate=None, allocationNotes=None):
mesg = "Updating reservation"
logit(self.logFile, mesg)
if reservationDuration:
if len(resDuration) == 8:
expireDate = resDuration
elif len(resDuration) < 4:
numdays = resDuration
cmd = "date +%Y%m%d --date=\"" + numdays + " day\""
p = os.popen(cmd)
expireDate = string.strip(p.read())
else:
mesg = "ERROR: Invalid reservation duration\n"
sys.stderr.write(mesg)
logit(self.logFile, mesg)
exit()
mesg = "Updating reservationDuration :" + resDuration
logit(self.logFile, mesg)
query = "update reservationinfo set reservation_exiration = \"" + expireDate_ + "\" where reservation_id = \"" + str(reservationId) + "\""
self.__updateDb(query)
if allocationNotes:
mesg = "Updating allocationNotes to " + allocationNotes
logit(self.logFile, mesg)
query = "update reservationinfo set notes = \"" + allocationNotes + "\" where reservation_id = \"" + str(reservationId) + "\""
self.__updateDb(query)
if vlanIsolate:
mesg = "UPDATING Vlan: "
logit(self.logFile, mesg)
query = "update reservationinfo set vlan_num = " + vlanIsolate + " where reservation_id = \"" + str(reservationId) + "\""
print "query is ", query
self.__updateDb(query)
if userId:
mesg = "UPDATING USER:"
logit(self.logFile, mesg)
query = "update reservationinfo set user_id = " + userId + " where reservation_id = \"" + str(reservationId) + "\""
self.__updateDb(query)
def addReservation (self, userId, reservationDuration=None, reservationNotes=None):
# set default for reservation duration to 15 days
if not reservationDuration:
resDuration = str(15)
else:
resDuration = str(reservationDuration)
if len(resDuration) == 8:
expireDate = resDuration
elif len(resDuration) < 4:
numdays = resDuration
cmd = "date +%Y%m%d --date=\"" + numdays + " day\""
p = os.popen(cmd)
expireDate = string.strip(p.read())
else:
mesg = "ERROR: Invalid reservation duration\n"
sys.stderr.write(mesg)
logit(self.logFile, mesg)
exit()
# create reservation
# Create the reservation
print userId, expireDate,reservationNotes
query = "insert into reservationinfo (user_id, reservation_expiration, notes) values (\"" + str(userId) + "\", " + str(expireDate) + ", \"" + reservationNotes + "\")"
mesg = "Creating new reservation\n" + query
logit(self.logFile, mesg)
self.__selectDb(query)
# Get the res_id
query = "select max(reservation_id) from reservationinfo"
res_id = self.__selectDb(query).fetchone()[0]
mesg = " Reservation created - ID :" + str(res_id)
logit(self.logFile, mesg)
return res_id
def archiveAllocation(self, nodeId, ip_addr, hostName, vlan_id, user_id, reservation_type, res_notes, notes):
combined_notes = str(res_notes) + "|" + str(notes)
mesg = "Insert to allocation archive:"
query = "insert into allocationarchive (node_id, ip_addr, hostname, vlan_id, user_id, reservation_type, notes) \
values (\"" + \
str(nodeId) + "\", \"" + str(ip_addr) + "\", \"" + \
str(hostName) + "\", \"" + str(vlan_id) + "\", \"" + \
str(user_id) + "\", \"" + str(reservation_type) + "\", \"" + \
str(combined_notes) + "\")"
self.__insertDb(query)
@checkSuper
def allocateNode(self, reservationId, nodeId, hostName, vlanIsolate=None, ip_addr=None, notes=None):
#print "nodeId", nodeId, self.getMacFromSysId(nodeId)
# Check if node is already allocated
query = "select * from allocationinfo where node_id = \"" + str(nodeId) + "\""
result = self.__selectDb(query)
if result.rowcount > 0:
val = str(result.fetchone())
mesg = "ERROR: Node already allocated " + val + "\n"
logit(self.logFile, mesg)
exit()
# Check if reservation exists
query = "select reservation_id, user_id, reservation_date, \
reservation_expiration, notes from reservationinfo \
where reservation_id = \"" + str(reservationId) + "\""
result = self.__selectDb(query)
if result.rowcount > 0:
res_results = result.fetchall()[0]
val = str(res_results)
res_id= res_results[0]
user_id = res_results[1]
res_notes = res_results[4]
if self.verbose:
mesg = "Reservation: " + val
logit(self.logFile, mesg)
else:
mesg = "ERROR: Reservation does not exist: " + reservationId + "\n"
logit(self.logFile, mesg)
exit()
if not vlanIsolate:
vlan = self.getAvailableVlan()
else:
vlan = vlanIsolate
# Allocate nodes to the reservation
# Reserve the node and assign to user
vlan_id = self.getVlanId(vlan)
if vlan != 999:
if not ip_addr:
ip_addr = self.getDomainIp(vlan)
else:
# Check to see if IP is free
query = "select * from allocationinfo where ip_addr = \"" + str(ip_addr) + "\""
result = self.__selectDb(query)
if result.rowcount > 0:
mesg = "ERROR: IP Address specified (" + str(ip_addr) + ") already in use\n"
mesg += str(result.fetchone())
logit(self.logFile, mesg)
exit()
else:
ip_addr = self.getIpFromSysId(nodeId)
#print "ip is ", ip_addr
# If there is no hostname, set to default
if not hostName:
hostName = self.getLocationFromSysId(nodeId)
#print "hostname is ", hostName, "ip is ", ip_addr, "vlan is ", vlan_id
# Assign IP address to node
dhcpdns = DhcpDns(self.config, verbose=1)
dnscheck = dhcpdns.addDhcp(hostName, ip_addr, self.getMacFromSysId(nodeId))
dhcpdns.addDns(hostName, ip_addr)
mesg = "Insert to Node allocation:"
query = "insert into allocationinfo (reservation_id, node_id, ip_addr, hostname, vlan_id, notes) \
values (\"" + str(reservationId) + "\", \"" + str(nodeId) + "\", \"" + \
str(ip_addr) + "\", \"" + str(hostName) + "\", \"" + str(vlan_id) + "\", \"" + \
str(notes) + "\")"
self.__insertDb(query)
#Archive
reservation_type = "allocation"
self.archiveAllocation(nodeId, ip_addr, hostName, vlan_id, user_id, reservation_type, res_notes, notes)
def rgasstest(self, vlan_num):
query = "select * from vlaninfo where vlan_num = " + vlan_num
res = self.__selectDb(query).fetchall()
print res
def removeReservation(self, res):
query = "delete from reservationinfo where reservation_id = " + str(res)
self.__updateDb(query)
query = "delete from allocationinfo where reservation_id = " + str(res)
self.__updateDb(query)
@checkSuper
def releaseNode(self, nodeName):
# Get the nodeId
query = "select node_id, r.reservation_id, a.ip_addr, hostname, vlan_id, a.notes, r.notes,r.user_id from allocationinfo a, sysinfo s, reservationinfo r where a.node_id = s.sys_id and a.reservation_id = r.reservation_id and location = \"" + nodeName + "\""
print query
result = self.__selectDb(query)
if result.rowcount == 0:
mesg = "ERROR: Node not allocated\n"
sys.stderr.write(mesg)
exit(1)
if result.rowcount > 1:
mesg = "WARNING: Node allocated multiple times (" + str(result.rowcount) + ")"
logit(self.logFile, mesg)
val = result.fetchone()
nodeId = int(val[0])
resId = int(val[1])
ip_addr = val[2]
hostName = val[3]
vlan_id = int(val[4])
allocation_notes = val[5]
reservation_notes = val[6]
user_id = val[7]
print "hostname is ", hostName
# Assign IP address to node
dhcpdns = DhcpDns(self.config, verbose=1)
dnscheck = dhcpdns.removeDns(hostName)
dhcpdns.removeDhcp(hostName)
'''
query = "select reservation_id, notes from reservationinfo where node_id = " + str(nodeId)
result = self.__selectDb(query)
for i in result:
print i
print result.rowcount
if result.rowcount == 0:
mesg = "No Reservation for this node.\n Please check"
logit(self.logFile, mesg)
exit(1)
if result.rowcount > 1:
mesg = "WARNING: Muliple reservations exist (" + str(result.rowcount) + ")"
logit(self.logFile, mesg)
resId = int(result.fetchone()[0])
res_notes = int(result.fetchone()[1])
print resId, res_notes
'''
# Eventually should add count =1 so deletes do get out of control
query = "delete from allocationinfo where reservation_id = " + str(resId) + " and node_id = " + str(nodeId)
result = self.__selectDb(query)
# Archive node release
reservation_type = "release"
self.archiveAllocation(nodeId, ip_addr, hostName, vlan_id, user_id, reservation_type, reservation_notes, allocation_notes)
def addImage(self, imageName):
name = ""
dist = ""
dist_ver = ""
if len(imageName.split(":")) > 1:
name = imageName.split(":")[0]
if len(imageName.split(":")) > 2:
dist = imageName.split(":")[1]
if len(imageName.split(":")) >= 3:
dist_ver = imageName.split(":")[2]
query = "select * from imageinfo where image_name = \"" + name + "\""
result = self.__selectDb(query)
if result.rowcount > 0:
mesg = "ERROR: Image already exists\n"
sys.stderr.write(mesg)
exit()
if name == "":
mesg = "ERROR: Image details not specified\n"
logit(self.logFile, mesg)
mesg = "Example amd64-rgass-testing:Ubuntu:8.04\n"
mesg += "or amd64-rgass-testing::\n"
sys.stderr.write(mesg)
exit()
query = "insert into imageinfo (image_name, dist, dist_ver) values(\"" + name + "\", \"" + dist + "\", \"" + dist_ver + "\")"
self.__insertDb(query)
def delImage(self, imageName):
query = "delete from imageinfo where image_name = \"" + imageName + "\""
result = self.__selectDb(query)
if result.rowcount == 0:
mesg = "ERROR: No images match your entry\n"
sys.stderr.write(mesg)
exit()
def assignImagetoHost(self, host, image):
# imagemap db should be sys_id instead of mac_addr
# change later
cur_image = host['pxe_image_name']
# Get the id of the new image
query = "select image_id from imageinfo where image_name = " + "\"" + image + "\""
row = self.__queryDb(query)
if len(row) < 1:
mesg = "ERROR: Image \"" + image + "\" does not exist"
logit(self.logFile, mesg)
exit()
new_image_id = str(row[0][0])
# check for entry and delete in exists
query = "select * from imagemap where mac_addr = \"" + host['mac_addr'] + "\""
result = self.__selectDb(query)
if result.rowcount > 0:
query = "delete from imagemap where mac_addr = \"" + host['mac_addr'] + "\""
result = self.__selectDb(query)
# update the database entry with the new image for the host
query = "insert into imagemap (mac_addr, image_id) values (\"" + host['mac_addr'] + "\", " + new_image_id + ")"
self.__selectDb(query)
# Update tftp link
mac_addr = "01-" + string.lower(string.replace(host['mac_addr'], ":", "-"))
maclink = self.tftpImageDir + "/" + mac_addr
#print "mac link is ", maclink
# Check if it exists first
if os.path.exists(maclink):
try:
os.unlink(maclink)
except Exception, e:
traceback.print_exc(sys.exc_info())
if OSError:
print OSError
mesg = "Cannot modify file. Please use sudo\n"
sys.stderr.write(mesg)
return 1
print e
return 1
# Relink
newlink = os.path.basename(self.tftpBootOptionsDir) + "/" + image
try:
os.symlink(newlink, maclink)
mesg = "Image assignment Successful " + host['location'] + " " + host['mac_addr'] + " " + image
logit(self.logFile, mesg)
except Exception, e:
if OSError:
mesg = "Cannot modify file. Please use sudo\n"
sys.stderr.write(mesg)
return 1
print e
return 1
return 0

View file

@ -0,0 +1,31 @@
# 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$
#
class SystemAssignment():
def addDns():
pass
def assignPxeImage():
pass

View file

@ -0,0 +1,64 @@
# 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 sys
import os
class SystemManagementInterface(object):
""" Interface description for hardware management controllers
- IPMI
- IOL
"""
def __init__(self, config):
self.config = config
def getPowerStatus(self):
raise NotImplementedError
def isPowered(self):
''' Return boolean if system is powered on or not '''
raise NotImplementedError
def powerOn(self):
''' Powers on a system '''
raise NotImplementedError
def powerOff(self):
''' Powers off a system '''
raise NotImplementedError
def powerCycle(self):
''' Powers cycles a system '''
raise NotImplementedError
def powerReset(self):
''' Resets a system '''
raise NotImplementedError
def activateConsole(self):
''' Activate Console'''
raise NotImplementedError

View file

@ -0,0 +1,121 @@
# 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 sys
import os
from usermanagementinterface import UserManagementInterface
import time
def timeF(f):
def myF(*args, **kw):
start = time.time()
res = f(*args, **kw)
end = time.time()
print "%s took %f" % (f.__name__, end-start)
return res
myF.__name__ = f.__name__
return myF
class ldap(UserManagementInterface):
#@timeF
def __init__(self):
self.userCache = {}
self.userCacheForward = {}
self.userCacheReverse= {}
cmd = "getent passwd "
a = os.popen(cmd)
for user in a.readlines():
uid = int(user.split(":")[2])
username = user.split(":")[0]
name = user.split(":")[4]
self.userCacheForward[username] = self.userCacheForward.get(username, {})
self.userCacheForward[username]['name'] = self.userCacheForward[username].get("name", name)
self.userCacheForward[username]['uid'] = self.userCacheForward[username].get("uid", uid)
self.userCacheReverse[uid] = self.userCacheReverse.get(uid, {})
self.userCacheReverse[uid]['name'] = self.userCacheReverse.get('name', name)
self.userCacheReverse[uid]['username'] = self.userCacheReverse.get('username', username)
def getUserId(self, userName):
#cmd = "getent passwd | grep " + userName
#a = os.popen(cmd)
#idlist = []
#for user in a.readlines():
#if userName in user:
#idlist.append(user.split(":")[2])
val = self.userCacheForward.get(userName)
if val:
return val['uid']
return val['username']
#if len(set(idlist)) == 0:
#mesg = "ERROR: User " + userName + " does not exist\n"
#sys.stderr.write(mesg)
#exit()
#elif len(set(idlist)) == 1:
#return idlist[0]
#else:
#print idlist
#mesg = "ERROR: Multiple entries exist! Choose one and use the --uid option"
#sys.stderr.write(mesg)
#exit()
def getUserName(self, userId):
# Check the cache
val = self.userCacheReverse.get(userId)
if val:
return val['username']
return userId
''' the old way
val = self.userCache.get(userId)
if val:
return self.userCache[userId]
cmd = "getent passwd | grep " + str(userId)
a = os.popen(cmd)
idlist = []
for user in a.readlines():
idlist.append(user.split(":")[0])
if len(idlist) > 0:
# Cache the info to speed things up
self.userCache[userId] = idlist[0]
return idlist[0]
return userId
'''
def getGroupId(self):
pass
class files(UserManagementInterface):
def __init__(self):
raise NotImplementedError
def getUserId(self):
raise NotImplementedError
def getGroupId(self):
raise NotImplementedError

View file

@ -0,0 +1,42 @@
# 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 sys
import os
class UserManagementInterface(object):
""" Interface description for user management
- ldap
- passwd
"""
def __init__(self, config):
self.config = config
def getUserId(self, userName):
raise NotImplementedError
def getUserName(self, userId):
raise NotImplementedError
def getGroupId(self, userId):
raise NotImplementedError

79
ssh/zoni-cli/util.py Normal file
View file

@ -0,0 +1,79 @@
# 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 ConfigParser
import time
def loadConfigFile(filename):
parser = ConfigParser.ConfigParser()
parser.read(filename)
config = {}
# Logging
config['logFile'] = parser.get("logging", "LOG_FILE").split()[0]
# DB connection
config['dbUser'] = parser.get("dbConnection", "DB_USER").split()[0]
config['dbPassword'] = config.get("dbPassword", "")
if not parser.get("dbConnection", "DB_PASSWORD") == "":
config['dbPassword'] = parser.get("dbConnection", "DB_PASSWORD").strip("\",'")
config['dbHost'] = parser.get("dbConnection", "DB_HOST").split()[0]
config['dbPort'] = int(parser.get("dbConnection", "DB_PORT").split()[0])
config['dbInst'] = parser.get("dbConnection", "DB_INST").split()[0]
# TFTP info
config['tftpRootDir'] = parser.get("tftp", "TFTP_ROOT_DIR").split()[0]
config['tftpImageDir'] = parser.get("tftp", "TFTP_IMAGE_DIR").split()[0]
config['tftpBootOptionsDir'] = parser.get("tftp", "TFTP_BOOT_OPTIONS_DIR").split()[0]
config['tftpUpdateFile'] = parser.get("tftp", "TFTP_UPDATE_FILE").split()[0]
config['tftpBaseFile'] = parser.get("tftp", "TFTP_BASE_FILE").split()[0]
config['tftpBaseMenuFile'] = parser.get("tftp", "TFTP_BASE_MENU_FILE").split()[0]
# SNMP
config['snmpCommunity'] = parser.get("snmp", "SNMP_COMMUNITY").split()[0]
# VLAN
config['vlan_reserved'] = parser.get("vlan", "VLAN_RESERVED")
config['vlan_max'] = parser.get("vlan", "VLAN_MAX")
# HARDWARE CONTROL
config['hardware_control'] = parser.get("hardware", "HARDWARE_CONTROL")
# DHCP/DNS
config['dnsKeyFile'] = parser.get("DhcpDns", "dnsKeyfile")
config['dnsServer'] = parser.get("DhcpDns", "dnsServer")
config['dnsDomain'] = parser.get("DhcpDns", "dnsDomain")
config['dnsExpire'] = parser.get("DhcpDns", "dnsExpire")
config['dhcpServer'] = parser.get("DhcpDns", "dhcpServer")
config['dhcpKeyName'] = parser.get("DhcpDns", "dhcpKeyName")
config['dhcpSecretKey'] = parser.get("DhcpDns", "dhcpSecretKey")
#self.ap_model['radius'] = int(parser.get("wireless_range", "radius").split()[0])
return config
def logit(logfile, mesg):
fd = open(logfile, "a+");
mesg = str(time.time()) + " " + mesg + "\n"
fd.write(mesg);
fd.close;
#if verbose:
print mesg
fd.close

20
ssh/zoni-cli/version.py Normal file
View file

@ -0,0 +1,20 @@
# 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 = "$Id:$"
version = "$LastChangedDate:$"
revision = "$Rev:$"

486
ssh/zoni-cli/zoni-cli.py Normal file
View file

@ -0,0 +1,486 @@
# /usr/bin/env python
#
# 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 os
import sys
import optparse
import resourcequerysql
from systemmanagementinterface import SystemManagementInterface
from ipmi import Ipmi
from usermanagementinterface import UserManagementInterface
from bootmanagementinterface import BootManagementInterface
import pxe
from raritanpdu import raritanDominionPx
from delldrac import dellDrac
from util import *
import version
from hwswitchinterface import HwSwitchInterface
from hwswitch import HwDellSwitch
import usermanagement
#from usermanagement import UserManagement
def parseTable():
pass
def main():
""" Main """
ver = version.version.split(" ")[1]
rev = version.revision
configFile = loadConfigFile("ZONI_DEFAULT.conf")
#logit(configFile['logFile'], "Starting prs_client")
#logit(configFile['logFile'], "Loading config file")
parser = optparse.OptionParser(usage="%prog [-n] [-u] [--uid] [-v]", version="%prog " + ver + " " + rev)
parser.add_option("-n", "--nodeName", dest="nodeName", help="Specify node")
parser.add_option("--switchPort", "--switchport", dest="switchPort", help="Specify switchport switchname:portnum")
parser.add_option("-u", "--userName", dest="userName", help="Specify user name")
parser.add_option("--uid", dest="uid", help="Specify user id")
parser.add_option("-v", "--verbose", dest="verbosity", help="Be verbose", action="store_true", default=False)
# Hardware controller
group = optparse.OptionGroup(parser, "Hardware control", "Options to control power on nodes")
group.add_option("--hw", dest="hardwareType", help="Make hardware call to ipmi|drac|pdu")
group.add_option("--powerStatus", "--powerstatus", dest="POWERSTATUS", help="Get power status on node", action="store_true", default=False)
group.add_option("--reboot", "--reboot", dest="REBOOTNODE", help="Reboot node (Soft)", action="store_true", default=False)
group.add_option("--powerCycle", "--powercycle", dest="POWERCYCLE", help="Power Cycle (Hard)", action="store_true", default=False)
group.add_option("--powerOff", "--poweroff", dest="POWEROFF", help="Power off node", action="store_true", default=False)
group.add_option("--powerOn", "--poweron", dest="POWERON", help="Power on node", action="store_true", default=False)
group.add_option("--powerReset", "--powerreset", dest="POWERRESET", help="Power reset node", action="store_true", default=False)
group.add_option("--console", dest="CONSOLE", help="Console mode", action="store_true", default=False)
parser.add_option_group(group)
# Query Interface
group = optparse.OptionGroup(parser, "Query Interface", "Query current systems and allocations")
group.add_option("-R", "--showReservation", "--showreservation", dest="showReservation", help="Show current node reservations", action="store_true", default=False)
group.add_option("-A", "--showAllocation", "--showallocation", dest="showAllocation", help="Show current node allocation", action="store_true", default=False)
group.add_option("-s", "--showResources", dest="showResources", help="Show available resources to choose from", action="store_true", default=False)
group.add_option("-p", "--procs", dest="numProcs", help="Set number of processors" )
group.add_option("-c", "--clock", dest="clockSpeed", help="Processor clock" )
group.add_option("--memory", dest="numMemory", help="Amount of memory (Bytes)" )
group.add_option("-f", "--cpuflags", dest="cpuFlags", help="CPU flags" )
group.add_option("--cores", dest="numCores", help="Number of Cores" )
group.add_option("-i", "--showPxeImages", "--showpxeimages", dest="showPxeImages", help="Show available PXE images to choose from", action="store_true", default=False)
group.add_option("-m", "--showPxeImageMap", "--showpxeimagemap", dest="showPxeImageMap", help="Show PXE images host mapping", action="store_true", default=False)
group.add_option("--showArchive", "--showarchive", dest="showArchive", help="Show allocation archive", action="store_true", default=False)
parser.add_option_group(group)
#parser.add_option("-p", "--printResources", dest="printResources", help="Print available resources to choose from", action="store_true", default=False)
# Admin INterface
group = optparse.OptionGroup(parser, "Admin Interface", "Administration Interface:")
group.add_option("--admin", dest="ADMIN", help="Enter Admin mode", action="store_true", default=False)
group.add_option("--addPxeImage", "--addpxeimage", dest="imageName", help="Add PXE image to database", action="store_true", default=False)
group.add_option("--enableHostPort", "--enablehostport", dest="enableHostPort", help="Enable a switch port", action="store_true", default=False)
group.add_option("--disableHostPort", "--disablehostport", dest="disableHostPort", help="Disable a switch port", action="store_true", default=False)
group.add_option("--removeVlan", "--removevlan", dest="removeVlanId", help="Remove vlan from all switches")
group.add_option("--createVlan", "--createvlan", dest="createVlanId", help="Create a vlan on all switches")
group.add_option("--addNodeToVlan", "--addnodetovlan", dest="add2Vlan", help="Add node to a vlan")
group.add_option("--removeNodeFromVlan", "--removenodefromvlan", dest="removeFromVlan", help="Remove node from a vlan")
group.add_option("--setNativeVlan", "--setnativevlan", dest="setNative", help="Configure native vlan")
group.add_option("--restoreNativeVlan", "--restorenativevlan", dest="restoreNative", help="Restore native vlan", action="store_true", default=False)
group.add_option("--removeAllVlans", "--removeallvlans", dest="removeAllVlans", help="Removes all vlans from a switchport", action="store_true", default=False)
group.add_option("--sendSwitchCommand", "--sendswitchcommand", dest="sendSwitchCommand", help="Send Raw Switch Command, VERY DANGEROUS. config;interface switchport ethernet g14;etc")
group.add_option("--interactiveSwitchConfig", "--interactiveswitchconfig", dest="interactiveSwitchConfig", help="Interactively configure a switch. switchhname")
group.add_option("--showSwitchConfig", "--showswitchconfig", dest="showSwitchConfig", help="Show switch config for node", action="store_true", default=False)
parser.add_option_group(group)
# Switch
#group = optparse.OptionGroup(parser, "Switch Interface", "Switch Interface:")
#group.add_option("--rawswitch", dest="RAWSWITCH", help="Enter RAW Switch Admin mode", action="store_true", default=False)
#group.add_option("--enablePort", "--enableport", dest="enablePort", help="Enable a port on the switch")
#group.add_option("--disablePort", "--disableport", dest="disablePort", help="Disable a port on the switch")
#group.add_option("--addVlanToTrunks", "--addvlantotrunks", dest="addVlanToTrunks", help="")
# Allocation Interface
group = optparse.OptionGroup(parser, "Allocation Interface", "Change current systems allocations:")
#group.add_option("-a", "--allocateResources", dest="allocateResources", help="Allocate resource", action="store_true", default=False)
group.add_option("--addImage", "--addimage", dest="addImage", help="Add image to PRS - amd64-image:dist:dist_ver")
group.add_option("--delImage", "--delimage", dest="delImage", help="Delete PXE image")
group.add_option("--assignImage", "--assignimage", dest="assignImage", help="Assign image to resource")
group.add_option("--allocateNode", "--allocatenode", dest="allocateNode", help="Assign node to a user", action="store_true", default=False)
group.add_option("--allocationNotes", "--allocationnotes", dest="allocationNotes", help="Description of allocation")
group.add_option("--vlanIsolate", "--vlanisolate", dest="vlanIsolate", help="Specify vlan for network isolation")
group.add_option("--hostName", "--hostname", dest="hostName", help="Specify hostname for node")
group.add_option("--ipaddr", dest="ipAddr", help="Specify ip address for node")
group.add_option("--releaseNode", "--releasenode", dest="releaseNode", help="Release current node allocation", action="store_true", default=False)
group.add_option("--reservationDuration", "--reservationduration", dest="reservationDuration", help="Specify duration of node reservation - YYYYMMDD format")
group.add_option("--reservationId", "--reservationid", dest="reservationId", help="Reservation ID")
group.add_option("--reservationNotes", "--reservationnotes", dest="reservationNotes", help="Description of reservation")
group.add_option("--addReservation", "--addreservation", dest="addReservation", help="Add a Reservation", action="store_true", default=False)
group.add_option("--updateReservation", "--updatereservation", dest="updateReservation", help="Update Reservation", action="store_true", default=False)
group.add_option("--delReservation", "--delreservation", dest="delReservation", help="Delete Reservation")
#group.add_option("-a", "--allocateResources", dest="allocateResources", help="Allocate resource", action="store_true", default=False)
group.add_option("--rgasstest", dest="rgasstest", help="Debug testing function", action="store_true", default=False)
parser.add_option_group(group)
(options, args) = parser.parse_args()
cmdargs = {}
# setup db connection
query = resourcequerysql.ResourceQuerySql(configFile, options.verbosity)
# Get host info
host=None
if options.nodeName:
host = query.getHostInfo(options.nodeName)
#print host
# Hardware control
if options.hardwareType:
if (options.hardwareType) and options.hardwareType not in configFile['hardware_control']:
mesg = "Non support hardware type specified\n"
mesg += "Supported types:\n"
mesg += str(configFile['hardware_control'])
mesg += "\n\n"
sys.stdout.write(mesg)
exit()
if (options.hardwareType) and options.nodeName:
#host = query.getHostInfo(options.nodeName)
if options.hardwareType == "ipmi":
hw = Ipmi(options.nodeName, host["ipmi_user"], host["ipmi_password"])
if options.hardwareType == "pdu":
hw = raritanDominionPx(host)
if options.hardwareType == "drac":
# Check if node has drac card
if "drac_name" in host:
hw = dellDrac(host)
else:
mesg = "Host (" + options.nodeName + ") does not have a DRAC card!!\n"
sys.stdout.write(mesg)
exit(1)
if options.verbosity:
hw.setVerbose(True)
if options.REBOOTNODE:
hw.powerReset()
exit()
if options.POWERCYCLE:
hw.powerCycle()
exit()
if options.POWEROFF:
hw.powerOff()
exit()
if options.POWERON:
hw.powerOn()
exit()
if options.POWERRESET:
hw.powerReset()
exit()
if options.POWERSTATUS:
hw.getPowerStatus()
exit()
if options.CONSOLE:
hw.activateConsole()
exit()
hw.getPowerStatus()
if (options.hardwareType) and not options.nodeName:
mesg = "\nMISSSING OPTION: Node name required -n or --nodeName\n"
parser.print_help();
sys.stderr.write(mesg)
exit()
if (options.REBOOTNODE or options.POWERCYCLE or options.POWEROFF or \
options.POWERON or options.POWERSTATUS or options.CONSOLE or \
options.POWERRESET) and not options.hardwareType:
parser.print_help()
usage = "\nMISSING OPTION: When specifying hardware parameters, you need the --hw option\n"
print usage
exit()
# Query Interface
if (options.numProcs):
cmdargs["num_procs"] = options.numProcs
if (options.numMemory):
cmdargs["mem_total"] = options.numMemory
if (options.clockSpeed):
cmdargs["clock_speed"] = options.clockSpeed
if (options.numCores):
cmdargs["num_cores"] = options.numCores
if (options.cpuFlags):
cmdargs["cpu_flags"] = options.cpuFlags
if (options.nodeName):
cmdargs["node_id"] = options.nodeName
if (options.numCores or options.clockSpeed or options.numMemory or options.numProcs or options.cpuFlags) and not options.showResources:
usage = "MISSING OPTION: When specifying hardware parameters, you need the -s or --showResources switch"
print usage
parser.print_help()
exit()
# Show current allocations
if (options.showAllocation):
if options.uid:
print "set"
nameorid = int(options.uid)
else:
nameorid = options.userName
query.showAllocation(nameorid)
exit()
# Show current reservation
if (options.showReservation):
if options.uid:
print "set"
nameorid = int(options.uid)
else:
nameorid = options.userName
query.showReservation(nameorid)
exit()
# Show allocation Archive
if (options.showArchive):
query.showArchive()
# Print all Resources
if (options.showResources):
query.showResources(cmdargs)
# Show PXE images
if (options.showPxeImages):
query.showPxeImages()
# Show machine to PXE image mapping
if (options.showPxeImageMap):
query.showPxeImagesToSystemMap(cmdargs)
exit()
if (len(sys.argv) == 1):
parser.print_help()
exit()
# Get the host object
#hostObj = getHostObject()
#if (options.allocateResources) and options.nodeName:
#query.getHostInfo(options.nodeName)
#exit()
# Delete reservation
if (options.delReservation):
query.removeReservation(options.delReservation)
exit()
# Specify usermanagement, ldap or files
usermgt = usermanagement.ldap()
if (options.rgasstest):
#pdu = raritanDominionPx(host)
#print pdu
#bootit = pxe.Pxe(configFile, options.verbosity)
#bootit.createPxeUpdateFile(query.getPxeImages())
#bootit.updatePxe()
#print "host is ", host
#drac = dellDrac("drac-r2r1c3", 1)
#drac.getPowerStatus()
#drac.powerOff()
#drac.powerOn()
#drac.powerCycle()
#drac.powerReset()
#drac.getPowerStatus()
print "host is ", host
pdu = raritanDominionPx(host)
print "pdu", pdu
pdu.getPowerStatus()
exit()
# Create a reservation for a user
if (options.addReservation):
if not (options.userName or options.uid):
mesg = "ERROR: AddReservation requires the following arguments...\n"
if not (options.userName or options.uid):
mesg += " Username: --userName=username or --uid 1000\n"
mesg += " Reservation Duration: --reservationDuration YYYYMMDD or numdays(optional, default 15 days)\n"
#mesg += " ReservationId: --reservationId IDNUM(optional, you want this if you want to add nodes to an existing reservation)\n"
mesg += " Notes: --reservationNotes(optional)\n"
sys.stderr.write(mesg)
exit()
userId = options.uid
if not options.uid:
userId = usermgt.getUserId(options.userName)
reservationId = query.addReservation(userId, options.reservationDuration, options.reservationNotes)
# Allocate node to user
if (options.allocateNode):
vlanNum = 999
if (options.vlanIsolate):
vlanNum = options.vlanIsolate
if not (options.reservationId) or not options.nodeName:
mesg = "ERROR: AllocateNode requires the following arguments...\n"
if not (options.nodeName):
mesg += " NodeName: --nodeName r1r1u25 \n"
if not (options.reservationId):
mesg += " ReservationId: --reservationId IDNUM(add nodes to an existing reservation)\n"
mesg += " Hostname: --hostName mynode01\n"
mesg += " Domain: --vlanIsolate vlan_num(default 999)\n"
mesg += " IP address: --ipaddr 172.17.10.100\n"
mesg += " Notes: --allocationNotes(optional)\n"
sys.stderr.write(mesg)
exit()
query.allocateNode(options.reservationId, host['node_id'], options.hostName, vlanNum, options.ipAddr, options.allocationNotes)
exit()
# Update allocation
if (options.updateReservation):
if not options.reservationId:
mesg = "ERROR: UpdateReservation requires the following arguments...\n"
if not (options.reservationId):
mesg += " Reservation ID: --reservationId RES\n"
mesg += " NodeName: --nodeName r1r1u25 (optional)\n"
mesg += " Username: --userName=username or --uid 1000 (optional)\n"
mesg += " Reservation Duration: --reservationDuration YYYYMMDD or numdays (optional, default 15 days)\n"
mesg += " Vlan: --vlanIsolate vlan_num(optional)\n"
mesg += " Notes: --reservationNotes(optional)\n"
sys.stderr.write(mesg)
exit()
userId = None
if options.uid and options.userName:
# Get the username from uid
userId = options.uid
if not options.uid:
userId = usermgt.getUserId(options.userName)
print options.reservationId, userId, options.reservationDuration, options.vlanIsolate, options.reservationNotes
query.updateReservation(options.reservationId, userId, options.reservationDuration, options.vlanIsolate, options.reservationNotes)
# Release node allocation
if (options.releaseNode):
if not options.nodeName:
mesg = "ERROR: releaseNode requires the following arguments...\n"
if not (options.nodeName):
mesg += " NodeName: --nodeName r1r1u25 \n"
sys.stderr.write(mesg)
exit()
query.releaseNode(options.nodeName)
# Assign image to host
if (options.assignImage):
if not options.nodeName:
usage = "Node not specified. Please specify a node with --nodeName or -n"
print usage
exit()
if query.assignImagetoHost(host, options.assignImage):
print "ERROR"
exit()
# Update PXE
bootit = pxe.Pxe(configFile, options.verbosity)
bootit.createPxeUpdateFile(query.getPxeImages())
bootit.updatePxe()
# Add image to database
if (options.addImage):
query.addImage(options.addImage)
# Delete PXE image
if (options.delImage):
query.delImage(options.delImage)
# Admin Interface
# snmpwalk -v2c -c prs-domain sw0-r1r1 .1.3.6.1.2.1.17.7.1.4.3.1.5
if (options.ADMIN):
if not options.nodeName and not options.createVlanId and not options.removeVlanId and not options.switchPort and not options.interactiveSwitchConfig:
mesg = "\nERROR: nodeName or switch not specified. Please specify nodename with -n or --nodeName or --switchport\n"
parser.print_help()
sys.stderr.write(mesg)
exit()
# We can specify port/switch combinations here
if options.switchPort:
host = query.getSwitchInfo(options.switchPort.split(":")[0])
if len(options.switchPort.split(":")) > 1:
host['hw_port'] = options.switchPort.split(":")[1]
host['location'] = options.switchPort
if options.interactiveSwitchConfig:
host = query.getSwitchInfo(options.interactiveSwitchConfig)
HwSwitch = HwDellSwitch
hwswitch = HwSwitch(configFile, host)
if options.verbosity:
hwswitch.setVerbose(True)
#print "create vlan", options.createVlanId
if options.enableHostPort and options.nodeName:
hwswitch.enableHostPort()
if options.disableHostPort and (options.nodeName or options.switchPort):
hwswitch.disableHostPort()
if options.createVlanId:
hwswitch.createVlans(options.createVlanId, query.getAllSwitches(), query)
if options.removeVlanId:
hwswitch.removeVlans(options.removeVlanId, query.getAllSwitches(), query)
if options.add2Vlan and (options.nodeName or options.switchPort):
hwswitch.addNodeToVlan(options.add2Vlan)
if options.removeFromVlan and options.nodeName:
hwswitch.removeNodeFromVlan(options.removeFromVlan)
if options.setNative and (options.nodeName or options.switchPort):
hwswitch.setNativeVlan(options.setNative)
if options.restoreNative and options.nodeName:
hwswitch.restoreNativeVlan()
if options.removeAllVlans and (options.nodeName or options.switchPort):
hwswitch.removeAllVlans()
if options.sendSwitchCommand and (options.nodeName or options.switchPort):
hwswitch.sendSwitchCommand(options.sendSwitchCommand)
if options.interactiveSwitchConfig:
hwswitch.interactiveSwitchConfig()
if options.showSwitchConfig and (options.nodeName or options.switchPort):
hwswitch.showInterfaceConfig()
if __name__ == "__main__":
main()