Revision 1fca349b

b/ncclient/content.py
20 20
### Namespace-related ###
21 21

  
22 22
BASE_NS = 'urn:ietf:params:xml:ns:netconf:base:1.0'
23

  
24
# cisco returns incorrectly namespaced xml
23
NOTIFICATION_NS = 'urn:ietf:params:xml:ns:netconf:notification:1.0'
24
# and this is BASE_NS according to cisco devices...
25 25
CISCO_BS = 'urn:ietf:params:netconf:base:1.0'
26 26

  
27 27
try:
b/ncclient/operations/__init__.py
18 18
logger = logging.getLogger('ncclient.operations')
19 19

  
20 20
from retrieve import Get, GetConfig
21
from edit import EditConfig, DeleteConfig
21
from edit import EditConfig, CopyConfig, DeleteConfig, Validate, Commit, DiscardChanges
22 22
from session import CloseSession, KillSession
23 23
from lock import Lock, Unlock
24 24
from subscribe import CreateSubscription
......
27 27
    'Get',
28 28
    'GetConfig',
29 29
    'EditConfig',
30
    'CopyConfig',
31
    'Validate',
32
    'Commit',
33
    'DiscardChanges',
30 34
    'DeleteConfig',
31 35
    'Lock',
32 36
    'Unlock',
b/ncclient/operations/edit.py
14 14

  
15 15
from rpc import RPC
16 16

  
17
# TODO
18

  
19

  
20
'''
21
notes
22
-> editconfig and copyconfig <running> target depends on :writable-running
23
-> 
24

  
25
'''
26

  
17 27
class EditConfig(RPC):
18 28
    pass
19 29

  
30
class CopyConfig(RPC):
31
    pass
32

  
20 33
class DeleteConfig(RPC):
21 34
    pass
22 35

  
36
class Validate(RPC):
37
    pass
38

  
39
class Commit(RPC):
40
    pass # .confirm() !
41

  
42
class DiscardChanges(RPC):
43
    pass
b/ncclient/operations/lock.py
14 14

  
15 15
'Locking-related NETCONF operations'
16 16

  
17
from rpc import RPC
17
# TODO - a context manager around some <target> would be real neat
18 18

  
19
from rpc import RPC
20
from copy import deepcopy
19 21

  
20 22
class Lock(RPC):
21 23
    
22
    def __init__(self, *args, **kwds):
23
        RPC.__init__(self, *args, **kwds)
24
        self.spec = {
25
            'tag': 'lock',
26
            'children': { 'tag': 'target', 'children': {'tag': None} }
27
            }
24
    SPEC = {
25
        'tag': 'lock',
26
        'children': {
27
            'tag': 'target',
28
            'children': {'tag': None }
29
        }
30
    }
28 31
    
29 32
    def request(self, target='running'):
30
        self.spec['children']['children']['tag'] = target
31
        self._request(self.spec)
33
        spec = deepcopy(Lock.SPEC)
34
        spec['children']['children']['tag'] = target
35
        return self._request(spec)
32 36

  
33 37

  
34 38
class Unlock(RPC):
35 39
    
36
    def __init__(self, *args, **kwds):
37
        RPC.__init__(self, *args, **kwds)
38
        self.spec = {
39
            'tag': 'unlock',
40
            'children': { 'tag': 'target', 'children': {'tag': None} }
41
            }
40
    SPEC = {
41
        'tag': 'unlock',
42
        'children': {
43
            'tag': 'target',
44
            'children': {'tag': None }
45
        }
46
    }
42 47
    
43 48
    def request(self, target='running'):
44
        self.spec['children']['children']['tag'] = target
45
        self._request(self.spec)
49
        spec = deepcopy(Unlock.SPEC)
50
        spec['children']['children']['tag'] = target
51
        return self._request(self.spec)
b/ncclient/operations/reply.py
34 34
        if self._parsed: return
35 35
        root = ET.fromstring(self._raw) # <rpc-reply> element
36 36
        
37
        # check if root is <rpc-reply> ??
38
        
37 39
        # per rfc 4741 an <ok/> tag is sent when there are no errors or warnings
38 40
        oktags = _('ok')
39 41
        for oktag in oktags:
b/ncclient/operations/retrieve.py
19 19

  
20 20
class GetConfig(RPC):
21 21
    pass
22

  
b/ncclient/operations/rpc.py
24 24
from . import logger
25 25
from reply import RPCReply
26 26

  
27

  
27 28
# Cisco does not include message-id attribute in <rpc-reply> in case of an error.
28 29
# This is messed up however we have to deal with it.
29 30
# So essentially, there can be only one operation at a time if we are talking to
30 31
# a Cisco device.
31 32

  
33
def cisco_check(session):
34
    try:
35
        return session.is_remote_cisco
36
    except AttributeError:
37
        return False
38

  
32 39
class RPC(object):
33 40
    
34 41
    def __init__(self, session, async=False):
35
        if session.is_remote_cisco and async:
42
        if cisco_check(session) and async:
36 43
            raise UserWarning('Asynchronous mode not supported for Cisco devices')
37 44
        self._session = session
38 45
        self._async = async
......
120 127
        if instance is None:
121 128
            instance = object.__new__(cls)
122 129
            instance._id2rpc = WeakValueDictionary()
123
            instance._cisco = session.is_remote_cisco
130
            instance._cisco = cisco_check(session)
124 131
            instance._errback = None
125 132
            session.add_listener(instance)
126 133
        return instance
b/ncclient/operations/session.py
15 15
'Session-related NETCONF operations'
16 16

  
17 17
from rpc import RPC
18
from copy import deepcopy
18 19

  
19 20
class CloseSession(RPC):
20 21
    
21 22
    'CloseSession is always synchronous'
22 23
    
23
    def __init__(self, *args, **kwds):
24
        RPC.__init__(self, *args, **kwds)
25
        self.spec = { 'tag': 'close-session' }
24
    SPEC = { 'tag': 'close-session' }
26 25
    
27 26
    def _delivery_hook(self):
28 27
        if self.reply.ok:
......
30 29
        self.session.close()
31 30
    
32 31
    def request(self):
33
        return self._request(self.spec)
32
        return self._request(CloseSession.SPEC)
34 33

  
35 34

  
36 35
class KillSession(RPC):
37 36
    
38
    def __init__(self, *args, **kwds):
39
        RPC.__init__(self, *args, **kwds)
40
        self.spec = {
41
            'tag': 'kill-session',
42
            'children': [ { 'tag': 'session-id', 'text': None} ]
43
            }
37
    SPEC = {
38
        'tag': 'kill-session',
39
        'children': [ { 'tag': 'session-id', 'text': None} ]
40
    }
44 41
    
45 42
    def request(self, session_id):
46
        if not isinstance(session_id, basestring): # just make sure...
43
        if not isinstance(session_id, basestring): # just making sure...
47 44
            session_id = str(session_id)
48
        self.spec['children'][0]['text'] = session_id
49
        return self._request(self.spec)
45
        spec = deepcopy(SPEC)
46
        spec['children'][0]['text'] = session_id
47
        return self._request(spec)
b/ncclient/operations/subscribe.py
12 12
# See the License for the specific language governing permissions and
13 13
# limitations under the License.
14 14

  
15
# TODO...
16

  
15 17
from rpc import RPC
16 18

  
17 19
from ncclient.glue import Listener
18

  
19
from notification import Notification
20
from ncclient.content import NOTIFICATION_NS
21
from ncclient.content import qualify as _
20 22

  
21 23
class CreateSubscription(RPC):    
22 24
    
23
    pass
25
    SPEC = {
26
        'tag': _('create-subscription', NOTIFICATION_NS),
27
        'startTime': None,
28
        'stream': None
29
    }
24 30

  
25 31

  
26 32
class NotificationListener(Listener):

Also available in: Unified diff