Revision 9667bcb2 ncclient/operations/edit.py
b/ncclient/operations/edit.py | ||
---|---|---|
12 | 12 |
# See the License for the specific language governing permissions and |
13 | 13 |
# limitations under the License. |
14 | 14 |
|
15 |
from copy import deepcopy |
|
16 |
|
|
17 |
from ncclient import xml_ |
|
15 |
from ncclient.xml_ import * |
|
18 | 16 |
|
19 | 17 |
from rpc import RPC |
20 | 18 |
|
21 | 19 |
import util |
22 | 20 |
|
23 | 21 |
import logging |
24 |
logger = logging.getLogger('ncclient.operations.edit')
|
|
22 |
logger = logging.getLogger("ncclient.operations.edit")
|
|
25 | 23 |
|
26 | 24 |
"Operations related to changing device configuration" |
27 | 25 |
|
28 | 26 |
class EditConfig(RPC): |
29 | 27 |
|
30 | 28 |
"*<edit-config>* RPC" |
31 |
|
|
32 |
SPEC = {'tag': 'edit-config', 'subtree': []} |
|
33 |
|
|
29 |
|
|
34 | 30 |
def request(self, target, config, default_operation=None, test_option=None, |
35 | 31 |
error_option=None): |
36 | 32 |
""" |
... | ... | |
51 | 47 |
|
52 | 48 |
:seealso: :ref:`return` |
53 | 49 |
""" |
54 |
spec = deepcopy(EditConfig.SPEC) |
|
55 |
subtree = spec['subtree'] |
|
56 |
subtree.append(util.store_or_url('target', target, self._assert)) |
|
50 |
node = new_ele("edit-config") |
|
51 |
node.append(util.datastore_or_url("target", target, self._assert)) |
|
57 | 52 |
if error_option is not None: |
58 |
if error_option == 'rollback-on-error': |
|
59 |
self._assert(':rollback-on-error') |
|
60 |
subtree.append({ |
|
61 |
'tag': 'error-option', |
|
62 |
'text': error_option |
|
63 |
}) |
|
53 |
if error_option == "rollback-on-error": |
|
54 |
self._assert(":rollback-on-error") |
|
55 |
sub_ele(node, "error-option").text = error_option |
|
64 | 56 |
if test_option is not None: |
65 | 57 |
self._assert(':validate') |
66 |
subtree.append({ |
|
67 |
'tag': 'test-option', |
|
68 |
'text': test_option |
|
69 |
}) |
|
58 |
sub_ele(node, "test-option").text = test_option |
|
70 | 59 |
if default_operation is not None: |
71 |
subtree.append({ |
|
72 |
'tag': 'default-operation', |
|
73 |
'text': default_operation |
|
74 |
}) |
|
75 |
subtree.append(xml_.validated_element(config, ('config', xml_.qualify('config')))) |
|
60 |
# TODO: check if it is a valid default-operation |
|
61 |
sub_ele(node, "default-operation").text = default_operation |
|
62 |
node.append(validated_element(config, ("config", qualify("config")))) |
|
76 | 63 |
return self._request(spec) |
77 | 64 |
|
65 |
|
|
78 | 66 |
class DeleteConfig(RPC): |
79 | 67 |
|
80 | 68 |
"*<delete-config>* RPC" |
81 | 69 |
|
82 |
SPEC = {'tag': 'delete-config', 'subtree': []} |
|
83 |
|
|
84 | 70 |
def request(self, target): |
85 | 71 |
""" |
86 | 72 |
:arg target: See :ref:`source_target` |
... | ... | |
88 | 74 |
|
89 | 75 |
:seealso: :ref:`return` |
90 | 76 |
""" |
91 |
spec = deepcopy(DeleteConfig.SPEC)
|
|
92 |
spec['subtree'].append(util.store_or_url('target', target, self._assert))
|
|
77 |
node = new_ele("delete-config")
|
|
78 |
node.append(util.datastore_or_url("target", target, self._assert))
|
|
93 | 79 |
return self._request(spec) |
94 | 80 |
|
95 | 81 |
|
96 | 82 |
class CopyConfig(RPC): |
97 | 83 |
|
98 | 84 |
"*<copy-config>* RPC" |
99 |
|
|
100 |
SPEC = {'tag': 'copy-config', 'subtree': []} |
|
101 |
|
|
85 |
|
|
102 | 86 |
def request(self, source, target): |
103 | 87 |
""" |
104 | 88 |
:arg source: See :ref:`source_target` |
... | ... | |
109 | 93 |
|
110 | 94 |
:seealso: :ref:`return` |
111 | 95 |
""" |
112 |
spec = deepcopy(CopyConfig.SPEC)
|
|
113 |
spec['subtree'].append(util.store_or_url('target', target, self._assert))
|
|
114 |
spec['subtree'].append(util.store_or_url('source', source, self._assert))
|
|
96 |
node = new_ele("copy-config")
|
|
97 |
node.append(util.datastore_or_url("target", target, self._assert))
|
|
98 |
node.append(util.datastore_or_url("source", source, self._assert))
|
|
115 | 99 |
return self._request(spec) |
116 | 100 |
|
117 | 101 |
|
... | ... | |
121 | 105 |
|
122 | 106 |
DEPENDS = [':validate'] |
123 | 107 |
|
124 |
SPEC = {'tag': 'validate', 'subtree': []} |
|
125 |
|
|
126 | 108 |
def request(self, source): |
127 | 109 |
""" |
128 | 110 |
:arg source: See :ref:`source_target` |
... | ... | |
130 | 112 |
|
131 | 113 |
:seealso: :ref:`return` |
132 | 114 |
""" |
133 |
spec = deepcopy(Validate.SPEC)
|
|
115 |
node = new_ele("validate")
|
|
134 | 116 |
try: |
135 |
src = xml_.validated_element(source, ('config', xml_.qualify('config')))
|
|
117 |
src = validated_element(source, ("config", qualify("config")))
|
|
136 | 118 |
except Exception as e: |
137 | 119 |
logger.debug(e) |
138 |
src = util.store_or_url('source', source, self._assert) |
|
139 |
spec['subtree'].append({ |
|
140 |
'tag': 'source', |
|
141 |
'subtree': src |
|
142 |
}) |
|
120 |
src = util.datastore_or_url("source", source, self._assert) |
|
121 |
(node if src.tag == "source" else sub_ele(node, "source")).append(src) |
|
143 | 122 |
return self._request(spec) |
144 | 123 |
|
145 | 124 |
|
... | ... | |
148 | 127 |
"*<commit>* RPC. Depends on the *:candidate* capability." |
149 | 128 |
|
150 | 129 |
DEPENDS = [':candidate'] |
151 |
|
|
152 |
SPEC = {'tag': 'commit', 'subtree': []} |
|
153 |
|
|
154 |
def _parse_hook(self): |
|
155 |
pass |
|
156 |
|
|
130 |
|
|
157 | 131 |
def request(self, confirmed=False, timeout=None): |
158 | 132 |
""" |
159 | 133 |
Requires *:confirmed-commit* capability if *confirmed* argument is |
... | ... | |
167 | 141 |
|
168 | 142 |
:seealso: :ref:`return` |
169 | 143 |
""" |
170 |
spec = deepcopy(Commit.SPEC)
|
|
144 |
node = new_ele("commit")
|
|
171 | 145 |
if confirmed: |
172 |
self._assert(':confirmed-commit')
|
|
173 |
spec['subtree'].append({'tag': 'confirmed'})
|
|
146 |
self._assert(":confirmed-commit")
|
|
147 |
sub_ele(node, "confirmed")
|
|
174 | 148 |
if timeout is not None: |
175 |
spec['subtree'].append({ |
|
176 |
'tag': 'confirm-timeout', |
|
177 |
'text': timeout |
|
178 |
}) |
|
149 |
# TODO check if timeout is a valid integer? |
|
150 |
sub_ele(node, "confirm-timeout").text = timeout |
|
179 | 151 |
return self._request(Commit.SPEC) |
180 | 152 |
|
181 | 153 |
|
182 | 154 |
class DiscardChanges(RPC): |
183 | 155 |
|
184 |
# TESTED |
|
185 |
|
|
186 | 156 |
"*<discard-changes>* RPC. Depends on the *:candidate* capability." |
187 | 157 |
|
188 |
DEPENDS = [':candidate'] |
|
189 |
|
|
190 |
SPEC = {'tag': 'discard-changes'} |
|
158 |
DEPENDS = [":candidate"] |
|
191 | 159 |
|
192 | 160 |
def request(self): |
193 | 161 |
":seealso: :ref:`return`" |
194 |
return self._request(DiscardChanges.SPEC)
|
|
162 |
return self._request(new_ele("discard-changes"))
|
Also available in: Unified diff