Statistics
| Branch: | Tag: | Revision:

root / ncclient / operations / edit.py @ ce5fb329

History | View | Annotate | Download (5.6 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
    "*<edit-config>* RPC"
33

    
34
    SPEC = {'tag': 'edit-config', 'subtree': []}
35

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

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

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

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

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

    
77
class DeleteConfig(RPC):
78

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

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

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

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

    
94

    
95
class CopyConfig(RPC):
96

    
97
    # TESTED
98

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

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

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

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

111
        :seealso: :ref:`return`
112
        """
113
        spec = deepcopy(CopyConfig.SPEC)
114
        spec['subtree'].append(util.store_or_url('target', target, self._assert))
115
        spec['subtree'].append(util.store_or_url('source', source, self._assert))
116
        return self._request(spec)
117

    
118

    
119
class Validate(RPC):
120

    
121
    # TESTED
122

    
123
    "*<validate>* RPC. Depends on the *:validate* capability."
124

    
125
    DEPENDS = [':validate']
126

    
127
    SPEC = {'tag': 'validate', 'subtree': []}
128

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

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

    
148

    
149
class Commit(RPC):
150

    
151
    "*<commit>* RPC. Depends on the *:candidate* capability."
152

    
153
    DEPENDS = [':candidate']
154

    
155
    SPEC = {'tag': 'commit', 'subtree': []}
156

    
157
    def _parse_hook(self):
158
        pass
159

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

165
        :arg confirmed: optional; request a confirmed commit
166
        :type confirmed: `bool`
167

168
        :arg timeout: specify timeout for confirmed commit
169
        :type timeout: `int`
170

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

    
184

    
185
class DiscardChanges(RPC):
186

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

    
189
    DEPENDS = [':candidate']
190

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

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