Statistics
| Branch: | Tag: | Revision:

root / ncclient / manager.py @ 4bc8021f

History | View | Annotate | Download (6.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
"This module is a thin layer of abstraction around the library. It exposes all core functionality."
16

    
17
import capabilities
18
import operations
19
import transport
20

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

    
24

    
25
CAPABILITIES = capabilities.Capabilities([
26
    "urn:ietf:params:netconf:base:1.0",
27
    "urn:ietf:params:netconf:capability:writable-running:1.0",
28
    "urn:ietf:params:netconf:capability:candidate:1.0",
29
    "urn:ietf:params:netconf:capability:confirmed-commit:1.0",
30
    "urn:ietf:params:netconf:capability:rollback-on-error:1.0",
31
    "urn:ietf:params:netconf:capability:startup:1.0",
32
    "urn:ietf:params:netconf:capability:url:1.0?scheme=http,ftp,file,https,sftp",
33
    "urn:ietf:params:netconf:capability:validate:1.0",
34
    "urn:ietf:params:netconf:capability:xpath:1.0",
35
    "urn:liberouter:params:netconf:capability:power-control:1.0"
36
    "urn:ietf:params:netconf:capability:interleave:1.0"
37
    #'urn:ietf:params:netconf:capability:notification:1.0', # TODO    
38
])
39
"""`~ncclient.capabilities.Capabilities` object representing the client's capabilities. This is used
40
during the initial capability exchange. Modify this if you need to announce some capability not
41
already included.
42
"""
43

    
44
OPERATIONS = {
45
    "get": operations.Get,
46
    "get_config": operations.GetConfig,
47
    "edit_config": operations.EditConfig,
48
    "copy_config": operations.CopyConfig,
49
    "validate": operations.Validate,
50
    "commit": operations.Commit,
51
    "discard_changes": operations.DiscardChanges,
52
    "delete_config": operations.DeleteConfig,
53
    "lock": operations.Lock,
54
    "unlock": operations.Unlock,
55
    "close_session": operations.CloseSession,
56
    "kill_session": operations.KillSession,
57
    "poweroff_machine": operations.PoweroffMachine,
58
    "reboot_machine": operations.RebootMachine
59
}
60
"""Dictionary of method names and corresponding `~ncclient.operations.RPC` subclasses. `Manager`
61
uses this to lookup operations, e.g. "get_config" is mapped to `~ncclient.operations.GetConfig`. It
62
is thus possible to add additional operations to the `Manager` API.
63
"""
64

    
65
def connect_ssh(*args, **kwds):
66
    """Initializes a NETCONF session over SSH, and creates a connected `Manager` instance. *host*
67
    must be specified, all the other arguments are optional and depend on the kind of host key
68
    verification and user authentication you want to complete.
69
        
70
    For the purpose of host key verification, on -NIX systems a user's :file:`~/.ssh/known_hosts`
71
    file is automatically considered. The *unknown_host_cb* argument specifies a callback that will
72
    be invoked when the server's host key cannot be verified. See
73
    :func:`~ncclient.transport.ssh.default_unknown_host_cb` for function signature.
74
    
75
    First, ``publickey`` authentication is attempted. If a specific *key_filename* is specified, it
76
    will be loaded and authentication attempted using it. If *allow_agent* is :const:`True` and an
77
    SSH agent is running, the keys provided by the agent will be tried. If *look_for_keys* is
78
    :const:`True`, keys in the :file:`~/.ssh/id_rsa` and :file:`~.ssh/id_dsa` will be tried. In case
79
    an encrypted key file is encountered, the *password* argument will be used as a decryption
80
    passphrase.
81
    
82
    If ``publickey`` authentication fails and the *password* argument has been supplied,
83
    ``password`` / ``keyboard-interactive`` SSH authentication will be attempted.
84
    
85
    :param host: hostname or address on which to connect
86
    :type host: `string`
87
    
88
    :param port: port on which to connect
89
    :type port: `int`
90
    
91
    :param timeout: timeout for socket connect
92
    :type timeout: `int`
93
    
94
    :param unknown_host_cb: optional; callback that is invoked when host key verification fails
95
    :type unknown_host_cb: `function`
96
    
97
    :param username: username to authenticate with, if not specified the username of the logged-in user is used
98
    :type username: `string`
99
    
100
    :param password: password for ``password`` authentication or passphrase for decrypting private key files
101
    :type password: `string`
102
    
103
    :param key_filename: location of a private key file on the file system
104
    :type key_filename: `string`
105
    
106
    :param allow_agent: whether to try connecting to SSH agent for keys
107
    :type allow_agent: `bool`
108
    
109
    :param look_for_keys: whether to look in usual locations for keys
110
    :type look_for_keys: `bool`
111
    
112
    :raises: :exc:`~ncclient.transport.SSHUnknownHostError`
113
    :raises: :exc:`~ncclient.transport.AuthenticationError`
114
    
115
    :rtype: `Manager`
116
    """    
117
    session = transport.SSHSession(CAPABILITIES)
118
    session.load_known_hosts()
119
    session.connect(*args, **kwds)
120
    return Manager(session)
121

    
122
connect = connect_ssh
123
"Same as :func:`connect_ssh`, since SSH is the default (and currently, the only) transport."
124

    
125
class Manager(object):
126

    
127
    def __init__(self, session):
128
        self._session = session
129
        self._async_mode = False
130
        self._timeout = None
131
        self._raise_mode = 'all'
132

    
133
    def __enter__(self):
134
        return self
135

    
136
    def __exit__(self, *argss):
137
        self.close_session()
138
        return False
139

    
140
    def __getattr__(self, name):
141
        op = OPERATIONS.get(name, None)
142
        if op is None:
143
            raise AttributeError
144
        else:
145
            return op(self._session,
146
                      async=self._async_mode,
147
                      timeout=self._timeout,
148
                      raise_mode=self._raise_mode).request
149
    
150
    def locked(self, target):
151
        return operations.LockContext(self._session, target)
152
    
153
    @property
154
    def client_capabilities(self):
155
        return self._session._client_capabilities
156

    
157
    @property
158
    def server_capabilities(self):
159
        return self._session._server_capabilities
160

    
161
    @property
162
    def session_id(self):
163
        return self._session.id
164

    
165
    @property
166
    def connected(self):
167
        return self._session.connected
168

    
169
    def set_async_mode(self, mode):
170
        self._async_mode = mode
171

    
172
    def set_raise_mode(self, mode):
173
        assert(choice in ("all", "errors", "none"))
174
        self._raise_mode = mode
175

    
176
    async_mode = property(fget=lambda self: self._async_mode, fset=set_async_mode)
177

    
178
    raise_mode = property(fget=lambda self: self._raise_mode, fset=set_raise_mode)