Skip to content

Commit

Permalink
Merge 7266d57 into e004c28
Browse files Browse the repository at this point in the history
  • Loading branch information
earies committed Nov 11, 2020
2 parents e004c28 + 7266d57 commit 3ba260d
Show file tree
Hide file tree
Showing 17 changed files with 757 additions and 48 deletions.
6 changes: 4 additions & 2 deletions examples/nokia/sros/get_config.py
Expand Up @@ -5,12 +5,14 @@
import sys

from ncclient import manager
from ncclient.namespaces import IETF
from ncclient.namespaces import Nokia
from ncclient.xml_ import to_xml
from ncclient.operations.rpc import RPCError

_NS_MAP = {
'nc': 'urn:ietf:params:xml:ns:netconf:base:1.0',
'nokia-conf': 'urn:nokia.com:sros:ns:yang:sr:conf'
'nc': IETF.nsmap['nc'],
'nokia-conf': Nokia.nsmap['conf']
}

_NOKIA_MGMT_INT_FILTER = '''
Expand Down
94 changes: 94 additions & 0 deletions examples/nokia/sros/get_data.py
@@ -0,0 +1,94 @@
#!/usr/bin/env python
#

import logging
import sys

from ncclient import manager

from ncclient._types import Datastore
from ncclient._types import FilterType
from ncclient._types import WithDefaults
from ncclient._types import Origin

from ncclient.namespaces import IETF
from ncclient.namespaces import Nokia

from ncclient.xml_ import to_xml
from ncclient.operations.rpc import RPCError

_NS_MAP = IETF.nsmap
_NS_MAP.update(Nokia.nsmap)

_NOKIA_CONF_MGMT_INT_FILTER = '''
<configure xmlns="%s">
<system>
<management-interface/>
</system>
</configure>
''' % (_NS_MAP['conf'])

_NOKIA_STATE_MGMT_INT_FILTER = '''
<state xmlns="%s">
<system>
<management-interface/>
</system>
</state>
''' % (_NS_MAP['state'])


def connect(host, port, user, password):
m = manager.connect(host=host, port=port,
username=user, password=password,
device_params={'name': 'sros'},
hostkey_verify=False)

## Issue get-data on the candidate datastore with a subtree filter,
## with-defaults and a max-depth of '3' and display the raw XML
## output
try:
result = m.get_data(datastore=Datastore.CANDIDATE,
filter=(FilterType.SUBTREE, _NOKIA_CONF_MGMT_INT_FILTER),
max_depth=3, with_defaults=WithDefaults.REPORT_ALL)
logging.info(result)

except RPCError as err:
logging.error(err)

## Issue get-data on the intended datastore with a subtree filter,
## with-defaults and display the raw XML output
try:
result = m.get_data(datastore=Datastore.INTENDED,
filter=(FilterType.SUBTREE, _NOKIA_CONF_MGMT_INT_FILTER),
with_defaults=WithDefaults.REPORT_ALL)
logging.info(result)

except RPCError as err:
logging.error(err)


## Issue get-data on the running datastore with a subtree filter,
## with-defaults and strip the rpc-reply + data elements
try:
result = m.get_data(datastore=Datastore.RUNNING,
filter=(FilterType.SUBTREE, _NOKIA_STATE_MGMT_INT_FILTER),
with_defaults=WithDefaults.REPORT_ALL).xpath(
'/nc:rpc-reply/nc:data/state:state',
namespaces=_NS_MAP)[0]
logging.info(to_xml(result, pretty_print=True))

except RPCError as err:
logging.error(err)

m.close_session()

if __name__ == '__main__':
LOG_FORMAT = '%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(message)s'
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format=LOG_FORMAT)

try:
connect(sys.argv[1], '830', 'admin', 'admin')

except IndexError:
logging.error('Must supply a valid hostname or IP address')

6 changes: 4 additions & 2 deletions examples/nokia/sros/md_cli_raw_command.py
Expand Up @@ -8,11 +8,13 @@
import sys

from ncclient import manager
from ncclient.namespaces import IETF
from ncclient.namespaces import Nokia
from ncclient.operations.rpc import RPCError

_NS_MAP = {
'nc': 'urn:ietf:params:xml:ns:netconf:base:1.0',
'nokia-oper': 'urn:nokia.com:sros:ns:yang:sr:oper-global'
'nc': IETF.nsmap['nc'],
'nokia-oper': Nokia.nsmap['oper-global']
}

def connect(host, port, user, password):
Expand Down
43 changes: 43 additions & 0 deletions ncclient/_types.py
@@ -0,0 +1,43 @@
# Copyright 2020 Ebben Aries
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import enum

class Datastore(enum.Enum):
"""RFC8342 NMDA Datastores"""
STARTUP = 0
CANDIDATE = 1
RUNNING = 2
INTENDED = 3
OPERATIONAL = 4

class FilterType(enum.Enum):
"""RFC6241 NETCONF filtering"""
SUBTREE = 0
XPATH = 1

class WithDefaults(enum.Enum):
"""RFC6243 NETCONF with-defaults modes"""
REPORT_ALL = 0
REPORT_ALL_TAGGED = 1
TRIM = 2
EXPLICIT = 3

class Origin(enum.Enum):
"""RFC8342 NMDA Origin annotations"""
INTENDED = 0
DYNAMIC = 1
SYSTEM = 2
LEARNED = 3
DEFAULT = 4
UNKNOWN = 5
2 changes: 2 additions & 0 deletions ncclient/devices/sros.py
@@ -1,6 +1,7 @@
from lxml import etree

from .default import DefaultDeviceHandler
from ncclient.operations.third_party.sros.rpc import SrosGetData
from ncclient.operations.third_party.sros.rpc import MdCliRawCommand
from ncclient.xml_ import BASE_NS_1_0

Expand Down Expand Up @@ -43,6 +44,7 @@ def get_xml_extra_prefix_kwargs(self):

def add_additional_operations(self):
operations = {
'get_data': SrosGetData,
'md_cli_raw_command': MdCliRawCommand
}
return operations
Expand Down
1 change: 1 addition & 0 deletions ncclient/manager.py
Expand Up @@ -31,6 +31,7 @@
OPERATIONS = {
"get": operations.Get,
"get_config": operations.GetConfig,
"get_data": operations.GetData,
"get_schema": operations.GetSchema,
"dispatch": operations.Dispatch,
"edit_config": operations.EditConfig,
Expand Down
37 changes: 37 additions & 0 deletions ncclient/namespaces.py
@@ -0,0 +1,37 @@
# Copyright 2020 Ebben Aries
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

class IETF(object):
# YANG module prefix -> namespace map
nsmap = {
'ds': 'urn:ietf:params:xml:ns:yang:ietf-datastores',
'nc': 'urn:ietf:params:xml:ns:netconf:base:1.0',
'ncds': 'urn:ietf:params:xml:ns:yang:ietf-netconf-nmda',
'ncm': 'urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring',
'ncwd': 'urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults',
'or': 'urn:ietf:params:xml:ns:yang:ietf-origin'
}

# Namespaces that are not defined in a YANG module and thus do not
# have a prefix declaration for mapping
notif = 'urn:ietf:params:xml:ns:netconf:notification:1.0'
yang = 'urn:ietf:params:xml:ns:yang:1'


class Nokia(object):
nsmap = {
'conf': 'urn:nokia.com:sros:ns:yang:sr:conf',
'oper-global': 'urn:nokia.com:sros:ns:yang:sr:oper-global',
'state': 'urn:nokia.com:sros:ns:yang:sr:state'
}
3 changes: 2 additions & 1 deletion ncclient/operations/__init__.py
Expand Up @@ -17,7 +17,7 @@

# rfc4741 ops

from ncclient.operations.retrieve import Get, GetConfig, GetSchema, GetReply, Dispatch
from ncclient.operations.retrieve import Get, GetConfig, GetData, GetSchema, GetReply, Dispatch
from ncclient.operations.edit import EditConfig, CopyConfig, DeleteConfig, Validate, Commit, DiscardChanges, CancelCommit
from ncclient.operations.session import CloseSession, KillSession
from ncclient.operations.lock import Lock, Unlock, LockContext
Expand All @@ -34,6 +34,7 @@
'GenericRPC',
'Get',
'GetConfig',
'GetData',
'GetSchema',
'Dispatch',
'GetReply',
Expand Down

0 comments on commit 3ba260d

Please sign in to comment.