mirror of
https://github.com/xcat2/confluent.git
synced 2026-09-29 08:41:00 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5702f7372b | |||
| f9e2f2e656 | |||
| 1dcca5d3eb | |||
| 0845a914c6 |
@@ -46,7 +46,10 @@ def main():
|
||||
noderange = args[0]
|
||||
nodelist = '/noderange/{0}/nodes/'.format(noderange)
|
||||
except IndexError:
|
||||
nodelist = '/nodes/'
|
||||
if os.environ.get('TEST_XCAT'):
|
||||
nodelist = "/xcat/nodes/"
|
||||
else:
|
||||
nodelist = '/nodes/'
|
||||
client.check_globbing(noderange)
|
||||
session = client.Command()
|
||||
exitcode = 0
|
||||
|
||||
@@ -123,7 +123,7 @@ def load_plugins():
|
||||
|
||||
|
||||
rootcollections = ['discovery/', 'events/', 'networking/',
|
||||
'noderange/', 'nodes/', 'nodegroups/', 'users/', 'version']
|
||||
'noderange/', 'nodes/', 'nodegroups/', 'users/', 'xcat/', 'version']
|
||||
|
||||
|
||||
class PluginRoute(object):
|
||||
@@ -977,6 +977,16 @@ def handle_path(path, operation, configmanager, inputdata=None, autostrip=True):
|
||||
"""
|
||||
pathcomponents = path.split('/')
|
||||
del pathcomponents[0] # discard the value from leading /
|
||||
xcat_url = False
|
||||
if pathcomponents and pathcomponents[0] == 'xcat':
|
||||
xcat_url = True
|
||||
if 'xcat/' in rootcollections:
|
||||
rootcollections.remove('xcat/')
|
||||
del pathcomponents[0]
|
||||
elif 'xcat/' not in rootcollections:
|
||||
rootcollections.insert(-1, 'xcat/')
|
||||
if xcat_url:
|
||||
configmanager.log("Start to deal with xCAT URL: %s" % path)
|
||||
if pathcomponents[-1] == '':
|
||||
del pathcomponents[-1]
|
||||
if not pathcomponents: # root collection list
|
||||
|
||||
@@ -30,6 +30,7 @@ import confluent.asynchttp
|
||||
import confluent.shellserver as shellserver
|
||||
import confluent.tlvdata
|
||||
import confluent.util as util
|
||||
from confluent.xcclient.xcat_manager import xCATConfigManager
|
||||
import copy
|
||||
import eventlet
|
||||
import eventlet.greenthread
|
||||
@@ -56,7 +57,7 @@ opmap = {
|
||||
'PUT': 'update',
|
||||
'DELETE': 'delete',
|
||||
}
|
||||
|
||||
xcat_cfm = None
|
||||
|
||||
class RobustCookie(Cookie.SimpleCookie):
|
||||
# this is very bad form, but BaseCookie has a terrible flaw
|
||||
@@ -437,6 +438,11 @@ def resourcehandler_backend(env, start_response):
|
||||
("Set-Cookie", m.OutputString())
|
||||
for m in authorized['cookie'].values())
|
||||
cfgmgr = authorized['cfgmgr']
|
||||
if (env['PATH_INFO'].startswith('/xcat')):
|
||||
global xcat_cfm
|
||||
if xcat_cfm is None:
|
||||
xcat_cfm = xCATConfigManager()
|
||||
cfgmgr = xcat_cfm
|
||||
if (operation == 'create') and env['PATH_INFO'] == '/sessions/current/async':
|
||||
pagecontent = ""
|
||||
try:
|
||||
|
||||
@@ -1575,9 +1575,13 @@ class CryptedAttributes(Attributes):
|
||||
self.desc = desc
|
||||
nkv = {}
|
||||
for key in kv.iterkeys():
|
||||
nkv[key] = {'isset': False}
|
||||
try:
|
||||
if kv[key] is not None and kv[key]['cryptvalue'] != '':
|
||||
if kv[key] is None:
|
||||
continue
|
||||
elif not isinstance(kv[key], dict):
|
||||
self.defaulttype = 'text'
|
||||
nkv[key] = kv[key]
|
||||
elif kv[key] is not None and kv[key]['cryptvalue'] != '':
|
||||
nkv[key] = {'isset': True}
|
||||
nkv[key]['inheritedfrom'] = kv[key]['inheritedfrom']
|
||||
except KeyError:
|
||||
|
||||
@@ -128,6 +128,8 @@ def retrieve_nodes(nodes, element, configmanager, inputdata):
|
||||
for node in util.natural_sort(list(attributes)):
|
||||
for attribute in sorted(attributes[node].iterkeys()):
|
||||
currattr = attributes[node][attribute]
|
||||
if currattr is None:
|
||||
continue
|
||||
try:
|
||||
desc = allattributes.node[attribute]['description']
|
||||
except KeyError:
|
||||
@@ -140,6 +142,8 @@ def retrieve_nodes(nodes, element, configmanager, inputdata):
|
||||
elif isinstance(currattr, list):
|
||||
yield msg.ListAttributes(
|
||||
node, {attribute: currattr}, desc)
|
||||
elif isinstance(currattr, str):
|
||||
yield msg.Attributes(node, {attribute: currattr}, desc)
|
||||
else:
|
||||
print attribute
|
||||
print repr(currattr)
|
||||
|
||||
@@ -46,7 +46,9 @@ import confluent.core as pluginapi
|
||||
import confluent.shellserver as shellserver
|
||||
import confluent.collective.manager as collective
|
||||
import confluent.util as util
|
||||
from confluent.xcclient.xcat_manager import xCATConfigManager
|
||||
|
||||
xcat_cfm = None
|
||||
tracelog = None
|
||||
auditlog = None
|
||||
try:
|
||||
@@ -115,6 +117,8 @@ def sessionhdl(connection, authname, skipauth=False, cert=None):
|
||||
if authdata is not None:
|
||||
cfm = authdata[1]
|
||||
authenticated = True
|
||||
if xcat_cfm is None:
|
||||
xcat_cfm = xCATConfigManager()
|
||||
send_data(connection, "Confluent -- v0 --")
|
||||
while not authenticated: # prompt for name and passphrase
|
||||
send_data(connection, {'authpassed': 0})
|
||||
@@ -156,6 +160,9 @@ def sessionhdl(connection, authname, skipauth=False, cert=None):
|
||||
return collective.handle_connection(connection, None, request['collective'],
|
||||
local=True)
|
||||
while request is not None:
|
||||
if request['path'].startswith('/xcat'):
|
||||
global xcat_cfm
|
||||
cfm = xcat_cfm
|
||||
try:
|
||||
process_request(
|
||||
connection, request, cfm, authdata, authname, skipauth)
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
###############################################################################
|
||||
# IBM(c) 2019 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
###############################################################################
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
|
||||
# 'node', which can be considered a 'system' or a 'vm'
|
||||
nodeattrs = {
|
||||
'groups': 'nodelist.groups',
|
||||
'collective.manager': None,
|
||||
'discovery.passwordrules': None,
|
||||
'discovery.policy': ['switch', 'mtms', 'sequential'],
|
||||
'info.note': 'nodelist.comments',
|
||||
'location.room': 'nodepos.room',
|
||||
'location.row': 'nodepos.comments',
|
||||
'location.rack': 'nodepos.rack',
|
||||
'location.u': 'nodepos.u',
|
||||
'console.logging': 'site.consoleondemand',
|
||||
'console.method': 'nodehm.cons',
|
||||
'virtualization.host': 'vm.host',
|
||||
'hardwaremanagement.manager': 'ipmi.bmc',
|
||||
'hardwaremanagement.method': 'nodehm.mgt',
|
||||
'enclosure.bay': None,
|
||||
'enclosure.extends': None,
|
||||
'enclosure.manager': None,
|
||||
'id.model': 'vpd.mtm',
|
||||
'id.serial': 'vpd.serial',
|
||||
'id.uuid': 'vpd.uuid',
|
||||
'net.bootable': None,
|
||||
'net.ipv4_gateway': None,
|
||||
'net.hwaddr': 'mac.mac',
|
||||
'net.switch': 'switch.switch',
|
||||
'net.switchport': 'switch.port',
|
||||
'secret.snmpcommunity': 'site.snmpc',
|
||||
'secret.ipmikg': None,
|
||||
'secret.hardwaremanagementuser': 'ipmi.username',
|
||||
'secret.hardwaremanagementpassword': 'ipmi.password',
|
||||
'pubkeys.addpolicy': None,
|
||||
'pubkeys.ssh': None,
|
||||
}
|
||||
|
||||
def conattr2xcatattr(attrs=()):
|
||||
if '*' in attrs or attrs == ():
|
||||
return nodeattrs
|
||||
attr_dict = {}
|
||||
if not isinstance(attrs, list):
|
||||
attr_dict[attrs] = nodeattrs.get(attrs, None)
|
||||
else:
|
||||
for attr in attrs:
|
||||
attr_dict[attr] = nodeattrs.get(attr, None)
|
||||
return attr_dict
|
||||
|
||||
def conattr2xcatattrv1(attrs):
|
||||
if '*' in attrs:
|
||||
attrs = nodeattrs.keys()
|
||||
all_attr_set=set(nodeattrs.keys())
|
||||
check_set=set(attrs)
|
||||
unknown_attrs = check_set - all_attr_set
|
||||
known_attrs = check_set & all_attr_set
|
||||
if len(unknown_attrs) > 0:
|
||||
return "The attrs " + str(unknown_attrs) + " are unknown"
|
||||
tab_cols={}
|
||||
error_attrs=[]
|
||||
for attr in known_attrs:
|
||||
xcatattr = nodeattrs[attr]
|
||||
if xcatattr is None:
|
||||
print(attr + " value is None?")
|
||||
error_attrs.append(attr)
|
||||
elif isinstance(xcatattr, list):
|
||||
for k in xcatattr:
|
||||
t,p,c = k.rpartition('.')
|
||||
if t in tab_cols:
|
||||
tab_cols[t].append(c)
|
||||
else:
|
||||
tab_cols[t] = [c]
|
||||
else:
|
||||
t,p,c = xcatattr.rpartition('.')
|
||||
if t in tab_cols:
|
||||
tab_cols[t].append(c)
|
||||
else:
|
||||
tab_cols[t] = [c]
|
||||
if len(error_attrs):
|
||||
return "The attrs " + str(error_attrs) + " are not supported yet"
|
||||
return tab_cols
|
||||
|
||||
if __name__ == '__main__':
|
||||
#print(conattr2xcatattrv2(['hardwaremanagement.manager','collective.manager', 'secret.hardwaremanagementuser']))
|
||||
#print(conattr2xcatattr(['hardwaremanagement.manager','collective.manager', 'secret.hardwaremanagementuser']))
|
||||
#print(conattr2xcatattr())
|
||||
#mydict = conattr2xcatattr(['hardwaremanagement.manager','collective.manager', 'secret.hardwaremanagementuser'])
|
||||
mydict = conattr2xcatattr('*')
|
||||
print(get_node_attr(mydict))
|
||||
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
#!/usr/bin/env python
|
||||
###############################################################################
|
||||
# IBM(c) 2019 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
###############################################################################
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import dbobject
|
||||
from dbobject import *
|
||||
from dbsession import DBsession
|
||||
from sqlalchemy import or_
|
||||
#from xcclient.shell import CommandException
|
||||
from exceptions import *
|
||||
import utils
|
||||
|
||||
def create_or_update(session,tabcls,key,newdict,ismatrixtable=True):
|
||||
tabkeys=tabcls.primkeys()
|
||||
#for matrix table, remove the record if all the non-key values are None or blank
|
||||
delrow=1
|
||||
#for flat table, keep the record untouch if the non-key values are None
|
||||
skiprow=1
|
||||
|
||||
objkeys=tabcls.getobjkey()
|
||||
|
||||
if type(key) not in (list,tuple):
|
||||
key=[key]
|
||||
keyvals=zip(objkeys,key)
|
||||
for (keyname,keyval) in keyvals:
|
||||
newdict[keyname]=keyval
|
||||
|
||||
tabcols=tabcls.getcolumns()
|
||||
for item in newdict.keys():
|
||||
if item not in tabcols:
|
||||
if newdict[item] is None:
|
||||
del newdict[item]
|
||||
continue
|
||||
else:
|
||||
raise BadSchemaException("Error: no column '"+item+"' in table "+tabcls.__tablename__+", might caused by mismatch between schema version and xCAT version!")
|
||||
|
||||
if item not in objkeys and newdict[item]:
|
||||
skiprow=0
|
||||
delrow=0
|
||||
|
||||
if item not in objkeys and newdict[item] is None:
|
||||
newdict[item]=''
|
||||
|
||||
#delete table rows when (1)the object keys are None or blank (2)the key is not specified in newdict and all non-key values are blank
|
||||
if item not in objkeys and newdict[item]!='':
|
||||
delrow=0
|
||||
|
||||
if item == 'disable' and newdict[item]=='':
|
||||
newdict[item]=None
|
||||
|
||||
if not ismatrixtable:
|
||||
if skiprow:
|
||||
return
|
||||
#do not remove for flat table
|
||||
delrow=0
|
||||
|
||||
#if tabcls.__tablename__=='switch':
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
try:
|
||||
query=session.query(tabcls)
|
||||
for tabkey in tabkeys:
|
||||
query=query.filter(getattr(tabcls,tabkey) == newdict[tabkey])
|
||||
record=query.all()
|
||||
except Exception, e:
|
||||
raise DBException("Error: query xCAT table "+tabcls.__tablename__+" failed: "+str(e))
|
||||
if record:
|
||||
if delrow:
|
||||
try:
|
||||
for item in record:
|
||||
session.delete(item)
|
||||
except Exception, e:
|
||||
raise DBException("Error: delete "+key+" is failed: "+str(e))
|
||||
#else:
|
||||
# print("delete row in xCAT table "+tabcls.__tablename__+".")
|
||||
else:
|
||||
try:
|
||||
#query=session.query(tabcls)
|
||||
#for tabkey in tabkeys:
|
||||
# query=query.filter(getattr(tabcls,tabkey) == newdict[tabkey])
|
||||
query.update(newdict)
|
||||
except Exception, e:
|
||||
raise DBException("Error: import object "+key+" is failed: "+str(e))
|
||||
elif delrow == 0:
|
||||
try:
|
||||
session.execute(tabcls.__table__.insert(), newdict)
|
||||
except Exception, e:
|
||||
raise DBException("Error: import object "+key+" is failed: "+str(e))
|
||||
|
||||
class matrixdbfactory():
|
||||
def __init__(self,dbsession):
|
||||
self._dbsession=dbsession
|
||||
|
||||
def gettab(self,tabs,keys=[]):
|
||||
ret={}
|
||||
for tabname in tabs:
|
||||
dbsession=self._dbsession.loadSession(tabname);
|
||||
if hasattr(dbobject,tabname):
|
||||
tab=getattr(dbobject,tabname)
|
||||
else:
|
||||
continue
|
||||
tabobjs=[]
|
||||
tabkeys=tab.primkeys()
|
||||
if not keys or len(keys)==0:
|
||||
tabobjs=dbsession.query(tab).filter(or_(tab.disable == None, tab.disable.notin_(['1','yes']))).all()
|
||||
elif len(tabkeys)==1:
|
||||
tabobjs = dbsession.query(tab).filter(getattr(tab, tabkeys[0]).in_(keys),
|
||||
or_(tab.disable == None, tab.disable.notin_(['1', 'yes']))).all()
|
||||
elif len(tabkeys)>1:
|
||||
for key in keys:
|
||||
if type(key)!=tuple:
|
||||
key=[key]
|
||||
kvdict=dict(zip(tabkeys,key))
|
||||
query=dbsession.query(tab)
|
||||
for key,value in kvdict.items():
|
||||
query=query.filter(getattr(tab,key).in_([value]))
|
||||
query=query.filter(or_(tab.disable == None, tab.disable.notin_(['1','yes'])))
|
||||
tabobj=query.all()
|
||||
tabobjs.extend(tabobj)
|
||||
if not tabobjs:
|
||||
continue
|
||||
|
||||
objkeyname=tab.getobjkey()
|
||||
dictoftab={}
|
||||
for myobj in tabobjs:
|
||||
mydict=myobj.getdict()
|
||||
|
||||
if len(objkeyname)==1:
|
||||
mykey=mydict[tab.__tablename__+'.'+objkeyname[0]]
|
||||
elif len(objkeyname)>1:
|
||||
mykeylist=[]
|
||||
for key in objkeyname:
|
||||
mykeylist.append(mydict[tab.__tablename__+'.'+key])
|
||||
mykey=tuple(mykeylist)
|
||||
|
||||
if mykey not in dictoftab.keys():
|
||||
dictoftab[mykey]=mydict
|
||||
else:
|
||||
if type(dictoftab[mykey])!=list:
|
||||
dictoftab[mykey]=[dictoftab[mykey]]
|
||||
dictoftab[mykey].append(mydict)
|
||||
|
||||
|
||||
for mykey in dictoftab.keys():
|
||||
if mykey not in ret.keys():
|
||||
ret[mykey]={}
|
||||
if type(dictoftab[mykey])==list:
|
||||
if tabname not in ret[mykey].keys():
|
||||
ret[mykey][tabname]=[]
|
||||
ret[mykey][tabname].extend(dictoftab[mykey])
|
||||
else:
|
||||
ret[mykey].update(dictoftab[mykey])
|
||||
|
||||
for mykey in ret.keys():
|
||||
if len(ret[mykey].keys())==1 and ret[mykey].keys()[0] in tabs :
|
||||
ret[mykey]=ret[mykey][ret[mykey].keys()[0]]
|
||||
|
||||
return ret
|
||||
|
||||
def settab(self,tabdict=None):
|
||||
#print("=========matrixdbfactory:settab========")
|
||||
#print(tabdict)
|
||||
#print("\n")
|
||||
if tabdict is None:
|
||||
return None
|
||||
for key in tabdict.keys():
|
||||
utils.verbose(" writting object: "+str(key),file=sys.stdout)
|
||||
#clear any existing table entries before adding new entries
|
||||
df=dbfactory(self._dbsession)
|
||||
df.cleartab(tabdict[key].keys(),[key])
|
||||
for tab in tabdict[key].keys():
|
||||
dbsession=self._dbsession.loadSession(tab);
|
||||
if hasattr(dbobject,tab):
|
||||
tabcls=getattr(dbobject,tab)
|
||||
else:
|
||||
continue
|
||||
|
||||
for record in tabdict[key][tab]:
|
||||
if tabcls.isValid(key,record):
|
||||
create_or_update(dbsession,tabcls,key,record)
|
||||
|
||||
class flatdbfactory() :
|
||||
def __init__(self,dbsession):
|
||||
self._dbsession=dbsession
|
||||
|
||||
def gettab(self,tabs,keys=None):
|
||||
ret={}
|
||||
if keys:
|
||||
rootkey=keys[0]
|
||||
else:
|
||||
rootkey='clustersite'
|
||||
ret[rootkey]={}
|
||||
for tabname in tabs:
|
||||
dbsession=self._dbsession.loadSession(tabname);
|
||||
if hasattr(dbobject,tabname):
|
||||
tab=getattr(dbobject,tabname)
|
||||
else:
|
||||
continue
|
||||
tabobj=dbsession.query(tab).filter(or_(tab.disable == None,tab.disable.notin_(['1','yes']))).all()
|
||||
if not tabobj:
|
||||
continue
|
||||
for myobj in tabobj:
|
||||
mydict=myobj.getdict()
|
||||
ret[rootkey].update(mydict)
|
||||
return ret
|
||||
|
||||
def settab(self,tabdict=None):
|
||||
#print("======flatdbfactory:settab======")
|
||||
#print(tabdict)
|
||||
if tabdict is None:
|
||||
return None
|
||||
for key in tabdict.keys():
|
||||
for tab in tabdict[key].keys():
|
||||
if hasattr(dbobject,tab):
|
||||
tabcls=getattr(dbobject,tab)
|
||||
else:
|
||||
continue
|
||||
tabkey=tabcls.getobjkey()[0]
|
||||
rowentlist=tabcls.dict2tabentry(tabdict[key][tab][0])
|
||||
dbsession=self._dbsession.loadSession(tab)
|
||||
for rowent in rowentlist:
|
||||
if tabcls.isValid(key, rowent):
|
||||
create_or_update(dbsession,tabcls,rowent[tabkey],rowent,False)
|
||||
|
||||
|
||||
|
||||
class dbfactory():
|
||||
|
||||
def __init__(self,dbsession):
|
||||
self._dbsession=dbsession
|
||||
|
||||
def gettab(self,tabs,keys=None):
|
||||
flattabs=[]
|
||||
matrixtabs=[]
|
||||
mydict={}
|
||||
|
||||
for tab in tabs:
|
||||
if hasattr(dbobject,tab):
|
||||
tabcls=getattr(dbobject,tab)
|
||||
else:
|
||||
continue
|
||||
if tabcls.getTabtype() == 'flat':
|
||||
flattabs.append(tab)
|
||||
else:
|
||||
matrixtabs.append(tab)
|
||||
if flattabs:
|
||||
df_flat=flatdbfactory(self._dbsession)
|
||||
mydict.update(df_flat.gettab(flattabs,keys))
|
||||
if matrixtabs:
|
||||
df_matrix=matrixdbfactory(self._dbsession)
|
||||
mydict.update(df_matrix.gettab(matrixtabs,keys))
|
||||
return mydict
|
||||
|
||||
#convert db dict from format {key:{tab.col=value}} to {key:{tab:{col}}}
|
||||
def __tabtransform(self,dbdict):
|
||||
#print("__tabtransform")
|
||||
#print(dbdict)
|
||||
flattabdict={}
|
||||
matrixtabdict={}
|
||||
|
||||
#try:
|
||||
for key in dbdict.keys():
|
||||
dbentlist=[]
|
||||
rawdbents=dbdict[key]
|
||||
if type(rawdbents)==dict:
|
||||
dbentlist.append(rawdbents)
|
||||
else:
|
||||
dbentlist.extend(rawdbents)
|
||||
|
||||
|
||||
for dbent in dbentlist:
|
||||
#print("@@@@@@@@@@@@")
|
||||
#print(dbent)
|
||||
#print("@@@@@@@@@@@@")
|
||||
rowdict={}
|
||||
for tabcol in dbent.keys():
|
||||
(tab,col)=tabcol.split('.')
|
||||
|
||||
if tab not in rowdict.keys():
|
||||
rowdict[tab]={}
|
||||
if col not in rowdict[tab].keys():
|
||||
rowdict[tab][col]={}
|
||||
rowdict[tab][col]=dbent[tabcol]
|
||||
|
||||
|
||||
for tab in rowdict.keys():
|
||||
if hasattr(dbobject,tab):
|
||||
tabcls=getattr(dbobject,tab)
|
||||
else:
|
||||
continue
|
||||
if tabcls.getTabtype() == 'flat':
|
||||
if key not in flattabdict.keys():
|
||||
flattabdict[key]={}
|
||||
if tab not in flattabdict[key].keys():
|
||||
flattabdict[key][tab]=[]
|
||||
flattabdict[key][tab].append(rowdict[tab])
|
||||
else:
|
||||
if key not in matrixtabdict.keys():
|
||||
matrixtabdict[key]={}
|
||||
if tab not in matrixtabdict[key].keys():
|
||||
matrixtabdict[key][tab]=[]
|
||||
matrixtabdict[key][tab].append(rowdict[tab])
|
||||
return(matrixtabdict,flattabdict)
|
||||
|
||||
|
||||
def settab(self,dbdict=None):
|
||||
if dbdict is None:
|
||||
return None
|
||||
(matrixtabdict,flattabdict)=self.__tabtransform(dbdict)
|
||||
if flattabdict:
|
||||
df_flat=flatdbfactory(self._dbsession)
|
||||
mydict=df_flat.settab(flattabdict)
|
||||
if matrixtabdict:
|
||||
df_matrix=matrixdbfactory(self._dbsession)
|
||||
mydict=df_matrix.settab(matrixtabdict)
|
||||
#except Exception as e:
|
||||
# raise ("Error: import object failed.")
|
||||
#else:
|
||||
# print("import object successfully.")
|
||||
|
||||
def cleartab(self,tabs,objkey=[]):
|
||||
for tab in tabs:
|
||||
if hasattr(dbobject,tab):
|
||||
tabcls=getattr(dbobject,tab)
|
||||
else:
|
||||
continue
|
||||
tabkey=tabcls.getobjkey()[0]
|
||||
ReservedKeys=tabcls.getReservedKeys()
|
||||
dbsession=self._dbsession.loadSession(tab)
|
||||
try:
|
||||
query=dbsession.query(tabcls)
|
||||
query=query.filter(or_(tabcls.disable == None, tabcls.disable.notin_(['1','yes'])))
|
||||
if ReservedKeys:
|
||||
query=query.filter(getattr(tabcls,tabkey).notin_(ReservedKeys))
|
||||
|
||||
if objkey:
|
||||
query=query.filter(getattr(tabcls,tabkey).in_(objkey))
|
||||
query.delete(synchronize_session='fetch')
|
||||
except Exception as e:
|
||||
raise DBException("Error: failed to clear table "+str(tab)+": "+str(e))
|
||||
#else:
|
||||
# print("table "+tab+ "cleared!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
#!/usr/bin/env python
|
||||
###############################################################################
|
||||
# IBM(c) 2019 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
###############################################################################
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from dbsession import *
|
||||
from copy import *
|
||||
from sqlalchemy import inspect
|
||||
import pdb
|
||||
|
||||
class mixin(object):
|
||||
def getdict(self):
|
||||
mydict={}
|
||||
for mykey in self.__dict__.keys():
|
||||
if mykey in self.__table__.columns:
|
||||
mydict[self.__tablename__+'.'+mykey.encode()]= self.__dict__[mykey] if self.__dict__[mykey] is None else self.__dict__[mykey].encode()
|
||||
try:
|
||||
self.__class__.outprocess(mydict)
|
||||
except:
|
||||
pass
|
||||
return mydict
|
||||
|
||||
#return a tuple of table primary keys
|
||||
@classmethod
|
||||
def primkeys(cls):
|
||||
ins = inspect(cls)
|
||||
prikeys=[ item.key for item in ins.primary_key ]
|
||||
prikeys.sort(None,None,reverse=False)
|
||||
return tuple(prikeys)
|
||||
|
||||
#return the key of object in table row
|
||||
@classmethod
|
||||
def getobjkey(cls):
|
||||
return cls.primkeys()
|
||||
|
||||
@classmethod
|
||||
def isValid(cls, netname, tabdict):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def dict2tabentry(self,objdict):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def getcolumns(self):
|
||||
return self.__table__.columns.keys()
|
||||
|
||||
@classmethod
|
||||
def getTabtype(self):
|
||||
return 'matrix'
|
||||
|
||||
@classmethod
|
||||
def getReservedKeys(self):
|
||||
return []
|
||||
########################################################################
|
||||
class passwd(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('passwd')
|
||||
__tablename__ = 'passwd'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
@classmethod
|
||||
def primkeys(cls):
|
||||
return ('key','username')
|
||||
|
||||
@classmethod
|
||||
def getobjkey(cls):
|
||||
return tuple(['key'])
|
||||
|
||||
########################################################################
|
||||
class networks(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('networks')
|
||||
__tablename__ = 'networks'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
@classmethod
|
||||
def primkeys(cls):
|
||||
return tuple(['netname'])
|
||||
@classmethod
|
||||
def getobjkey(cls):
|
||||
return tuple(['netname'])
|
||||
|
||||
@classmethod
|
||||
def isValid(cls, netname, tabdict):
|
||||
eptkey=0
|
||||
if 'net' not in tabdict.keys() or not tabdict['net']:
|
||||
print("Error: net value should not be empty for xCAT network object "+netname)
|
||||
eptkey=1
|
||||
if 'mask' not in tabdict.keys() or not tabdict['mask']:
|
||||
print ("Error: mask value should not be empty for xCAT network object "+netname)
|
||||
eptkey=1
|
||||
if eptkey:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
########################################################################
|
||||
class routes(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('routes')
|
||||
__tablename__ = 'routes'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
|
||||
########################################################################
|
||||
class nodetype(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nodetype')
|
||||
__tablename__ = 'nodetype'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
########################################################################
|
||||
'''
|
||||
class hosts(Base,mixin):
|
||||
""""""
|
||||
__tablename__ = 'hosts'
|
||||
__table_args__ = {'autoload':True}
|
||||
'''
|
||||
########################################################################
|
||||
class noderes(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('noderes')
|
||||
__tablename__ = 'noderes'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
########################################################################
|
||||
class switch(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('switch')
|
||||
__tablename__ = 'switch'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
@classmethod
|
||||
def getobjkey(cls):
|
||||
return tuple(['node'])
|
||||
########################################################################
|
||||
class switches(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('switches')
|
||||
__tablename__ = 'switches'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
|
||||
########################################################################
|
||||
class mac(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('mac')
|
||||
__tablename__ = 'mac'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class hwinv(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('hwinv')
|
||||
__tablename__ = 'hwinv'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class postscripts(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('postscripts')
|
||||
__tablename__ = 'postscripts'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
@classmethod
|
||||
def getReservedKeys(self):
|
||||
return ('xcatdefaults','service')
|
||||
|
||||
########################################################################
|
||||
class bootparams(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('bootparams')
|
||||
__tablename__ = 'bootparams'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
########################################################################
|
||||
class nodelist(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nodelist')
|
||||
__tablename__ = 'nodelist'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
########################################################################
|
||||
class vm(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('vm')
|
||||
__tablename__ = 'vm'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class policy(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('policy')
|
||||
__tablename__ = 'policy'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
########################################################################
|
||||
class nodehm(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nodehm')
|
||||
__tablename__ = 'nodehm'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class nodegroup(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nodegroup')
|
||||
__tablename__ = 'nodegroup'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class vpd(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('vpd')
|
||||
__tablename__ = 'vpd'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class servicenode(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('servicenode')
|
||||
__tablename__ = 'servicenode'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class hosts(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('hosts')
|
||||
__tablename__ = 'hosts'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class nics(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nics')
|
||||
__tablename__ = 'nics'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class openbmc(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('openbmc')
|
||||
__tablename__ = 'openbmc'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class prodkey(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('prodkey')
|
||||
__tablename__ = 'prodkey'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
@classmethod
|
||||
def getobjkey(cls):
|
||||
return tuple(['node'])
|
||||
########################################################################
|
||||
class domain(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('domain')
|
||||
__tablename__ = 'domain'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class chain(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('chain')
|
||||
__tablename__ = 'chain'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class rack(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('rack')
|
||||
__tablename__ = 'rack'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class nodepos(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nodepos')
|
||||
__tablename__ = 'nodepos'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class ppc(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('ppc')
|
||||
__tablename__ = 'ppc'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class ppchcp(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('ppchcp')
|
||||
__tablename__ = 'ppchcp'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class mp(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('mp')
|
||||
__tablename__ = 'mp'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class zvm(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('zvm')
|
||||
__tablename__ = 'zvm'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class mpa(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('mpa')
|
||||
__tablename__ = 'mpa'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class pdu(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('pdu')
|
||||
__tablename__ = 'pdu'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class pduoutlet(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('pduoutlet')
|
||||
__tablename__ = 'pduoutlet'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class cfgmgt(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('cfgmgt')
|
||||
__tablename__ = 'cfgmgt'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class hypervisor(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('hypervisor')
|
||||
__tablename__ = 'hypervisor'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class iscsi(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('iscsi')
|
||||
__tablename__ = 'iscsi'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class mic(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('mic')
|
||||
__tablename__ = 'mic'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class ppcdirect(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('ppcdirect')
|
||||
__tablename__ = 'ppcdirect'
|
||||
__table_args__ = {'autoload':True}
|
||||
|
||||
@classmethod
|
||||
def primkeys(cls):
|
||||
return tuple(['hcp'])
|
||||
########################################################################
|
||||
class storage(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('storage')
|
||||
__tablename__ = 'storage'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class websrv(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('websrv')
|
||||
__tablename__ = 'websrv'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class prescripts(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('prescripts')
|
||||
__tablename__ = 'prescripts'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class ipmi(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('ipmi')
|
||||
__tablename__ = 'ipmi'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class osimage(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('osimage')
|
||||
__tablename__ = 'osimage'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class linuximage(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('linuximage')
|
||||
__tablename__ = 'linuximage'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class winimage(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('winimage')
|
||||
__tablename__ = 'winimage'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class nimimage(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('nimimage')
|
||||
__tablename__ = 'nimimage'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class zone(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('zone')
|
||||
__tablename__ = 'zone'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class osdistro(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('osdistro')
|
||||
__tablename__ = 'osdistro'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
class site(Base,mixin):
|
||||
""""""
|
||||
Base.metadata.bind = DBsession.getEngine('site')
|
||||
__tablename__ = 'site'
|
||||
__table_args__ = {'autoload':True}
|
||||
########################################################################
|
||||
def getdict(self):
|
||||
mydict={}
|
||||
mykey=self.__dict__['key']
|
||||
mydict[self.__tablename__+'.'+mykey]=mykey=self.__dict__['value']
|
||||
return mydict
|
||||
|
||||
@classmethod
|
||||
def dict2tabentry(self,objdict):
|
||||
mydict={}
|
||||
ret=[]
|
||||
for key in objdict.keys():
|
||||
mydict['key']=key
|
||||
mydict['value']=objdict[key]
|
||||
mydict['disable']=None
|
||||
ret.append(deepcopy(mydict))
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def getTabtype(self):
|
||||
return 'flat'
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def query_table_by_node(session, tclass, tkey):
|
||||
""""""
|
||||
result=session.query(tclass).filter(tclass.node == tkey).all()
|
||||
if not result:
|
||||
return None
|
||||
return result[0].getdict()
|
||||
|
||||
|
||||
def query_nodelist_by_key(session, nodelist):
|
||||
""""""
|
||||
nodelist_value = {}
|
||||
for node in nodelist:
|
||||
nodelist_value[node]={}
|
||||
classlist = [Bootparams,Nodetype,Hosts,Switch,Mac,Noderes]
|
||||
for eachclass in classlist:
|
||||
clsdict = query_table_by_node(session,eachclass,node)
|
||||
nodelist_value[node].update(clsdict)
|
||||
return nodelist_value
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python
|
||||
###############################################################################
|
||||
# IBM(c) 2019 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
###############################################################################
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from sqlalchemy import create_engine,inspect
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
import re
|
||||
import os
|
||||
import sqlalchemy.exc
|
||||
from exceptions import *
|
||||
import codecs
|
||||
|
||||
codecs.register(lambda name: codecs.lookup('utf8') if name == 'utf8mb4' else None)
|
||||
|
||||
Base = declarative_base()
|
||||
Base.metadata.bind = None;
|
||||
|
||||
|
||||
class Singleton(object):
|
||||
def __new__(cls,*args,**kwargs):
|
||||
if not hasattr(cls,'_inst'):
|
||||
cls._inst=super(Singleton,cls).__new__(cls,*args,**kwargs)
|
||||
return cls._inst
|
||||
|
||||
class DBsession(Singleton):
|
||||
_dbcfgpath='/etc/xcat/cfgloc'
|
||||
_dbcfgregex=re.compile("^(\S+):dbname=(\S+);host=(\S+)\|(\S+)\|(\S*)$")
|
||||
|
||||
def __init__(self):
|
||||
self._sessions={}
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
#check whether the backend db is sqlite
|
||||
@classmethod
|
||||
def isSqlite(cls):
|
||||
if os.path.exists(cls._dbcfgpath):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
#create DB engine according to the xcat cfgloc file
|
||||
@classmethod
|
||||
def createEngine(cls,tablename=None):
|
||||
if not cls.isSqlite():
|
||||
dbcfgfile = open(cls._dbcfgpath)
|
||||
dbcfgloc = dbcfgfile.read( )
|
||||
dbcfgfile.close()
|
||||
try:
|
||||
(dbtype,dbname,dbhost,dbusername,dbpasswd)=re.findall(cls._dbcfgregex,dbcfgloc)[0]
|
||||
except:
|
||||
raise BadDBHdlException("Error: invalid cfgloc file: %(o)s", o=cls._dbcfgpath)
|
||||
if dbtype == 'Pg':
|
||||
conn="postgresql+psycopg2://"
|
||||
elif dbtype == 'mysql':
|
||||
conn="mysql+pymysql://"
|
||||
engine_value = conn+dbusername+':'+dbpasswd+'@'+dbhost+'/'+dbname
|
||||
elif tablename:
|
||||
engine_value = 'sqlite:////etc/xcat/'+tablename+'.sqlite'
|
||||
else:
|
||||
raise BadDBHdlException("Error: table name not specified!")
|
||||
engine=create_engine(engine_value, echo=False)
|
||||
return engine
|
||||
|
||||
@classmethod
|
||||
def getEngine(cls,tablename=None):
|
||||
""""""
|
||||
if not cls.isSqlite():
|
||||
if not Base.metadata.bind:
|
||||
engine=cls.createEngine()
|
||||
else:
|
||||
return Base.metadata.bind
|
||||
elif tablename:
|
||||
engine=cls.createEngine(tablename)
|
||||
return engine
|
||||
|
||||
#bind Base.metadata to db engine
|
||||
@classmethod
|
||||
def createSession(cls,tablename=None):
|
||||
""""""
|
||||
engine=cls.getEngine(tablename)
|
||||
#metadata = Base.metadata
|
||||
#print metadata.tables.keys()
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
return session
|
||||
|
||||
|
||||
#get db session
|
||||
def loadSession(self,tablename=None):
|
||||
if self.__class__.isSqlite():
|
||||
if tablename not in self._sessions.keys():
|
||||
session=self.__class__.createSession(tablename)
|
||||
if session:
|
||||
self._sessions[tablename]=session
|
||||
return session
|
||||
else:
|
||||
return self._sessions[tablename]
|
||||
else:
|
||||
if self._sessions:
|
||||
mykey=self._sessions.keys()[0]
|
||||
return self._sessions[mykey]
|
||||
else:
|
||||
session=self.__class__.createSession(tablename)
|
||||
self._sessions['_globaldbsession']=session
|
||||
return session
|
||||
|
||||
#commit all the transactions
|
||||
def commit(self):
|
||||
for session in self._sessions.keys():
|
||||
self._sessions[session].commit()
|
||||
#close all sessions
|
||||
def close(self):
|
||||
for session in self._sessions.keys():
|
||||
self._sessions[session].close()
|
||||
del self._sessions[session]
|
||||
|
||||
#for debug: print the self._sessions
|
||||
def dumpsession(self):
|
||||
print(self._sessions)
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
#xcat version string
|
||||
xcat_version=""
|
||||
|
||||
#xcat version number
|
||||
xcat_verno=""
|
||||
|
||||
#xcat service running?
|
||||
isxcatrunning=0
|
||||
|
||||
implicitEnvVars={'OBJNAME':{'description':"the object name to import"},
|
||||
'GITROOT':{'description':"the root path of the git repo where the inventory file resides in"},
|
||||
'GITBRANCH':{'description':"the current git branch name of the inventory file to import"},
|
||||
'GITTAG':{'description':"the current git tag of the inventory file to import"},
|
||||
'GITCOMMIT':{'description':"the current git commit number of the inventory file to import"}}
|
||||
|
||||
#verbose?
|
||||
verbose=False
|
||||
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env python
|
||||
###############################################################################
|
||||
# IBM(c) 2019 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
###############################################################################
|
||||
# -*- coding: utf-8 -*-
|
||||
# common helper subroutines
|
||||
#
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import json
|
||||
import yaml
|
||||
import sys
|
||||
import globalvars
|
||||
from exceptions import *
|
||||
from contextlib import contextmanager
|
||||
|
||||
def runCommand(cmd, env=None):
|
||||
"""
|
||||
Run one command only, when you don't want to bother setting up
|
||||
the Popen stuff.
|
||||
(retcode,out,err)=runCommand('lsxcatd -v')
|
||||
"""
|
||||
try:
|
||||
p = subprocess.Popen(cmd,
|
||||
env=env,
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
except OSError,e:
|
||||
return p.returncode,out, err
|
||||
return p.returncode,out, err
|
||||
|
||||
#remove the dict entries whose value is null or ''
|
||||
def Util_rmnullindict(mydict):
|
||||
for key in mydict.keys():
|
||||
if isinstance(mydict[key],dict):
|
||||
Util_rmnullindict(mydict[key])
|
||||
if not mydict[key].keys():
|
||||
del mydict[key]
|
||||
else:
|
||||
if not mydict[key]:
|
||||
del mydict[key]
|
||||
|
||||
|
||||
# replace the "{{x}}" variables in the value of dict "mydict"
|
||||
# with the values of "vardict[x]"
|
||||
def Util_subvarsindict(mydict,vardict):
|
||||
for key in mydict.keys():
|
||||
if isinstance(mydict[key],dict):
|
||||
Util_subvarsindict(mydict[key],vardict)
|
||||
elif isinstance(mydict[key],list):
|
||||
for idx,val in enumerate(mydict[key]):
|
||||
if isinstance(val,str):
|
||||
mydict[key][idx]=re.sub(r'\{\{(.*)\}\}',lambda m:vardict.get(m.group(1)),val)
|
||||
elif isinstance(mydict[key],str):
|
||||
mydict[key]=re.sub(r'\{\{(.*)\}\}',lambda m:vardict.get(m.group(1)),mydict[key])
|
||||
|
||||
|
||||
# get the dict value mydict[a][b][c] with key path a.b.c
|
||||
def Util_getdictval(mydict,keystr):
|
||||
if not isinstance(mydict,dict):
|
||||
return None
|
||||
dictkeyregex=re.compile("([^\.]+)\.?(\S+)*")
|
||||
result=re.findall(dictkeyregex,keystr)
|
||||
if result:
|
||||
(key,remdkey)=result[0]
|
||||
if key not in mydict.keys():
|
||||
return None
|
||||
if remdkey:
|
||||
return Util_getdictval(mydict[key],remdkey)
|
||||
else:
|
||||
return mydict[key]
|
||||
|
||||
# get the dict value mydict[a][b][c] with key path a.b.c
|
||||
def Util_setdictval(mydict,keystr,value):
|
||||
dictkeyregex=re.compile("([^\.]+)\.?(\S+)*")
|
||||
result=re.findall(dictkeyregex,keystr)
|
||||
if result:
|
||||
(key,remdkey)=result[0]
|
||||
if remdkey:
|
||||
if key not in mydict.keys():
|
||||
mydict[key]={}
|
||||
Util_setdictval(mydict[key],remdkey,value)
|
||||
else:
|
||||
mydict[key]=value
|
||||
|
||||
#remove dict key [a][b][c] with key path a.b.c
|
||||
def Util_deldictkey(mydict,keystr):
|
||||
dictkeyregex=re.compile("([^\.]+)\.?(\S+)*")
|
||||
result=re.findall(dictkeyregex,keystr)
|
||||
if result:
|
||||
(key,remdkey)=result[0]
|
||||
if remdkey:
|
||||
if key not in mydict.keys():
|
||||
mydict[key]={}
|
||||
Util_deldictkey(mydict[key],remdkey)
|
||||
else:
|
||||
del mydict[key]
|
||||
|
||||
|
||||
def loadfile(filename):
|
||||
if not os.path.exists(filename):
|
||||
raise FileNotExistException("Error: File '%s' does not exist, please check..." % filename)
|
||||
|
||||
contents={}
|
||||
fmt = 'json'
|
||||
with open(filename,"r") as fh:
|
||||
f=fh.read()
|
||||
if not f.startswith('{'):
|
||||
fmt = 'yaml'
|
||||
try:
|
||||
contents=json.loads(f)
|
||||
except ValueError:
|
||||
try:
|
||||
contents = yaml.load(f)
|
||||
except Exception,e:
|
||||
raise InvalidFileException("Error: failed to load file \"%s\", please validate the file with 'yamllint %s'(for yaml format) or 'cat %s|python -mjson.tool'(for json format)!"%(filename,filename,filename))
|
||||
return contents, fmt
|
||||
return None, fmt
|
||||
|
||||
#initialize the global vars in globalvars.py
|
||||
def initglobal():
|
||||
if os.path.exists("/var/run/xcatd.pid"):
|
||||
globalvars.isxcatrunning=1
|
||||
else:
|
||||
globalvars.isxcatrunning=0
|
||||
if globalvars.isxcatrunning:
|
||||
(retcode,out,err)=runCommand("XCATBYPASS=0 lsxcatd -v")
|
||||
if retcode!=0 or not globalvars.isxcatrunning:
|
||||
(retcode,out,err)=runCommand("XCATBYPASS=1 lsxcatd -v")
|
||||
if retcode!=0:
|
||||
globalvars.xcat_version=""
|
||||
globalvars.xcat_verno=""
|
||||
else:
|
||||
globalvars.xcat_version=out.strip()
|
||||
globalvars.xcat_verno=globalvars.xcat_version.split(' ')[1]
|
||||
|
||||
# if "key" of d1 or "key" of d1[key] not in d2, delete it
|
||||
def filter_dict_keys(d1, d2):
|
||||
tmp_d1 = d1
|
||||
for key in tmp_d1.keys():
|
||||
if key not in d2:
|
||||
del tmp_d1[key]
|
||||
continue
|
||||
if type(tmp_d1[key]) != dict:
|
||||
continue
|
||||
for subkey in tmp_d1[key].keys():
|
||||
if subkey not in d2[key]:
|
||||
del tmp_d1[key][subkey]
|
||||
return tmp_d1
|
||||
|
||||
#print if -v|--verbose specified
|
||||
def verbose(message,file=sys.stdout):
|
||||
if globalvars.verbose:
|
||||
print("%s"%(message),file=file)
|
||||
|
||||
#get home directory of the current user
|
||||
def gethome():
|
||||
home = os.path.expanduser("~")
|
||||
return home
|
||||
|
||||
#strip single and double quotes from string
|
||||
def stripquotes(instring):
|
||||
return instring.strip('"').strip("'")
|
||||
|
||||
#redirect stdout to stream
|
||||
@contextmanager
|
||||
def stdout_redirector(stream):
|
||||
old_stdout = sys.stdout
|
||||
sys.stdout = stream
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.stdout = old_stdout
|
||||
|
||||
#redirect stderr to stream
|
||||
@contextmanager
|
||||
def stderr_redirector(stream):
|
||||
old_stderr = sys.stderr
|
||||
sys.stderr = stream
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.stderr = old_stderr
|
||||
|
||||
|
||||
|
||||
#traverse the inventory object directory and get the object type and object names
|
||||
def traverseobjdir(path):
|
||||
if not os.path.isdir(path):
|
||||
return None
|
||||
ret={}
|
||||
from manager import InventoryFactory
|
||||
for subdir in os.listdir(path):
|
||||
objpath=os.path.join(path,subdir)
|
||||
if os.path.isdir(objpath):
|
||||
if os.path.isfile(os.path.join(objpath,'definition.yaml')):
|
||||
objfile=os.path.join(objpath,'definition.yaml')
|
||||
with open(objfile, 'r') as stream:
|
||||
try:
|
||||
obj_attr_dict = yaml.load(stream)
|
||||
except:
|
||||
continue
|
||||
elif os.path.isfile(os.path.join(objpath,'definition.json')):
|
||||
objfile=os.path.join(objpath,'definition.json')
|
||||
with open(objfile, 'r') as stream:
|
||||
string=stream.read()
|
||||
try:
|
||||
obj_attr_dict = json.loads(string)
|
||||
except:
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
objtypes=list(set(obj_attr_dict.keys()) & set(InventoryFactory.getvalidobjtypes(ignorepartial=1)))
|
||||
if objtypes and len(objtypes)==1:
|
||||
objtype=objtypes[0]
|
||||
if objtype not in ret.keys():
|
||||
ret[objtype]=[subdir]
|
||||
else:
|
||||
ret[objtype].append(subdir)
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python
|
||||
###############################################################################
|
||||
# IBM(c) 2019 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
###############################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import confluent.log as log
|
||||
from functools import wraps
|
||||
from .dbsession import DBsession
|
||||
from .dbfactory import dbfactory
|
||||
from .attributes import conattr2xcatattr
|
||||
xcat_dbi=None
|
||||
data_store=None
|
||||
xcfm_logger=None
|
||||
def xcat_manager_decorator(function):
|
||||
@wraps(function)
|
||||
def decorator(*args, **kwargs):
|
||||
xcfm_logger.log("In xCAT configManager: run " + function.__name__)
|
||||
return function(*args, **kwargs)
|
||||
return decorator
|
||||
|
||||
class xCATConfigManager(object):
|
||||
global data_store
|
||||
data_store={}
|
||||
data_store['nodes']={}
|
||||
data_store['nodegroup']=[]
|
||||
|
||||
def __init__(self):
|
||||
global xcat_dbi
|
||||
if xcat_dbi is None:
|
||||
dbsession = DBsession()
|
||||
xcat_dbi = dbfactory(dbsession)
|
||||
global xcfm_logger
|
||||
if xcfm_logger is None:
|
||||
xcfm_logger = log.Logger("xcat_manager")
|
||||
xcfm_logger.log("Init xCAT configManager")
|
||||
self.decrypt = False
|
||||
self.current_user = 'xcat'
|
||||
self.tenant = None
|
||||
self._list_nodes()
|
||||
self._list_nodegroup()
|
||||
def _get_data_from_db(self):
|
||||
try:
|
||||
nodelist_set = xcat_dbi.gettab(['nodelist'])
|
||||
nodelist = nodelist_set.keys()
|
||||
except KeyError:
|
||||
data_store['nodes'] = {}
|
||||
return
|
||||
attrs_dict = conattr2xcatattr('*')
|
||||
xcat_dbs=attrs_dict.values()
|
||||
db_hash = {}
|
||||
for e in xcat_dbs:
|
||||
if e is None:
|
||||
continue
|
||||
elif isinstance(e, list):
|
||||
continue
|
||||
else:
|
||||
t,p,c=e.rpartition('.')
|
||||
if t in db_hash:
|
||||
db_hash[t].append(c)
|
||||
else:
|
||||
db_hash[t]=[c]
|
||||
dataset = xcat_dbi.gettab(db_hash.keys())
|
||||
for node in nodelist:
|
||||
nodeinfo = {}
|
||||
for attr in attrs_dict.keys():
|
||||
self.log("The attr:" + attr)
|
||||
nodeinfo[attr] = {}
|
||||
if attrs_dict[attr] is None:
|
||||
nodeinfo[attr]['value'] = None
|
||||
elif isinstance(attrs_dict[attr], list):
|
||||
nodeinfo[attr]['value'] = attrs_dict[attr]
|
||||
elif attrs_dict[attr] in dataset[node]:
|
||||
nodeinfo[attr]['value'] = dataset[node][attrs_dict[attr]]
|
||||
else:
|
||||
nodeinfo[attr]['value'] = attrs_dict[attr]
|
||||
data_store['nodes'][node] = nodeinfo
|
||||
|
||||
def _list_nodes(self):
|
||||
self._get_data_from_db()
|
||||
|
||||
def _list_nodegroup(self):
|
||||
try:
|
||||
dataset = xcat_dbi.gettab(['nodegroup'])
|
||||
data_store['nodegroup'] = dataset.keys()
|
||||
except KeyError:
|
||||
data_store['nodegroup'] = []
|
||||
@xcat_manager_decorator
|
||||
def list_nodes(self):
|
||||
try:
|
||||
dataset = xcat_dbi.gettab(['nodelist', 'nodegroup'])
|
||||
return iter(dataset.keys())
|
||||
except KeyError:
|
||||
return []
|
||||
@xcat_manager_decorator
|
||||
def get_groups(self, sizesort=False):
|
||||
if len(data_store['nodegroup']) == 0:
|
||||
self._list_nodegroup()
|
||||
return data_store['nodegroup']
|
||||
@xcat_manager_decorator
|
||||
def is_node(self, node):
|
||||
return node in data_store['nodes'].keys()
|
||||
|
||||
@xcat_manager_decorator
|
||||
def is_nodegroup(self, nodegroup):
|
||||
return nodegroup in data_store['nodegroup']
|
||||
|
||||
@xcat_manager_decorator
|
||||
def check_quorum(self):
|
||||
pass
|
||||
@xcat_manager_decorator
|
||||
def get_node_attributes(self, nodelist, attributes=(), decrypt=None):
|
||||
ret_dict = {}
|
||||
if '*' in nodelist:
|
||||
nodelist = data_store['nodes'].keys()
|
||||
if len(nodelist) == 0:
|
||||
return None
|
||||
if len(set(nodelist) - set(data_store['nodes'].keys())):
|
||||
self._get_data_from_db()
|
||||
if '*' in attributes or attributes == ():
|
||||
for node in nodelist:
|
||||
ret_dict[node] = data_store['nodes'][node]
|
||||
self.log(self.__class__.__name__ + "==> get all attributes for: " + str(nodelist))
|
||||
self.log(str(ret_dict))
|
||||
return ret_dict
|
||||
self.log(self.__class__.__name__ + "==> get attributes:" + str(attributes) + "for: " + str(nodelist))
|
||||
for node in nodelist:
|
||||
nodeinfo = {}
|
||||
for attr in attributes:
|
||||
nodeinfo[attr] = data_store['nodes'][node][attr]
|
||||
ret_dict[node] = nodeinfo
|
||||
return ret_dict
|
||||
@xcat_manager_decorator
|
||||
def get_collective_member(self, name):
|
||||
return None
|
||||
#return get_collective_member(name)
|
||||
@xcat_manager_decorator
|
||||
def watch_attributes(self, nodes, attributes, callback):
|
||||
pass
|
||||
|
||||
def log(self, logmsg):
|
||||
xcfm_logger.log(logmsg)
|
||||
if __name__ == '__main__':
|
||||
xcfm = xCATConfigManager()
|
||||
xcfm.get_node_attributes()
|
||||
@@ -16,6 +16,7 @@ setup(
|
||||
'confluent/plugins/hardwaremanagement/',
|
||||
'confluent/plugins/shell/',
|
||||
'confluent/collective/',
|
||||
'confluent/xcclient/',
|
||||
'confluent/plugins/configuration/'],
|
||||
install_requires=['paramiko', 'pycrypto>=2.6', 'confluent_client>=0.1.0', 'eventlet',
|
||||
'dnspython', 'netifaces', 'pyte', 'pysnmp', 'pyparsing',
|
||||
|
||||
Reference in New Issue
Block a user