Source code for jnpr.junos.facts.swver

import re


[docs]class version_info(object):
[docs] def __init__(self, verstr): """verstr - version string""" m1 = re.match('(.*?)([RBIXSF-])(.*)', verstr) self.type = m1.group(2) self.major = tuple(map(int, m1.group(1).split('.'))) # creates tuyple after_type = m1.group(3).split('.') self.minor = after_type[0] if 'X' == self.type: # assumes form similar to "45-D10", so extract the bits from this xm = re.match("(\d+)-(\w)(\d+)", self.minor) if xm is not None: self.minor = tuple( [int(xm.group(1)), xm.group(2), int(xm.group(3))]) if len(after_type) < 2: self.build = None else: self.build = int(after_type[1]) # X type not hyphen format, perhaps "11.4X12.1", just extract build rev or set None else: if len(after_type) < 2: self.build = None else: self.build = int(after_type[1]) elif ('I' == self.type) or ('-' == self.type): self.type = 'I' try: # assumes that we have a build/spin, but not numeric self.build = after_type[1] except: self.build = None else: try: self.build = int(after_type[1]) # assumes numeric build/spin except: self.build = after_type[0] # non-numeric self.as_tuple = self.major + tuple([self.minor, self.build]) self.v_dict = {'major': self.major, 'type': self.type, 'minor': self.minor, 'build': self.build}
def __iter__(self): for key in self.v_dict: yield key, self.v_dict[key] def __repr__(self): retstr = "junos.version_info(major={major}, type={type}," \ " minor={minor}, build={build})".format( major=self.major, type=self.type, minor=self.minor, build=self.build ) return retstr def _cmp_tuple(self, other): bylen = { 2: (self.as_tuple[0:2]), 4: self.as_tuple } return bylen[len(other)] def __lt__(self, other): return self._cmp_tuple(other) < other def __le__(self, other): return self._cmp_tuple(other) <= other def __gt__(self, other): return self._cmp_tuple(other) > other def __ge__(self, other): return self._cmp_tuple(other) >= other def __eq__(self, other): return self._cmp_tuple(other) == other def __ne__(self, other): return self._cmp_tuple(other) != other
def _get_swver(dev, facts): # See if we're VC Capable if facts['vc_capable'] is True: try: return dev.rpc.cli("show version all-members", format='xml') except: pass try: return dev.rpc.cli("show version invoke-on all-routing-engines", format='xml') except: return dev.rpc.get_software_information()
[docs]def facts_software_version(junos, facts): """ The following facts are required: facts['master'] The following facts are assigned: facts['hostname'] facts['version'] facts['version_<RE#>'] for each RE in dual-RE, cluster or VC system facts['version_info'] for master RE """ x_swver = _get_swver(junos, facts) if not facts.get('model'): # try to extract the model from the version information facts['model'] = x_swver.findtext('.//product-model') # ------------------------------------------------------------------------ # extract the version information out of the RPC response # ------------------------------------------------------------------------ f_master = facts.get('master', 'RE0') if x_swver.tag == 'multi-routing-engine-results': # we need to find/identify each of the routing-engine (CPU) versions. if len(x_swver.xpath('./multi-routing-engine-item')) > 1: facts['2RE'] = True versions = [] if isinstance(f_master, list): xpath = './multi-routing-engine-item[re-name="{0}"' \ ']/software-information/host-name'.format(f_master[0].lower()) else: xpath = './multi-routing-engine-item[re-name="{0}"' \ ']/software-information/host-name'.format(f_master.lower()) facts['hostname'] = x_swver.findtext(xpath) if facts['hostname'] is None: # then there the re-name is not what we are expecting; we should # handle this better, eh? For now, just assume there is one # software-information element and take that host-name. @@@ hack. facts['hostname'] = x_swver.findtext( './/software-information/host-name') for re_sw in x_swver.xpath('.//software-information'): re_name = re_sw.xpath('preceding-sibling::re-name')[0].text # handle the cases where the "RE name" could be things like # "FPC<n>" or "ndoe<n>", and normalize to "RE<n>". re_name = re.sub(r'(\w+)(\d+)', 'RE\\2', re_name) # First try the <junos-version> tag present in >= 15.1 swinfo = re_sw.findtext('junos-version', default=None) if not swinfo: # For < 15.1, get version from the "junos" package. pkginfo = re_sw.xpath( 'package-information[normalize-space(name)="junos"]/comment' )[0].text try: swinfo = re.findall(r'\[(.*)\]', pkginfo)[0] except: swinfo = "0.0I0.0" versions.append((re_name.upper(), swinfo)) # now add the versions to the facts <dict> for re_ver in versions: facts['version_' + re_ver[0]] = re_ver[1] if f_master is not None: master = f_master[0] if isinstance(f_master, list) else f_master if 'version_' + master in facts: facts['version'] = facts['version_' + master] else: facts['version'] = versions[0][1] else: facts['version'] = versions[0][1] else: # single-RE facts['hostname'] = x_swver.findtext('host-name') # First try the <junos-version> tag present in >= 15.1 swinfo = x_swver.findtext('.//junos-version', default=None) if not swinfo: # For < 15.1, get version from the "junos" package. pkginfo = x_swver.xpath( './/package-information[normalize-space(name)="junos"]/comment' )[0].text try: swinfo = re.findall(r'\[(.*)\]', pkginfo)[0] except: swinfo = "0.0I0.0" facts['version'] = swinfo # ------------------------------------------------------------------------ # create a 'version_info' object based on the master version # ------------------------------------------------------------------------ facts['version_info'] = version_info(facts['version'])
[docs]def version_yaml_representer(dumper, version): return dumper.represent_mapping(u'tag:yaml.org,2002:map', version.v_dict)