[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