Skip to content

Instantly share code, notes, and snippets.

@soyo42
Last active October 2, 2015 15:24
Show Gist options
  • Save soyo42/285aa8d63f3960e186e3 to your computer and use it in GitHub Desktop.
Save soyo42/285aa8d63f3960e186e3 to your computer and use it in GitHub Desktop.
config subsystem required capabilities pairing
karaf-etc-coss
karaf-system
META-INF
= Pair used namespaces to capabilities =
Colect namespaces used in given config subsystem file and then pair it to yang model. Result is list of namespace+module+revision coordinates suitable for required-capabilities of given config.
== Quick start ==
ln -s <controller distribution root>/etc/opendaylight/karaf karaf-etc-coss
ln -s <controller distribution root>system karaf-system
# first run - need to unzip all yangs into META-INF folder and then pair
./pairNsToYang.sh karaf-system karaf-etc-coss/<examined config file>
# subsequent run - just pairing
./pairNsToYang.sh karaf-system karaf-etc-coss/<examined config file> -
== Result ==
Output contains:
* found namespaces (green)
* MISSING yang info (red)
* DUPLICATE yang modules - differing in revision or module (yellow)
* stats info (total amounts)
* pairing result - telling amounts in order to track duplicate hits
* directly usable (copy+paste) capabilities list without duplicated
== Known bugs ==
* can not handle duplicates
* reading of yang files might fail if extra spaces are used in formatting
or if namespace/revision is written on more than 2 consequent lines
#!/bin/bash
if [ -z "$2" ]; then
echo "usage:: $0 <karaf-system root> <coss-file to be paired>"
exit 1
fi
if [[ -z "$3" ]]; then
echo 'unzipping yangs'
find -L "$1" -type f -name '*.jar' | while read i; do
#echo "$i"
unzip $i *yang
done
fi
./processCoss.py "$2" META-INF/yang
#!/usr/bin/python
import sys
import re
import os
if len(sys.argv) != 3:
sys.stderr.write('usage:: {0} <coss file> <yangs root folder>\n'.format(sys.argv[0]))
sys.exit(1)
cossNsRe = re.compile('\sxmlns:([^=]+)="([^"]+)"')
yangNsRe = re.compile('^\s*namespace "([^"]+)";')
yangRevRe = re.compile('^\s*revision "?([^ "]+)"?')
yangModuleRe = re.compile('^module ([^ }]+) *\{')
def dig_ns_module_rev(yang_input):
with open(yang_input, 'r') as yangContent:
namespace = None
revision = None
module = None
prev_line = None
for line1 in yangContent:
stripped_line = line1.strip()
if prev_line is None:
prev_line = stripped_line
continue
double_line = ' '.join((prev_line, stripped_line))
if module is None:
mach1 = yangModuleRe.match(double_line)
if mach1: module = mach1.group(1)
if namespace is None:
mach1 = yangNsRe.match(double_line)
if mach1: namespace = mach1.group(1)
if revision is None:
mach1 = yangRevRe.search(double_line)
if mach1: revision = mach1.group(1)
if namespace and revision and module:
break
prev_line = stripped_line
if not namespace or not revision or not module:
sys.stderr.write('\033[31mMISSING: {0}\033[0m: {1} | {2} | {3}\n'
.format(yang_input, namespace, module, revision))
return namespace, module, revision
# collect namespace candidates for required capabilities
candidates = []
with open(sys.argv[1], 'r') as cossFile:
idx = 0
for line in cossFile:
mach = cossNsRe.search(line)
if mach:
sys.stdout.write('{2:2d} prefix={0:18s} -> \033[32m{1}\033[0m\n'.format(mach.group(1), mach.group(2), idx))
candidates.append(mach.group(2))
idx += 1
# collect available namespaces + module/revision
availableNSs = {}
for (dirpath, dirnames, filenames) in os.walk(sys.argv[2]):
for yangFile in filenames:
# print(yangFile)
nsModRev = dig_ns_module_rev(os.path.join(dirpath, yangFile))
if nsModRev[0] not in availableNSs:
availableNSs[nsModRev[0]] = []
else:
sys.stderr.write('\033[33;1mDUPLICATE: {0}\033[0m: {1} in {2}\n'
.format(nsModRev[0], (nsModRev[1:3]), availableNSs[nsModRev[0]]))
availableNSs[nsModRev[0]].append((nsModRev[1:3]))
print('ns to pair: {0}'.format(len(candidates)))
print('ns available:{0}'.format(len(availableNSs)))
# for (ns, rev) in availableNSs.iteritems():
# print('[{0}] -> {1}'.format(ns, rev))
# PAIRING
paired_capabilities = set()
for alienIdx in range(len(candidates)):
ns = candidates[alienIdx]
if ns in availableNSs:
resolved = availableNSs[ns]
alert = str(len(resolved)) if len(resolved) > 1 else ' '
capability = '<capability>{0}?module={1}&amp;revision={2}</capability>'\
.format(ns, resolved[0][0],resolved[0][1])
paired_capabilities.add(capability)
print('{0:2d} [\033[36m{1}\033[0m] -> {2}'.format(alienIdx, len(resolved), resolved[0][0]))
for capability in paired_capabilities:
print(capability)
print('done')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment