Revision b2d60e49 ncclient/manager.py
b/ncclient/manager.py | ||
---|---|---|
19 | 19 |
import transport |
20 | 20 |
|
21 | 21 |
import logging |
22 |
|
|
22 | 23 |
logger = logging.getLogger('ncclient.manager') |
23 | 24 |
|
24 | 25 |
CAPABILITIES = [ |
... | ... | |
33 | 34 |
"urn:ietf:params:netconf:capability:xpath:1.0", |
34 | 35 |
"urn:liberouter:params:netconf:capability:power-control:1.0" |
35 | 36 |
"urn:ietf:params:netconf:capability:interleave:1.0" |
36 |
#'urn:ietf:params:netconf:capability:notification:1.0', # TODO |
|
37 | 37 |
] |
38 |
"""A list of URI's representing the client's capabilities. This is used during the initial |
|
39 |
capability exchange. Modify this if you need to announce some capability not already included. |
|
40 |
""" |
|
38 |
"A list of URI's representing the client's capabilities. This is used during the initial capability exchange. Modify this if you need to announce some capability not already included." |
|
41 | 39 |
|
42 | 40 |
OPERATIONS = { |
43 | 41 |
"get": operations.Get, |
... | ... | |
55 | 53 |
"poweroff_machine": operations.PoweroffMachine, |
56 | 54 |
"reboot_machine": operations.RebootMachine |
57 | 55 |
} |
58 |
"""Dictionary of method names and corresponding `~ncclient.operations.RPC` subclasses. It is used to |
|
59 |
lookup operations, e.g. "get_config" is mapped to `~ncclient.operations.GetConfig`. It is thus |
|
60 |
possible to add additional operations to the `Manager` API.""" |
|
56 |
"""Dictionary of method names and corresponding `~ncclient.operations.RPC` subclasses. It is used to lookup operations, e.g. "get_config" is mapped to `~ncclient.operations.GetConfig`. It is thus possible to add additional operations to the `Manager` API.""" |
|
61 | 57 |
|
62 | 58 |
def connect_ssh(*args, **kwds): |
63 |
"""Initializes a NETCONF session over SSH, and creates a connected `Manager` instance. *host* |
|
64 |
must be specified, all the other arguments are optional and depend on the kind of host key |
|
65 |
verification and user authentication you want to complete. |
|
59 |
"""Initializes a NETCONF session over SSH, and creates a connected `Manager` instance. *host* must be specified, all the other arguments are optional and depend on the kind of host key verification and user authentication you want to complete. |
|
66 | 60 |
|
67 |
For the purpose of host key verification, on -NIX systems a user's :file:`~/.ssh/known_hosts` |
|
68 |
file is automatically considered. The *unknown_host_cb* argument specifies a callback that will |
|
69 |
be invoked when the server's host key cannot be verified. See |
|
70 |
:func:`~ncclient.transport.ssh.default_unknown_host_cb` for function signature. |
|
61 |
For the purpose of host key verification, on -NIX systems a user's :file:`~/.ssh/known_hosts` file is automatically considered. The *unknown_host_cb* argument specifies a callback that will be invoked when the server's host key cannot be verified. See :func:`~ncclient.transport.ssh.default_unknown_host_cb` for function signature. |
|
71 | 62 |
|
72 | 63 |
First, ``publickey`` authentication is attempted. If a specific *key_filename* is specified, it |
73 | 64 |
will be loaded and authentication attempted using it. If *allow_agent* is :const:`True` and an |
... | ... | |
76 | 67 |
an encrypted key file is encountered, the *password* argument will be used as a decryption |
77 | 68 |
passphrase. |
78 | 69 |
|
79 |
If ``publickey`` authentication fails and the *password* argument has been supplied, |
|
80 |
``password`` / ``keyboard-interactive`` SSH authentication will be attempted. |
|
70 |
If ``publickey`` authentication fails and the *password* argument has been supplied, ``password`` / ``keyboard-interactive`` SSH authentication will be attempted. |
|
81 | 71 |
|
82 | 72 |
:param host: hostname or address on which to connect |
83 | 73 |
:type host: `string` |
... | ... | |
110 | 100 |
:raises: :exc:`~ncclient.transport.AuthenticationError` |
111 | 101 |
|
112 | 102 |
:rtype: `Manager` |
113 |
"""
|
|
103 |
""" |
|
114 | 104 |
session = transport.SSHSession(capabilities.Capabilities(CAPABILITIES)) |
115 | 105 |
session.load_known_hosts() |
116 | 106 |
session.connect(*args, **kwds) |
... | ... | |
119 | 109 |
connect = connect_ssh |
120 | 110 |
"Same as :func:`connect_ssh`, since SSH is the default (and currently, the only) transport." |
121 | 111 |
|
112 |
class OpExecutor(type): |
|
113 |
def __new__(cls, name, bases, attrs): |
|
114 |
def make_wrapper(op_cls): |
|
115 |
def wrapper(self, *args, **kwds): |
|
116 |
return self.execute(op_cls, *args, **kwds) |
|
117 |
wrapper.func_doc = op_cls.request.func_doc |
|
118 |
return wrapper |
|
119 |
for op_name, op_cls in OPERATIONS.iteritems(): |
|
120 |
attrs[op_name] = make_wrapper(op_cls) |
|
121 |
return super(OpExecutor, cls).__new__(cls, name, bases, attrs) |
|
122 |
|
|
122 | 123 |
class Manager(object): |
123 | 124 |
|
125 |
__metaclass__ = OpExecutor |
|
126 |
|
|
127 |
RAISE_NONE = 0 |
|
128 |
RAISE_ERRORS = 1 |
|
129 |
RAISE_ALL = 2 |
|
130 |
|
|
124 | 131 |
def __init__(self, session): |
125 | 132 |
self._session = session |
126 | 133 |
self._async_mode = False |
127 | 134 |
self._timeout = None |
128 |
self._raise_mode = 'all'
|
|
135 |
self._raise_mode = self.RAISE_ALL
|
|
129 | 136 |
|
130 | 137 |
def __enter__(self): |
131 | 138 |
return self |
132 | 139 |
|
133 |
def __exit__(self, *argss):
|
|
140 |
def __exit__(self, *args): |
|
134 | 141 |
self.close_session() |
135 | 142 |
return False |
136 | 143 |
|
137 |
def __getattr__(self, name): |
|
138 |
op = OPERATIONS.get(name, None) |
|
139 |
if op is None: |
|
140 |
raise AttributeError |
|
141 |
else: |
|
142 |
return op(self._session, |
|
143 |
async=self._async_mode, |
|
144 |
timeout=self._timeout, |
|
145 |
raise_mode=self._raise_mode).request |
|
146 |
|
|
144 |
def execute(self, cls, *args, **kwds): |
|
145 |
return cls(self._session, |
|
146 |
async=self._async_mode, |
|
147 |
timeout=self._timeout, |
|
148 |
raise_mode=self._raise_mode).request(*args, **kwds) |
|
149 |
|
|
147 | 150 |
def locked(self, target): |
148 | 151 |
return operations.LockContext(self._session, target) |
149 |
|
|
152 |
|
|
150 | 153 |
@property |
151 | 154 |
def client_capabilities(self): |
152 | 155 |
return self._session._client_capabilities |
... | ... | |
167 | 170 |
self._async_mode = mode |
168 | 171 |
|
169 | 172 |
def set_raise_mode(self, mode): |
170 |
assert(choice in ("all", "errors", "none"))
|
|
173 |
assert(choice in (self.RAISE_NONE, self.RAISE_ERRORS, self.RAISE_ALL))
|
|
171 | 174 |
self._raise_mode = mode |
172 | 175 |
|
173 | 176 |
async_mode = property(fget=lambda self: self._async_mode, fset=set_async_mode) |
Also available in: Unified diff