[Python-modules-commits] [junos-eznc] 01/04: Imported Upstream version 1.3.1
Vincent Bernat
bernat at moszumanska.debian.org
Tue May 24 14:23:21 UTC 2016
This is an automated email from the git hooks/post-receive script.
bernat pushed a commit to branch master
in repository junos-eznc.
commit 167d902054fa19b3d654a722cd4bb0c9202fc48c
Author: Vincent Bernat <bernat at debian.org>
Date: Tue May 24 16:04:17 2016 +0200
Imported Upstream version 1.3.1
---
MANIFEST.in | 2 +
PKG-INFO | 27 +
README.txt | 3 +
lib/jnpr/__init__.py | 1 +
lib/jnpr/junos/__init__.py | 39 ++
lib/jnpr/junos/cfg/__init__.py | 1 +
lib/jnpr/junos/cfg/phyport/__init__.py | 16 +
lib/jnpr/junos/cfg/phyport/base.py | 85 +++
lib/jnpr/junos/cfg/phyport/classic.py | 46 ++
lib/jnpr/junos/cfg/phyport/switch.py | 72 +++
lib/jnpr/junos/cfg/resource.py | 844 +++++++++++++++++++++++++
lib/jnpr/junos/cfg/user.py | 100 +++
lib/jnpr/junos/cfg/user_ssh_key.py | 101 +++
lib/jnpr/junos/cfgro/__init__.py | 0
lib/jnpr/junos/cfgro/srx.yml | 70 ++
lib/jnpr/junos/decorators.py | 75 +++
lib/jnpr/junos/device.py | 842 ++++++++++++++++++++++++
lib/jnpr/junos/exception.py | 281 ++++++++
lib/jnpr/junos/factory/__init__.py | 33 +
lib/jnpr/junos/factory/cfgtable.py | 244 +++++++
lib/jnpr/junos/factory/factory_cls.py | 84 +++
lib/jnpr/junos/factory/factory_loader.py | 276 ++++++++
lib/jnpr/junos/factory/optable.py | 66 ++
lib/jnpr/junos/factory/table.py | 328 ++++++++++
lib/jnpr/junos/factory/to_json.py | 57 ++
lib/jnpr/junos/factory/view.py | 274 ++++++++
lib/jnpr/junos/factory/viewfields.py | 74 +++
lib/jnpr/junos/facts/__init__.py | 24 +
lib/jnpr/junos/facts/chassis.py | 52 ++
lib/jnpr/junos/facts/domain.py | 37 ++
lib/jnpr/junos/facts/ifd_style.py | 6 +
lib/jnpr/junos/facts/personality.py | 49 ++
lib/jnpr/junos/facts/routing_engines.py | 89 +++
lib/jnpr/junos/facts/session.py | 8 +
lib/jnpr/junos/facts/srx_cluster.py | 28 +
lib/jnpr/junos/facts/switch_style.py | 19 +
lib/jnpr/junos/facts/swver.py | 207 ++++++
lib/jnpr/junos/jxml.py | 176 ++++++
lib/jnpr/junos/op/__init__.py | 0
lib/jnpr/junos/op/arp.py | 7 +
lib/jnpr/junos/op/arp.yml | 12 +
lib/jnpr/junos/op/bfd.py | 7 +
lib/jnpr/junos/op/bfd.yml | 47 ++
lib/jnpr/junos/op/ccc.py | 7 +
lib/jnpr/junos/op/ccc.yml | 25 +
lib/jnpr/junos/op/ethernetswitchingtable.py | 9 +
lib/jnpr/junos/op/ethernetswitchingtable.yml | 41 ++
lib/jnpr/junos/op/ethport.py | 7 +
lib/jnpr/junos/op/ethport.yml | 29 +
lib/jnpr/junos/op/fpc.py | 7 +
lib/jnpr/junos/op/fpc.yml | 66 ++
lib/jnpr/junos/op/idpattacks.py | 7 +
lib/jnpr/junos/op/idpattacks.yml | 11 +
lib/jnpr/junos/op/intopticdiag.py | 7 +
lib/jnpr/junos/op/intopticdiag.yml | 22 +
lib/jnpr/junos/op/isis.py | 7 +
lib/jnpr/junos/op/isis.yml | 35 +
lib/jnpr/junos/op/l2circuit.py | 7 +
lib/jnpr/junos/op/l2circuit.yml | 28 +
lib/jnpr/junos/op/lacp.py | 7 +
lib/jnpr/junos/op/lacp.yml | 56 ++
lib/jnpr/junos/op/ldp.py | 7 +
lib/jnpr/junos/op/ldp.yml | 43 ++
lib/jnpr/junos/op/lldp.py | 7 +
lib/jnpr/junos/op/lldp.yml | 15 +
lib/jnpr/junos/op/nd.py | 7 +
lib/jnpr/junos/op/nd.yml | 13 +
lib/jnpr/junos/op/ospf.py | 7 +
lib/jnpr/junos/op/ospf.yml | 22 +
lib/jnpr/junos/op/phyport.py | 7 +
lib/jnpr/junos/op/phyport.yml | 100 +++
lib/jnpr/junos/op/routes.py | 7 +
lib/jnpr/junos/op/routes.yml | 51 ++
lib/jnpr/junos/op/teddb.py | 7 +
lib/jnpr/junos/op/teddb.yml | 46 ++
lib/jnpr/junos/op/vlan.py | 7 +
lib/jnpr/junos/op/vlan.yml | 16 +
lib/jnpr/junos/op/xcvr.py | 7 +
lib/jnpr/junos/op/xcvr.yml | 16 +
lib/jnpr/junos/rpcmeta.py | 166 +++++
lib/jnpr/junos/utils/__init__.py | 1 +
lib/jnpr/junos/utils/config.py | 685 ++++++++++++++++++++
lib/jnpr/junos/utils/fs.py | 433 +++++++++++++
lib/jnpr/junos/utils/scp.py | 125 ++++
lib/jnpr/junos/utils/start_shell.py | 131 ++++
lib/jnpr/junos/utils/sw.py | 609 ++++++++++++++++++
lib/jnpr/junos/utils/util.py | 48 ++
lib/jnpr/junos/version.py | 2 +
lib/junos_eznc.egg-info/PKG-INFO | 27 +
lib/junos_eznc.egg-info/SOURCES.txt | 95 +++
lib/junos_eznc.egg-info/dependency_links.txt | 1 +
lib/junos_eznc.egg-info/namespace_packages.txt | 1 +
lib/junos_eznc.egg-info/requires.txt | 7 +
lib/junos_eznc.egg-info/top_level.txt | 1 +
requirements.txt | 7 +
setup.cfg | 5 +
setup.py | 43 ++
97 files changed, 7959 insertions(+)
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..f78132b
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,2 @@
+include requirements.txt
+recursive-include lib *.yml
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..8404bdd
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,27 @@
+Metadata-Version: 1.1
+Name: junos-eznc
+Version: 1.3.1
+Summary: Junos 'EZ' automation for non-programmers
+Home-page: http://www.github.com/Juniper/py-junos-eznc
+Author: Jeremy Schulman
+Author-email: jnpr-community-netdev at juniper.net
+License: Apache 2.0
+Description: UNKNOWN
+Keywords: Junos NETCONF networking automation
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Information Technology
+Classifier: Intended Audience :: System Administrators
+Classifier: Intended Audience :: Telecommunications Industry
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Topic :: Software Development :: Libraries
+Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Networking
+Classifier: Topic :: Text Processing :: Markup :: XML
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..2193a83
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,3 @@
+==========
+junos-eznc
+==========
diff --git a/lib/jnpr/__init__.py b/lib/jnpr/__init__.py
new file mode 100644
index 0000000..de40ea7
--- /dev/null
+++ b/lib/jnpr/__init__.py
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/lib/jnpr/junos/__init__.py b/lib/jnpr/junos/__init__.py
new file mode 100644
index 0000000..5764bbb
--- /dev/null
+++ b/lib/jnpr/junos/__init__.py
@@ -0,0 +1,39 @@
+from jnpr.junos.device import Device
+from jnpr.junos.factory.to_json import PyEzJSONEncoder
+from jnpr.junos.facts.swver import version_info, version_yaml_representer
+from . import jxml
+from . import jxml as JXML
+from . import version
+from . import exception
+
+import json
+import yaml
+import logging
+
+__version__ = version.VERSION
+__date__ = version.DATE
+
+#import time
+#__date__ = time.strftime("%Y-%b-%d")
+
+# Set default JSON encoder
+json._default_encoder = PyEzJSONEncoder()
+
+# Disable ignore_aliases for YAML dumper
+# To support version_info
+yaml.dumper.SafeDumper.ignore_aliases = lambda self, data: True
+yaml.dumper.Dumper.ignore_aliases = lambda self, data: True
+# Add YAML representer for version_info
+yaml.Dumper.add_multi_representer(version_info, version_yaml_representer)
+yaml.SafeDumper.add_multi_representer(version_info, version_yaml_representer)
+
+
+# Suppress Paramiko logger warnings
+plog = logging.getLogger('paramiko')
+if not plog.handlers:
+ class NullHandler(logging.Handler):
+
+ def emit(self, record):
+ pass
+
+ plog.addHandler(NullHandler())
diff --git a/lib/jnpr/junos/cfg/__init__.py b/lib/jnpr/junos/cfg/__init__.py
new file mode 100644
index 0000000..54c8e61
--- /dev/null
+++ b/lib/jnpr/junos/cfg/__init__.py
@@ -0,0 +1 @@
+from jnpr.junos.cfg.resource import Resource
diff --git a/lib/jnpr/junos/cfg/phyport/__init__.py b/lib/jnpr/junos/cfg/phyport/__init__.py
new file mode 100644
index 0000000..cc7864d
--- /dev/null
+++ b/lib/jnpr/junos/cfg/phyport/__init__.py
@@ -0,0 +1,16 @@
+from jnpr.junos.cfg import Resource
+from jnpr.junos.cfg.phyport.classic import PhyPortClassic
+from jnpr.junos.cfg.phyport.switch import PhyPortSwitch
+
+__all__ = ['PhyPort']
+
+
+class PhyPort(object):
+
+ def __new__(cls, dev, name=None):
+ supercls = {
+ 'CLASSIC': PhyPortClassic,
+ 'SWITCH': PhyPortSwitch,
+ }.get(dev.facts['ifd_style'])
+ newcls = type(cls.__name__, (supercls,), {})
+ return newcls(dev, name)
diff --git a/lib/jnpr/junos/cfg/phyport/base.py b/lib/jnpr/junos/cfg/phyport/base.py
new file mode 100644
index 0000000..8dc52db
--- /dev/null
+++ b/lib/jnpr/junos/cfg/phyport/base.py
@@ -0,0 +1,85 @@
+# 3rd-party
+from lxml.builder import E
+
+# local module
+from jnpr.junos.cfg.resource import Resource
+
+
+class PhyPortBase(Resource):
+
+ """
+ [edit interfaces <name>]
+
+ Resource name: str
+ <name> is the interface-name (IFD), e.g. 'ge-0/0/0'
+ """
+
+ PROPERTIES = [
+ 'admin', # True
+ 'description', # str
+ 'speed', # ['10m','100m','1g','10g']
+ 'duplex', # ['full','half']
+ 'mtu', # int
+ 'loopback', # True
+ '$unit_count' # number of units defined
+ ]
+
+ PORT_DUPLEX = {
+ 'full': 'full-duplex',
+ 'half': 'half-duplex'
+ }
+
+ @classmethod
+ def _set_invert(cls, in_this, item, from_this):
+ from_item = in_this[item]
+ in_this[item] = [
+ _k for _k,
+ _v in from_this.items() if _v == from_item][0]
+
+ # -----------------------------------------------------------------------
+ # XML readers
+ # -----------------------------------------------------------------------
+
+ def _xml_at_top(self):
+ return E.interfaces(E.interface(
+ E.name(self._name)
+ ))
+
+ def _xml_at_res(self, xml):
+ return xml.find('.//interface')
+
+ def _xml_to_py(self, has_xml, has_py):
+ # common to all subclasses
+ Resource._r_has_xml_status(has_xml, has_py)
+ has_py['admin'] = bool(has_xml.find('disable') is None)
+ Resource.copyifexists(has_xml, 'description', has_py)
+ Resource.copyifexists(has_xml, 'mtu', has_py)
+ has_py['$unit_count'] = len(has_xml.findall('unit'))
+
+ # -----------------------------------------------------------------------
+ # XML writers
+ # -----------------------------------------------------------------------
+
+ # description handed by Resource
+
+ def _xml_change_admin(self, xml):
+ xml.append(
+ Resource.xmltag_set_or_del(
+ 'disable',
+ (self.admin == False)))
+ return True
+
+ def _xml_change_mtu(self, xml):
+ Resource.xml_set_or_delete(xml, 'mtu', self.mtu)
+ return True
+
+ # -----------------------------------------------------------------------
+ # Manager List, Catalog
+ # -----------------------------------------------------------------------
+
+ def _r_list(self):
+ got = self.R.get_interface_information(
+ media=True,
+ interface_name="[xgf]e*")
+ self._rlist = [
+ name.text.strip() for name in got.xpath('physical-interface/name')]
diff --git a/lib/jnpr/junos/cfg/phyport/classic.py b/lib/jnpr/junos/cfg/phyport/classic.py
new file mode 100644
index 0000000..d08e8b3
--- /dev/null
+++ b/lib/jnpr/junos/cfg/phyport/classic.py
@@ -0,0 +1,46 @@
+# 3rd-party
+from lxml.builder import E
+
+# local
+from jnpr.junos.cfg.resource import Resource
+from jnpr.junos import JXML
+from jnpr.junos.cfg.phyport.base import PhyPortBase
+
+
+class PhyPortClassic(PhyPortBase):
+
+ # -----------------------------------------------------------------------
+ # XML readers
+ # -----------------------------------------------------------------------
+
+ def _xml_to_py(self, has_xml, has_py):
+ PhyPortBase._xml_to_py(self, has_xml, has_py)
+
+ Resource.copyifexists(has_xml, 'speed', has_py)
+ Resource.copyifexists(has_xml, 'link-mode', has_py, 'duplex')
+ if has_xml.find('gigether-options/loopback') is not None:
+ has_py['loopback'] = True
+ has_py['$unit_count'] = len(has_xml.findall('unit'))
+
+ # normalizers
+ if 'duplex' in has_py:
+ PhyPortBase._set_invert(has_py, 'duplex', self.PORT_DUPLEX)
+
+ # -----------------------------------------------------------------------
+ # XML writers
+ # -----------------------------------------------------------------------
+
+ def _xml_change_speed(self, xml):
+ Resource.xml_set_or_delete(xml, 'speed', self.speed)
+ return True
+
+ def _xml_change_duplex(self, xml):
+ value = self.PORT_DUPLEX.get(self.duplex)
+ Resource.xml_set_or_delete(xml, 'link-mode', value)
+ return True
+
+ def _xml_change_loopback(self, xml):
+ opts = E('gigether-options')
+ opts.append(Resource.xmltag_set_or_del('loopback', self.loopback))
+ xml.append(opts)
+ return True
diff --git a/lib/jnpr/junos/cfg/phyport/switch.py b/lib/jnpr/junos/cfg/phyport/switch.py
new file mode 100644
index 0000000..fa36a52
--- /dev/null
+++ b/lib/jnpr/junos/cfg/phyport/switch.py
@@ -0,0 +1,72 @@
+# 3rd-party
+from lxml.builder import E
+
+# local
+from jnpr.junos.cfg import Resource
+from jnpr.junos import JXML
+from jnpr.junos.cfg.phyport.base import PhyPortBase
+
+
+class PhyPortSwitch(PhyPortBase):
+
+ PORT_SPEED = {
+ 'auto': 'auto-negotiation',
+ '10m': 'ethernet-10m',
+ '100m': 'ethernet-100m',
+ '1g': 'ethernet-1g'
+ }
+
+ # -----------------------------------------------------------------------
+ # XML readers
+ # -----------------------------------------------------------------------
+
+ def _xml_to_py(self, has_xml, has_py):
+ PhyPortBase._xml_to_py(self, has_xml, has_py)
+
+ # speed, duplex, loopback are all under 'ether-options'
+ ethopts = has_xml.find('ether-options')
+ if ethopts is None:
+ return
+
+ if ethopts.find('loopback') is not None:
+ has_py['loopback'] = True
+
+ speed = ethopts.find('speed')
+ if speed is not None:
+ # take the first child element
+ has_py['speed'] = speed[0].tag
+ PhyPortBase._set_invert(has_py, 'speed', self.PORT_SPEED)
+
+ Resource.copyifexists(ethopts, 'link-mode', has_py, 'duplex')
+ if 'duplex' in has_py:
+ PhyPortBase._set_invert(has_py, 'duplex', self.PORT_DUPLEX)
+
+ # -----------------------------------------------------------------------
+ # XML writers
+ # -----------------------------------------------------------------------
+
+ def _xml_hook_build_change_begin(self, xml):
+ if any([this in self.should for this in ['speed', 'duplex',
+ 'loopback']]):
+ self._ethopts = E('ether-options')
+ xml.append(self._ethopts)
+
+ def _xml_change_speed(self, xml):
+ speed_tag = self.PORT_SPEED.get(self.speed)
+ add_this = E.speed(
+ JXML.DEL) if speed_tag is None else E.speed(
+ E(speed_tag))
+ self._ethopts.append(add_this)
+ return True
+
+ def _xml_change_duplex(self, xml):
+ value = self.PORT_DUPLEX.get(self.duplex)
+ Resource.xml_set_or_delete(self._ethopts, 'link-mode', value)
+ return True
+
+ def _xml_change_loopback(self, xml):
+ self._ethopts.append(
+ Resource.xmltag_set_or_del(
+ 'loopback',
+ self.loopback))
+ return True
diff --git a/lib/jnpr/junos/cfg/resource.py b/lib/jnpr/junos/cfg/resource.py
new file mode 100644
index 0000000..6c89330
--- /dev/null
+++ b/lib/jnpr/junos/cfg/resource.py
@@ -0,0 +1,844 @@
+# stdlib
+import warnings
+from pprint import pformat
+from copy import deepcopy
+
+# 3rd-party
+from lxml.builder import E
+
+# package modules
+from jnpr.junos import jxml as JXML
+
+P_JUNOS_EXISTS = '_exists'
+P_JUNOS_ACTIVE = '_active'
+
+
+class Resource(object):
+
+ PROPERTIES = [
+ P_JUNOS_EXISTS,
+ P_JUNOS_ACTIVE
+ ]
+
+ def __init__(self, junos, namevar=None, **kvargs):
+ """
+ Resource or Resource-Manager constructor. All managed resources
+ and resource-managers inherit from this class.
+
+ junos
+ Instance of Device, this is bound to the Resource for
+ device access
+
+ namevar
+ If not None, identifies a specific resource by 'name'. The
+ format of the name is resource dependent. Most resources take
+ a single string name, while others use tuples for compound names.
+ refer to each resource for the 'namevar' definition
+
+ If namevar is None, then the instance is a Resource-Manager (RM).
+ The RM is then used to select specific resources by name using
+ the __getitem__ overload.
+
+ kvargs['P'] or kvargs['parent']
+ Instance to the resource parent. This is set when resources have
+ hierarchical relationships, like rules within rulesets
+
+ kvargs['M']
+ Instance to the resource manager.
+ """
+ self._junos = junos
+ self._name = namevar
+ self._parent = kvargs.get('parent') or kvargs.get('P')
+ self._opts = kvargs
+ self._manager = kvargs.get('M')
+
+ if not namevar:
+ # then this is a resource-manager instance. setup the list and
+ # catalog attributes, but do not load them now. when the caller
+ # invokes the properties, they will auto-load when empty.
+ self._rlist = []
+ self._rcatalog = {}
+ return
+
+ # otherwise, a resource includes public attributes:
+
+ self.properties = []
+ self.properties.extend(Resource.PROPERTIES)
+ if self.__class__ != Resource:
+ self.properties.extend(self.__class__.PROPERTIES)
+
+ # if this resource manages others, then hook that
+ # into the :manages: list
+
+ if hasattr(self, 'MANAGES'):
+ self._manages = self.MANAGES.keys()
+ for k, v in self.MANAGES.items():
+ self.__dict__[k] = v(junos, parent=self)
+
+ # setup resource cache-attributes
+
+ self.has = {}
+ self.should = {}
+ self._is_new = False
+
+ # now load the properties from the device.
+ self.read()
+
+ # -----------------------------------------------------------------------
+ # PROPERTIES
+ # -----------------------------------------------------------------------
+
+ @property
+ def active(self):
+ """
+ is this resource configuration active on the Junos device?
+
+ :RuntimeError: if invoked on a manager object
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ return self.has[P_JUNOS_ACTIVE]
+
+ @property
+ def exists(self):
+ """
+ does this resource configuration exist on the Junos device?
+
+ :RuntimError: if invoked on a manager
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ return self.has[P_JUNOS_EXISTS]
+
+ @property
+ def is_mgr(self):
+ """
+ is this a resource manager?
+ """
+ return (self._name is None)
+
+ @property
+ def is_new(self):
+ """
+ is this a new resource? that is, it does not exist
+ on the Junos device when it was initally retrieved
+
+ :RuntimeError: if invoked on a manager
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ return self._is_new
+
+ @property
+ def name(self):
+ """
+ the name of the resource
+
+ :RuntimeError: if invoked on a manager
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ raise AttributeError("name is currently read-only")
+
+ @property
+ def manages(self):
+ """
+ a resource may contain sub-managers for hierarchical
+ oriented resources. this method will return a list
+ of manager names attached to this resource, or
+ :None: if there are not any
+ """
+ if hasattr(self, '_manages'):
+ return self._manages
+ return None
+
+ @manages.setter
+ def manages(self):
+ raise AttributeError("read-only")
+
+ @property
+ def xml(self):
+ """
+ for debugging the resource XML configuration that was
+ read from the Junos device
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ return self._has_xml
+
+ @property
+ def list(self):
+ """
+ returns a list of named resources
+ """
+ if not self.is_mgr:
+ raise RuntimeError("Must be a manager!")
+ if not len(self._rlist):
+ self.list_refresh()
+ return self._rlist
+
+ @property
+ def catalog(self):
+ """
+ returns a dictionary of resources
+ """
+ if not self.is_mgr:
+ raise RuntimeError("Must be a manager!")
+ if not len(self._rcatalog):
+ self.catalog_refresh()
+ return self._rcatalog
+
+ # -------------------------------------------------------------------------
+ # shortcuts
+ # -------------------------------------------------------------------------
+
+ @property
+ def D(self):
+ """ returns the Device object bound to this resource/manager """
+ return self._junos
+
+ @property
+ def R(self):
+ """ returns the Device RPC meta object """
+ return self._junos.rpc
+
+ @property
+ def M(self):
+ """ returns the :Resource: manager associated to this resource """
+ return self._manager
+
+ @property
+ def P(self):
+ """ returns the parent of the associated Junos object """
+ return self._parent
+
+ # -----------------------------------------------------------------------
+ # PUBLIC METHODS
+ # -----------------------------------------------------------------------
+
+ # -------------------------------------------------------------------------
+ # read
+ # -------------------------------------------------------------------------
+
+ def read(self):
+ """
+ read resource configuration from device
+ """
+
+ self._r_has_init()
+ self._has_xml = self._r_config_read_xml()
+
+ if None == self._has_xml or not len(self._has_xml):
+ self._is_new = True
+ self._r_when_new()
+ return None
+
+ # the xml_read_parser *MUST* be implement by the
+ # resource subclass. it is used to parse the XML
+ # into native python structures.
+
+ self._xml_to_py(self._has_xml, self.has)
+
+ # return the python structure represntation
+ return True
+
+ # -------------------------------------------------------------------------
+ # write
+ # -------------------------------------------------------------------------
+
+ def write(self, **kvargs):
+ """
+ write resource configuration stored in :should: back to device
+
+ kvargs['touch']
+ if True, then write() will skip the check to see if any
+ items exist in :should:
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+
+ if not len(self.should) and 'touch' not in kvargs:
+ return False
+
+ # if this resource did not previously exist,
+ # then mark it now into :should:
+
+ if P_JUNOS_EXISTS not in self.should:
+ self._r_set_exists(self.should, True)
+
+ if self.is_new:
+ self._r_set_active(self.should, True)
+
+ # construct the XML change structure
+ xml_change = self._xml_build_change()
+ if None == xml_change:
+ return False
+
+ # write these changes to the device
+ rsp = self._r_config_write_xml(xml_change)
+
+ # copy :should: into :has: and then clear :should:
+ self.has.update(self.should)
+ self.should.clear()
+
+ return True
+
+ # -------------------------------------------------------------------------
+ # activate
+ # -------------------------------------------------------------------------
+
+ def activate(self):
+ """
+ activate resource in Junos config
+ the same as the Junos config-mode "activate" command
+ """
+ # no action needed if it's already active
+ if self.active:
+ return False
+ self._r_set_active(self.should, True)
+ return self.write()
+
+ # -------------------------------------------------------------------------
+ # deactivate
+ # -------------------------------------------------------------------------
+
+ def deactivate(self):
+ """
+ activate resource in Junos config
+ the same as the Junos config-mode "deactivate" command
+ """
+ # no action needed if it's already deactive
+ if not self.active:
+ return False
+ self._r_set_active(self.should, False)
+ return self.write()
+
+ # -------------------------------------------------------------------------
+ # delete
+ # -------------------------------------------------------------------------
+
+ def delete(self):
+ """
+ remove configuration from Junos device
+ the same as the Junos config-mode "delete" command
+ """
+ # cannot delete something that doesn't exist
+ # @@@ should raise?
+
+ if not self.exists:
+ return False
+
+ # remove the config from Junos
+ xml = self._xml_edit_at_res()
+ xml.attrib.update(JXML.DEL)
+ self._xml_hook_on_delete(xml)
+ rsp = self._r_config_write_xml(xml)
+
+ # reset the :has: attribute
+ self._r_has_init()
+ return True
+
+ # -------------------------------------------------------------------------
+ # rename
+ # -------------------------------------------------------------------------
+
+ def rename(self, new_name):
+ """
+ rename resource in Junos configuration
+ the same as the Junos config-mode "rename" command
+ """
+ # cannot rename something that doesn't exist
+ # @@@ should raise?
+
+ if not self.exists:
+ return False
+
+ xml = self._xml_edit_at_res()
+ xml.attrib.update(JXML.REN)
+ xml.attrib.update(JXML.NAME(new_name))
+
+ rsp = self._r_config_write_xml(xml)
+ self._name = new_name
+
+ return True
+
+ # -------------------------------------------------------------------------
+ # reorder
+ # -------------------------------------------------------------------------
+
+ def reorder(self, **kvargs):
+ """
+ move the configuration within the Junos hierarcy
+ the same as the Junos config-mode "insert" command
+
+ :kvargs:
+ after="<name>"
+ before="<name>"
+ """
+ cmd, name = next(kvargs.iteritems())
+ if cmd != 'before' and cmd != 'after':
+ raise ValueError("Must be either 'before' or 'after'")
+
+ xml = self._xml_edit_at_res()
+ xml.attrib.update(JXML.INSERT(cmd))
+ xml.attrib.update(JXML.NAME(name))
+
+ rsp = self._r_config_write_xml(xml)
+ return True
+
+ def list_refresh(self):
+ """
+ reloads the managed resource list from the Junos device
+ """
+ if not self.is_mgr:
+ raise RuntimeError("Only on a manager!")
+ del self._rlist[:]
+ self._r_list() # invoke the specific resource method
+
+ def catalog_refresh(self):
+ """
+ reloads the resource catalog from the Junos device
+ """
+ if not self.is_mgr:
+ raise RuntimeError("Only on a manager!")
+ self._rcatalog.clear()
+ self._r_catalog() # invoke the specific resource method
+
+ def _r_catalog(self):
+ """
+ provide a 'default' catalog creator method that simply uses
+ the manager list and runs through each resource making
+ a refcopy to the :has: properties
+ """
+ zone_list = self.list
+ for name in zone_list:
+ r = self[name]
+ self._rcatalog[name] = r.has
+
+ def refresh(self):
+ if not self.is_mgr:
+ raise RuntimeError("Only on a manager!")
+ self.list_refresh()
+ self.catalog_refresh()
+
+ def propcopy(self, p_name):
+ """
+ proptery from :has: to :should:
+
+ performs a 'deepcopy' of the property; used to make
+ changes to list, dict type properties
+ """
+ self.should[p_name] = deepcopy(self.has[p_name])
+ return self.should[p_name]
+
+ # -----------------------------------------------------------------------
+ # OVERLOADS
+ # -----------------------------------------------------------------------
+
+ # ---------------------------------------------------------------------
+ # ITEMS: for read/write of resource managed properties
+ # ---------------------------------------------------------------------
+
+ def __getitem__(self, namekey):
+ """
+ implements [] to obtain property value. value will come
+ from :should: if set or from :has: otherwise.
+ """
+
+ if self.is_mgr:
+ # ---------------------------------------------------------------
+ # use is resource-manager accessing specific index/name
+ # to return resource instance
+ # ---------------------------------------------------------------
+
+ self._opts['M'] = self
+ if isinstance(namekey, int):
+ # index, not name
+ namekey = self.list[namekey]
+
+ res = self.__class__(self._junos, namekey, **self._opts)
+ return res
+
+ # ---------------------------------------------------------------
+ # use-case is resource instance for read property
+ # ---------------------------------------------------------------
+
+ if namekey in self.should:
+ return self.should[namekey]
+
+ if namekey in self.has:
+ return self.has[namekey]
+
+ if namekey in self.properties:
+ # it's a valid property, just not set in the resource
+ return None
+
+ raise ValueError("Unknown property request: %s" % namekey)
+
+ def __setitem__(self, r_prop, value):
+ """
+ implements []= to set property value into :should:
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ if r_prop in self.properties:
+ self.should[r_prop] = value
+ else:
+ raise ValueError("Uknown property request: %s" % r_prop)
+
+ def __call__(self, **kvargs):
+ """
+ alternative way to set property values as aggregation of
+ key/value pairs. this will automatically call :write():
+ when completed.
+ """
+ if self.is_mgr:
+ raise RuntimeError("Not on a manager!")
+ if not kvargs:
+ return False
+
+ # validate property names first!
+ for p_name, p_val in kvargs.items():
+ if p_name not in self.properties:
+ raise ValueError("Unknown property: %s" % p_name)
+
+ # now cleared to add all the values
+ self.should.update(kvargs)
+ return self.write()
+
+ # ---------------------------------------------------------------------
+ # ATTRIBUTE: for read/write of resource managed properties
+ # ---------------------------------------------------------------------
+
+ def __getattr__(self, namekey):
+ """
+ returns property value, accessed as attribute <resource>.<property>
+ only for resource instance
+ """
+ if self.is_mgr:
+ raise RuntimeError("not on a resource-manager")
+ return self[namekey]
+
+ def __setattr__(self, name, value):
+ if hasattr(self, 'properties') and name in self.properties:
+ # we can set this name/value in the resource property
+ self[name] = value
+ else:
+ # pass 'up' to standard setattr method
+ object.__setattr__(self, name, value)
+
+ # ---------------------------------------------------------------------
+ # PRINT/DEBUG
... 7643 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/junos-eznc.git
More information about the Python-modules-commits
mailing list