#!/usr/bin/python from __future__ import print_function import yaml import json import os import re import sys import shutil import subprocess #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] # 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 def GetAttrInFile(fpath,objtype,objname,attrpath): f=open(fpath,'r') try: objdict=json.loads(f) except TypeError,ValueError: try: objdict=yaml.load(f) except Exception,e: raise Exception("Error: cannot open file "+fpath+"! "+str(e)) f.close() myattrpath=objtype+"."+objname+"."+attrpath myvalue=Util_getdictval(objdict,myattrpath) return myvalue def compattr(exptattr,rawattr): if isinstance(exptattr,list) and re.match(r'^\[.*\]$',rawattr): rawattr=eval(rawattr) if isinstance(rawattr,str): if rawattr in exptattr: return 0 else: return 1 else: return cmp(exptattr,rawattr) def runCommand(cmd, env=None): """ Run one command only, when you don't want to bother setting up the Popen stuff. """ print('Running command: %s' %cmd) try: p = subprocess.Popen(cmd, env=env, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) out, err = p.communicate() except OSError,e: print('RunCommand failed due to OSError %s' % e) if p.returncode: print('Command %s failed with return code %d : %s' % (cmd , p.returncode, err)) print(out) print(err) return p.returncode def UpdateAttrInFile(fpath,fformat,objtype,objname,attrpath,value): f=open(fpath,'r') try: objdict=json.loads(f) except TypeError,ValueError: try: objdict=yaml.load(f) except Exception,e: raise Exception("Error: cannot open file "+fpath+"! "+str(e)) f.close() myattrpath=objtype+"."+objname+"."+attrpath if value == "": Util_setdictval(objdict,myattrpath,"") Util_rmnullindict(objdict) else: origobjdict=Util_getdictval(objdict,myattrpath) origattrtype=type(origobjdict) newvalue=value if origattrtype == list and re.match(r'^\[.*\]$',value): #import pdb #pdb.set_trace() newvalue=eval(value) if isinstance(origobjdict,list) and isinstance(newvalue,str): newvalue=[newvalue] Util_setdictval(objdict,myattrpath,newvalue) f=open(fpath,'w') if fformat == "yaml": print(yaml.dump(objdict,default_flow_style=False),file=f) elif fformat == "json": print(json.dumps(objdict, sort_keys=True, indent=4, separators=(',', ': ')),file=f) f.close() def removeobj(objtype,objname): print("removing existing \""+objtype+"\" type object \""+objname+"\" from xCAT\n") if str(objtype) in ('node','osimage','network','site','route','zone','policy'): runCommand("rmdef -t "+objtype+" -o "+objname) elif str(objtype) in ('passwd'): runCommand("tabch -d key="+objname+" passwd") def Usage(): print("Usage:\n") print(sys.argv[0]+" [OBJTYPE OBJNAME ATTRIBUTE ATTRVALUE TMPDIR]") if len(sys.argv) < 6: Usage() exit(1) objtype=str(sys.argv[1]) objname=str(sys.argv[2]) attribute=str(sys.argv[3]) attrvalue=str(sys.argv[4]) tmpdir=str(sys.argv[5]) print("objtype=%s\nobjname=%s\nattribute=%s\nattrvalue=%s\ntmpdir=%s\n"%(objtype,objname,attribute,attrvalue,tmpdir)) if os.path.exists(tmpdir): runCommand("rm -rf "+tmpdir) os.mkdir(tmpdir) print("Temporary directory to hold intermediate files: "+tmpdir+"\n") curdir=os.path.split(os.path.realpath(sys.argv[0]))[0] yamldeftmpl=curdir+"/templates/"+objtype+'.yaml' jsondeftmpl=curdir+"/templates/"+objtype+'.json' yamldef=tmpdir+"/"+objtype+'.yaml' jsondef=tmpdir+"/"+objtype+'.json' yamldefout=tmpdir+"/"+objtype+'.out.yaml' jsondefout=tmpdir+"/"+objtype+'.out.json' shutil.copyfile(yamldeftmpl,yamldef) shutil.copyfile(jsondeftmpl,jsondef) rcfinal=0 rcyaml=0 rcjson=0 rc=0 UpdateAttrInFile(yamldef,'yaml',objtype,objname,attribute,attrvalue) print("=================the inventory file to import: "+yamldef+"=====================\n") runCommand("cat "+yamldef) print("===============================================================================\n") print("import the inventory file "+yamldef+"\n") rc=runCommand("xcat-inventory import -t "+objtype+" -o "+objname+" -f "+yamldef) if rc !=0: print("failed to import the inventory file "+yamldef) rcyaml=1 else: print("the inventory file "+yamldef+" imported successfully\n") print("export the \""+objtype+"\" type object \""+objname+"\" just imported\n") rc=runCommand("xcat-inventory export -t "+objtype+" -o "+objname+" --format=yaml 1>"+yamldefout) if rc!=0: print("failed to export the \""+objtype+"\" type object \""+objname+"\"\n") rcyaml=1 else: print("==============the exported inventory file "+yamldefout+"======================\n") runCommand("cat "+yamldefout) print("===========================================================================\n") myattrvalue=GetAttrInFile(yamldefout,objtype,objname,attribute) if attrvalue == '': if myattrvalue is not None: rcyaml=1 else: if compattr(myattrvalue,attrvalue) != 0 : rcyaml=1 if rcyaml == 0: print("yaml validation passed\n") else: print("yaml validation failed\n") removeobj(objtype,objname) UpdateAttrInFile(jsondef,'json',objtype,objname,attribute,attrvalue) print("=================the inventory file to import: "+jsondef+"=====================\n") runCommand("cat "+jsondef) print("===============================================================================\n") print("import the inventory file "+jsondef+"\n") rc=runCommand("xcat-inventory import -t "+objtype+" -o "+objname+" -f "+jsondef) print("rc="+str(rc)) if rc !=0: print("failed to import the inventory file "+jsondef) rcjson=1 else: print("the inventory file "+jsondef+" imported successfully\n") print("export the \""+objtype+"\" type object \""+objname+"\" just imported\n") rc=runCommand("xcat-inventory export -t "+objtype+" -o "+objname+" --format=json 1>"+jsondefout) if rc!=0: print("failed to export the \""+objtype+"\" type object \""+objname+"\"\n") rcjson=1 else: print("==============the exported inventory file "+jsondefout+"======================\n") runCommand("cat "+jsondefout) print("===========================================================================\n") myattrvalue=GetAttrInFile(jsondefout,objtype,objname,attribute) if attrvalue == '': if myattrvalue is not None: rcjson=1 else: if compattr(myattrvalue,attrvalue) != 0 : rcjson=1 if rcjson ==0: print("json validation passed\n") else: print("json validation failed\n") removeobj(objtype,objname) if rcjson !=0 or rcyaml!=0: rcfinal=1 print("remove intermediate directory "+tmpdir) if os.path.exists(tmpdir): runCommand("rm -rf "+tmpdir) exit(rcfinal)