2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-29 16:50:57 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
zhaoertao 5702f7372b Have nodes/ipminode/power/state work for xcat node 2019-02-22 22:10:35 -05:00
zhaoertao f9e2f2e656 Map xcat node object to confluent node model 2019-02-22 02:53:49 -05:00
ertaozh 1dcca5d3eb Update Shebang and copyright year 2019-02-20 13:58:58 +08:00
zhaoertao 0845a914c6 Add url /xcat to retrieve nodes from xCAT db 2019-02-14 21:58:23 -05:00
15 changed files with 1466 additions and 5 deletions
+4 -1
View File
@@ -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
+11 -1
View File
@@ -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
+7 -1
View File
@@ -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:
+6 -2
View File
@@ -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)
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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()
+1
View File
@@ -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',