mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-08-09 21:10:15 +00:00
rewrite validatehelper with python to process complex scenario
This commit is contained in:
@@ -1,191 +1,251 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/python
|
||||
from __future__ import print_function
|
||||
|
||||
objtype=$1
|
||||
objname=$2
|
||||
attribute=$3
|
||||
attrvalue=$4
|
||||
tmpdir=$5
|
||||
import yaml
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
#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]
|
||||
|
||||
|
||||
function usage {
|
||||
echo "Usage:"
|
||||
echo "${BASH_SOURCE[0]} [ OBJTYPE OBJNAME ATTRIBUTE ATTRVALUE TMPDIR]"
|
||||
}
|
||||
# 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]
|
||||
|
||||
echo objtype=\"${objtype}\"
|
||||
echo objname=\"${objname}\"
|
||||
echo attribute=\"${attribute}\"
|
||||
echo attrvalue=\"${attrvalue}\"
|
||||
echo tmpdir=\"${tmpdir}\"
|
||||
# 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)
|
||||
if isinstance(myvalue,list):
|
||||
myvalue=myvalue[0]
|
||||
return myvalue
|
||||
|
||||
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)
|
||||
if isinstance(origobjdict,list) and not isinstance(value,list):
|
||||
newvalue=[value]
|
||||
else:
|
||||
newvalue=value
|
||||
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")
|
||||
|
||||
|
||||
if [ -z "$objtype" ] || [ -z "$objname" ] || [ -z "$attribute" ] || [ -z "$tmpdir" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
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 myattrvalue != attrvalue:
|
||||
rcyaml=1
|
||||
|
||||
RETCODE_YAML=0
|
||||
RETCODE_JSON=0
|
||||
if rcyaml == 0:
|
||||
print("yaml validation passed\n")
|
||||
else:
|
||||
print("yaml validation failed\n")
|
||||
|
||||
[ -e "$tmpdir" ] || rm -rf $tmpdir
|
||||
mkdir -p $tmpdir
|
||||
echo "Temporary directory to hold intermediate files: $tmpdir"
|
||||
removeobj(objtype,objname)
|
||||
|
||||
cp ${DIR}/templates/${objtype}.json ${tmpdir}/
|
||||
cp ${DIR}/templates/${objtype}.yaml ${tmpdir}/
|
||||
|
||||
#the intermediate inventory files to import
|
||||
yamldef="${tmpdir}/${objtype}.yaml"
|
||||
jsondef="${tmpdir}/${objtype}.json"
|
||||
|
||||
#the intermediate inventory files exported
|
||||
yamldefout="${tmpdir}/${objtype}.out.yaml"
|
||||
jsondefout="${tmpdir}/${objtype}.out.json"
|
||||
|
||||
echo "removing existing \"$objtype\" type object \"$objname\" from xCAT"
|
||||
echo "osimage node network site route zone policy "|grep -q -w "$objtype"
|
||||
if [ $? -eq 0 ];then
|
||||
rmdef -t $objtype -o $objname
|
||||
fi
|
||||
if [ "$objtype" = "passwd" ];then
|
||||
tabch -d key=$objname passwd
|
||||
fi
|
||||
|
||||
#substitute the attribute value in inventory files
|
||||
if [ ${#attrvalue} -ne 0 ];then
|
||||
sed -i -E -e "s/^(\s*["'"'"']?$attribute["'"'"']?:\s*["'"'"']?)[^'"'"'"]*(["'"'"']?[,]?\s*)$/\1$attrvalue\2/g" $yamldef
|
||||
else
|
||||
sed -i -e "/^\s*["'"'"']*$attribute["'"'"']*:/d" $yamldef
|
||||
fi
|
||||
|
||||
echo "=================the inventory file to import: ${yamldef}====================="
|
||||
cat $yamldef
|
||||
echo "=============================================================================="
|
||||
UpdateAttrInFile(jsondef,'json',objtype,objname,attribute,attrvalue)
|
||||
print("=================the inventory file to import: "+jsondef+"=====================\n")
|
||||
runCommand("cat "+jsondef)
|
||||
print("===============================================================================\n")
|
||||
|
||||
|
||||
echo "import the inventory file $yamldef "
|
||||
xcat-inventory import -t $objtype -o $objname -f $yamldef
|
||||
if [ $? -ne 0 ];then
|
||||
echo "failed to import the inventory file $yamldef"
|
||||
RETCODE_YAML=1
|
||||
else
|
||||
echo "the inventory file $yamldef imported successfully"
|
||||
echo "export the \"$objtype\" type object \"$objname\" just imported"
|
||||
xcat-inventory export -t $objtype -o $objname --format=yaml 1>$yamldefout
|
||||
if [ $? -ne 0 ];then
|
||||
echo "failed to export the \"$objtype\" type object \"$objname\""
|
||||
RETCODE_YAML=1
|
||||
else
|
||||
echo "the inventory data of the \"$objtype\" type object \"$objname\" exported to $yamldefout"
|
||||
echo "==============the exported inventory file $yamldefout======================"
|
||||
cat $yamldefout
|
||||
echo "==========================================================================="
|
||||
echo "make sure the attribute $attribute is imported and exported successfully"
|
||||
if [ -n "$attrvalue" ]; then
|
||||
cat $yamldefout|grep -w "$attribute"|grep -q -w "$attrvalue"
|
||||
if [ $? -ne 0 ];then
|
||||
RETCODE_YAML=1
|
||||
fi
|
||||
else
|
||||
cat $yamldefout|grep -q -w "$attribute"
|
||||
if [ $? -eq 0 ];then
|
||||
RETCODE_YAML=1
|
||||
fi
|
||||
fi
|
||||
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 myattrvalue != attrvalue:
|
||||
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)
|
||||
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $RETCODE_YAML -eq 0 ]; then
|
||||
echo "yaml validation passed"
|
||||
else
|
||||
echo "yaml validation failed"
|
||||
fi
|
||||
|
||||
echo "removing existing \"$objtype\" type object \"$objname\" from xCAT"
|
||||
echo "osimage node network site route zone policy "|grep -q -w "$objtype"
|
||||
if [ $? -eq 0 ];then
|
||||
rmdef -t $objtype -o $objname
|
||||
fi
|
||||
|
||||
if [ "$objtype" = "passwd" ];then
|
||||
tabch -d key=$objname passwd
|
||||
fi
|
||||
|
||||
|
||||
if [ ${#attrvalue} -ne 0 ];then
|
||||
sed -i -E -e "s/^(\s*["'"'"']?$attribute["'"'"']?:\s*["'"'"']?)[^'"'"'"]*(["'"'"']?[,]?\s*)$/\1$attrvalue\2/g" $jsondef
|
||||
else
|
||||
sed -i -e "/^\s*["'"'"']*$attribute["'"'"']*:/d" $jsondef
|
||||
fi
|
||||
|
||||
echo "=================the inventory file to import: ${jsondef}====================="
|
||||
cat $jsondef
|
||||
echo "=============================================================================="
|
||||
|
||||
echo "import the inventory file $jsondef "
|
||||
xcat-inventory import -t $objtype -o $objname -f $jsondef
|
||||
if [ $? -ne 0 ];then
|
||||
echo "failed to import the inventory file $jsondef"
|
||||
RETCODE_JSON=1
|
||||
else
|
||||
xcat-inventory export -t $objtype -o $objname 1>$jsondefout
|
||||
if [ $? -ne 0 ];then
|
||||
echo "the inventory file $jsondef imported successfully"
|
||||
echo "export the \"$objtype\" type object \"$objname\" just imported"
|
||||
RETCODE_JSON=1
|
||||
else
|
||||
echo "the inventory data of the \"$objtype\" type object \"$objname\" exported to $jsondefout"
|
||||
echo "==============the exported inventory file $jsondefout======================"
|
||||
cat $jsondefout
|
||||
echo "==========================================================================="
|
||||
echo "make sure the attribute $attribute is imported and exported successfully"
|
||||
if [ -n "$attrvalue" ]; then
|
||||
cat $jsondefout|grep -w "$attribute"|grep -q -w "$attrvalue"
|
||||
if [ $? -ne 0 ];then
|
||||
RETCODE_JSON=1
|
||||
fi
|
||||
else
|
||||
cat $jsondefout|grep -q -w "$attribute"
|
||||
if [ $? -eq 0 ];then
|
||||
RETCODE_JSON=1
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $RETCODE_JSON -eq 0 ]; then
|
||||
echo "json validation passed"
|
||||
else
|
||||
echo "json validation failed"
|
||||
fi
|
||||
|
||||
|
||||
echo "osimage node network site route zone policy "|grep -q -w "$objtype"
|
||||
if [ $? -eq 0 ];then
|
||||
rmdef -t $objtype -o $objname
|
||||
fi
|
||||
|
||||
if [ "$objtype" = "passwd" ];then
|
||||
tabch -d key=$objname passwd
|
||||
fi
|
||||
|
||||
echo "remove intermediate directory $tmpdir"
|
||||
[ -e "$tmpdir" ] || rm -rf $tmpdir
|
||||
|
||||
if [ $RETCODE_YAML -ne 0 ] || [ $RETCODE_JSON -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
Reference in New Issue
Block a user