Statistics
| Branch: | Tag: | Revision:

root / ncclient / operations / edit.py @ dd225c7a

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 xml_
18

    
19
from rpc import RPC
20

    
21
import util
22

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

    
26
"Operations related to changing device configuration"
27

    
28
class EditConfig(RPC):
29

    
30
    "*<edit-config>* RPC"
31

    
32
    SPEC = {'tag': 'edit-config', 'subtree': []}
33

    
34
    def request(self, target, config, default_operation=None, test_option=None,
35
                error_option=None):
36
        """
37
        :arg target: see :ref:`source_target`
38
        :type target: string
39

40
        :arg config: a config element in :ref:`dtree`
41
        :type config: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
42

43
        :arg default_operation: optional; one of {'merge', 'replace', 'none'}
44
        :type default_operation: `string`
45

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

49
        :arg test_option: optional; one of {'test-then-set', 'set'}. Depends on *:validate* capability.
50
        :type test_option: string
51

52
        :seealso: :ref:`return`
53
        """
54
        spec = deepcopy(EditConfig.SPEC)
55
        subtree = spec['subtree']
56
        subtree.append(util.store_or_url('target', target, self._assert))
57
        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
                })
64
        if test_option is not None:
65
            self._assert(':validate')
66
            subtree.append({
67
                'tag': 'test-option',
68
                'text': test_option
69
                })
70
        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'))))
76
        return self._request(spec)
77

    
78
class DeleteConfig(RPC):
79

    
80
    "*<delete-config>* RPC"
81

    
82
    SPEC = {'tag': 'delete-config', 'subtree': []}
83

    
84
    def request(self, target):
85
        """
86
        :arg target: See :ref:`source_target`
87
        :type target: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
88

89
        :seealso: :ref:`return`
90
        """
91
        spec = deepcopy(DeleteConfig.SPEC)
92
        spec['subtree'].append(util.store_or_url('target', target, self._assert))
93
        return self._request(spec)
94

    
95

    
96
class CopyConfig(RPC):
97

    
98
    "*<copy-config>* RPC"
99

    
100
    SPEC = {'tag': 'copy-config', 'subtree': []}
101

    
102
    def request(self, source, target):
103
        """
104
        :arg source: See :ref:`source_target`
105
        :type source: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
106

107
        :arg target: See :ref:`source_target`
108
        :type target: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
109

110
        :seealso: :ref:`return`
111
        """
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))
115
        return self._request(spec)
116

    
117

    
118
class Validate(RPC):
119

    
120
    "*<validate>* RPC. Depends on the *:validate* capability."
121

    
122
    DEPENDS = [':validate']
123

    
124
    SPEC = {'tag': 'validate', 'subtree': []}
125

    
126
    def request(self, source):
127
        """
128
        :arg source: See :ref:`source_target`
129
        :type source: `string` or `dict` or :class:`~xml.etree.ElementTree.Element`
130

131
        :seealso: :ref:`return`
132
        """
133
        spec = deepcopy(Validate.SPEC)
134
        try:
135
            src = markup.validated_element(source, ('config', markup.qualify('config')))
136
        except Exception as e:
137
            logger.debug(e)
138
            src = util.store_or_url('source', source, self._assert)
139
        spec['subtree'].append({
140
            'tag': 'source',
141
            'subtree': src
142
            })
143
        return self._request(spec)
144

    
145

    
146
class Commit(RPC):
147

    
148
    "*<commit>* RPC. Depends on the *:candidate* capability."
149

    
150
    DEPENDS = [':candidate']
151

    
152
    SPEC = {'tag': 'commit', 'subtree': []}
153

    
154
    def _parse_hook(self):
155
        pass
156

    
157
    def request(self, confirmed=False, timeout=None):
158
        """
159
        Requires *:confirmed-commit* capability if *confirmed* argument is
160
        :const:`True`.
161

162
        :arg confirmed: optional; request a confirmed commit
163
        :type confirmed: `bool`
164

165
        :arg timeout: specify timeout for confirmed commit
166
        :type timeout: `int`
167

168
        :seealso: :ref:`return`
169
        """
170
        spec = deepcopy(Commit.SPEC)
171
        if confirmed:
172
            self._assert(':confirmed-commit')
173
            spec['subtree'].append({'tag': 'confirmed'})
174
            if timeout is not None:
175
                spec['subtree'].append({
176
                    'tag': 'confirm-timeout',
177
                    'text': timeout
178
                })
179
        return self._request(Commit.SPEC)
180

    
181

    
182
class DiscardChanges(RPC):
183

    
184
    # TESTED
185

    
186
    "*<discard-changes>* RPC. Depends on the *:candidate* capability."
187

    
188
    DEPENDS = [':candidate']
189

    
190
    SPEC = {'tag': 'discard-changes'}
191

    
192
    def request(self):
193
        ":seealso: :ref:`return`"
194
        return self._request(DiscardChanges.SPEC)