Statistics
| Branch: | Tag: | Revision:

root / ncclient / operations / edit.py @ 2abf9522

History | View | Annotate | Download (5.8 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
from copy import deepcopy
16

    
17
from ncclient import content
18

    
19
from rpc import RPC
20

    
21
import util
22

    
23
import logging
24
logger = logging.getLogger('ncclient.operations.edit')
25

    
26

    
27

    
28
"Operations related to changing device configuration"
29

    
30
class EditConfig(RPC):
31

    
32
    # TESTED
33

    
34
    "*<edit-config>* RPC"
35

    
36
    SPEC = {'tag': 'edit-config', 'subtree': []}
37

    
38
    def request(self, target, config, default_operation=None, test_option=None,
39
                error_option=None):
40
        """
41
        :arg target: see :ref:`source_target`
42
        :type target: string
43

44
        :arg config: a config element in :ref:`dtree`
45
        :type config: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
46

47
        :arg default_operation: optional; one of {'merge', 'replace', 'none'}
48
        :type default_operation: `string`
49

50
        :arg error_option: optional; one of {'stop-on-error', 'continue-on-error', 'rollback-on-error'}. Last option depends on the *:rollback-on-error* capability
51
        :type error_option: string
52

53
        :arg test_option: optional; one of {'test-then-set', 'set'}. Depends on *:validate* capability.
54
        :type test_option: string
55

56
        :seealso: :ref:`return`
57
        """
58
        spec = deepcopy(EditConfig.SPEC)
59
        subtree = spec['subtree']
60
        subtree.append(util.store_or_url('target', target, self._assert))
61
        if error_option is not None:
62
            if error_option == 'rollback-on-error':
63
                self._assert(':rollback-on-error')
64
            subtree.append({
65
                'tag': 'error-option',
66
                'text': error_option
67
                })
68
        if test_option is not None:
69
            self._assert(':validate')
70
            subtree.append({
71
                'tag': 'test-option',
72
                'text': test_option
73
                })
74
        if default_operation is not None:
75
            subtree.append({
76
                'tag': 'default-operation',
77
                'text': default_operation
78
                })
79
        subtree.append(content.validated_element(config, ('config', content.qualify('config'))))
80
        return self._request(spec)
81

    
82
class DeleteConfig(RPC):
83

    
84
    # TESTED
85

    
86
    "*<delete-config>* RPC"
87

    
88
    SPEC = {'tag': 'delete-config', 'subtree': []}
89

    
90
    def request(self, target):
91
        """
92
        :arg target: See :ref:`source_target`
93
        :type target: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
94

95
        :seealso: :ref:`return`
96
        """
97
        spec = deepcopy(DeleteConfig.SPEC)
98
        spec['subtree'].append(util.store_or_url('target', target, self._assert))
99
        return self._request(spec)
100

    
101

    
102
class CopyConfig(RPC):
103

    
104
    # TESTED
105

    
106
    "*<copy-config>* RPC"
107

    
108
    SPEC = {'tag': 'copy-config', 'subtree': []}
109

    
110
    def request(self, source, target):
111
        """
112
        :arg source: See :ref:`source_target`
113
        :type source: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
114

115
        :arg target: See :ref:`source_target`
116
        :type target: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
117

118
        :seealso: :ref:`return`
119
        """
120
        spec = deepcopy(CopyConfig.SPEC)
121
        spec['subtree'].append(util.store_or_url('target', target, self._assert))
122
        spec['subtree'].append(util.store_or_url('source', source, self._assert))
123
        return self._request(spec)
124

    
125

    
126
class Validate(RPC):
127

    
128
    # TESTED
129

    
130
    "*<validate>* RPC. Depends on the *:validate* capability."
131

    
132
    DEPENDS = [':validate']
133

    
134
    SPEC = {'tag': 'validate', 'subtree': []}
135

    
136
    def request(self, source):
137
        """
138
        :arg source: See :ref:`source_target`
139
        :type source: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
140

141
        :seealso: :ref:`return`
142
        """
143
        spec = deepcopy(Validate.SPEC)
144
        try:
145
            src = content.validated_element(source, ('config', content.qualify('config')))
146
        except Exception as e:
147
            logger.debug(e)
148
            src = util.store_or_url('source', source, self._assert)
149
        spec['subtree'].append({
150
            'tag': 'source',
151
            'subtree': src
152
            })
153
        return self._request(spec)
154

    
155

    
156
class Commit(RPC):
157

    
158
    # TESTED
159

    
160
    "*<commit>* RPC. Depends on the *:candidate* capability."
161

    
162
    DEPENDS = [':candidate']
163

    
164
    SPEC = {'tag': 'commit', 'subtree': []}
165

    
166
    def _parse_hook(self):
167
        pass
168

    
169
    def request(self, confirmed=False, timeout=None):
170
        """
171
        Requires *:confirmed-commit* capability if *confirmed* argument is
172
        :const:`True`.
173

174
        :arg confirmed: optional; request a confirmed commit
175
        :type confirmed: `bool`
176

177
        :arg timeout: specify timeout for confirmed commit
178
        :type timeout: `int`
179

180
        :seealso: :ref:`return`
181
        """
182
        spec = deepcopy(Commit.SPEC)
183
        if confirmed:
184
            self._assert(':confirmed-commit')
185
            spec['subtree'].append({'tag': 'confirmed'})
186
            if timeout is not None:
187
                spec['subtree'].append({
188
                    'tag': 'confirm-timeout',
189
                    'text': timeout
190
                })
191
        return self._request(Commit.SPEC)
192

    
193

    
194
class DiscardChanges(RPC):
195

    
196
    # TESTED
197

    
198
    "*<discard-changes>* RPC. Depends on the *:candidate* capability."
199

    
200
    DEPENDS = [':candidate']
201

    
202
    SPEC = {'tag': 'discard-changes'}
203

    
204
    def request(self):
205
        ":seealso: :ref:`return`"
206
        return self._request(DiscardChanges.SPEC)