Statistics
| Branch: | Tag: | Revision:

root / ncclient / manager.py @ bbd4ce54

History | View | Annotate | Download (5.7 kB)

1
# Copyright 2009 Shikhar Bhushan
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#    http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

    
15
"Thin layer of abstraction around NCClient"
16

    
17
import capabilities
18
import operations
19
import transport
20

    
21
import logging
22
logger = logging.getLogger('ncclient.manager')
23

    
24
def connect_ssh(*args, **kwds):
25
    """Connect to NETCONF server over SSH. See :meth:`SSHSession.connect()
26
    <ncclient.transport.SSHSession.connect>` for function signature."""
27
    session = transport.SSHSession(capabilities.CAPABILITIES)
28
    session.load_known_hosts()
29
    session.connect(*args, **kwds)
30
    return Manager(session)
31

    
32
#: Same as :meth:`connect_ssh`
33
connect = connect_ssh
34

    
35
#: Raise all :class:`~ncclient.operations.rpc.RPCError`
36
RAISE_ALL = 0
37
#: Only raise when *error-severity* is "error" i.e. no warnings
38
RAISE_ERR = 1
39
#: Don't raise any
40
RAISE_NONE = 2
41

    
42
class Manager:
43

    
44
    """API for NETCONF operations. Currently only supports making synchronous
45
    RPC requests.
46

47
    It is also a context manager, so a :class:`Manager` instance can be used
48
    with the *with* statement. The session is closed when the context ends. """
49

    
50
    def __init__(self, session):
51
        self._session = session
52
        self._raise = RAISE_ALL
53

    
54
    def set_rpc_error_action(self, action):
55
        """Specify the action to take when an *<rpc-error>* element is encountered.
56

57
        :arg action: one of :attr:`RAISE_ALL`, :attr:`RAISE_ERR`, :attr:`RAISE_NONE`
58
        """
59
        self._raise = action
60

    
61
    def __enter__(self):
62
        return self
63

    
64
    def __exit__(self, *args):
65
        self.close()
66
        return False
67

    
68
    def do(self, op, *args, **kwds):
69
        op = operations.OPERATIONS[op](self._session)
70
        reply = op.request(*args, **kwds)
71
        if not reply.ok:
72
            if self._raise == RAISE_ALL:
73
                raise reply.error
74
            elif self._raise == RAISE_ERR:
75
                for error in reply.errors:
76
                    if error.severity == 'error':
77
                        raise error
78
        return reply
79

    
80
    #: :see: :meth:`Get.request() <ncclient.operations.Get.request>`
81
    get = lambda self, *args, **kwds: self.do('get', *args, **kwds)
82

    
83
    #: :see: :meth:`GetConfig.request() <ncclient.operations.GetConfig.request>`
84
    get_config = lambda self, *args, **kwds: self.do('get-config', *args, **kwds)
85

    
86
    #: :see: :meth:`EditConfig.request() <ncclient.operations.EditConfig.request>`
87
    edit_config = lambda self, *args, **kwds: self.do('edit-config', *args, **kwds)
88

    
89
    #: :see: :meth:`CopyConfig.request() <ncclient.operations.CopyConfig.request>`
90
    copy_config = lambda self, *args, **kwds: self.do('copy-config', *args, **kwds)
91

    
92
    #: :see: :meth:`GetConfig.request() <ncclient.operations.Validate.request>`
93
    validate = lambda self, *args, **kwds: self.do('validate', *args, **kwds)
94

    
95
    #: :see: :meth:`Commit.request() <ncclient.operations.Commit.request>`
96
    commit = lambda self, *args, **kwds: self.do('commit', *args, **kwds)
97

    
98
    #: :see: :meth:`DiscardChanges.request() <ncclient.operations.DiscardChanges.request>`
99
    discard_changes = lambda self, *args, **kwds: self.do('discard-changes', *args, **kwds)
100

    
101
    #: :see: :meth:`DeleteConfig.request() <ncclient.operations.DeleteConfig.request>`
102
    delete_config = lambda self, *args, **kwds: self.do('delete-config', *args, **kwds)
103

    
104
    #: :see: :meth:`Lock.request() <ncclient.operations.Lock.request>`
105
    lock = lambda self, *args, **kwds: self.do('lock', *args, **kwds)
106

    
107
    #: :see: :meth:`DiscardChanges.request() <ncclient.operations.Unlock.request>`
108
    unlock = lambda self, *args, **kwds: self.do('unlock', *args, **kwds)
109

    
110
    #: :see: :meth:`CloseSession.request() <ncclient.operations.CloseSession.request>`
111
    close_session = lambda self, *args, **kwds: self.do('close-session', *args, **kwds)
112

    
113
    #: :see: :meth:`KillSession.request() <ncclient.operations.KillSession.request>`
114
    kill_session = lambda self, *args, **kwds: self.do('kill-session', *args, **kwds)
115

    
116
    def locked(self, target):
117
        """Returns a context manager for the *with* statement.
118

119
        :arg target: name of the datastore to lock
120
        :type target: `string`
121
        :rtype: :class:`~ncclient.operations.LockContext`
122
        """
123
        return operations.LockContext(self._session, target)
124

    
125
    def close(self):
126
        """Closes the NETCONF session. First does *<close-session>* RPC."""
127
        try: # try doing it clean
128
            self.close_session()
129
        except Exception as e:
130
            logger.debug('error doing <close-session> -- %r' % e)
131
        if self._session.connected: # if that didn't work...
132
            self._session.close()
133

    
134
    @property
135
    def session(self):
136
        ":class:`~ncclient.transport.Session` instance"
137
        return self._session
138

    
139
    @property
140
    def client_capabilities(self):
141
        ":class:`~ncclient.capabilities.Capabilities` object for client"
142
        return self._session._client_capabilities
143

    
144
    @property
145
    def server_capabilities(self):
146
        ":class:`~ncclient.capabilities.Capabilities` object for server"
147
        return self._session._server_capabilities
148

    
149
    @property
150
    def session_id(self):
151
        "*<session-id>* as assigned by NETCONF server"
152
        return self._session.id
153

    
154
    @property
155
    def connected(self):
156
        "Whether currently connected to NETCONF server"
157
        return self._session.connected