# See the License for the specific language governing permissions and
# limitations under the License.
+from copy import deepcopy
+
from ncclient import content
from rpc import RPC
import util
+import logging
+logger = logging.getLogger('ncclient.operations.edit')
+
+
+
"Operations related to changing device configuration"
class EditConfig(RPC):
+ # TESTED
+
"*<edit-config>* RPC"
SPEC = {'tag': 'edit-config', 'subtree': []}
:arg default_operation: optional; one of {'merge', 'replace', 'none'}
:type default_operation: `string`
- :arg test_option: optional; one of {'stop-on-error', 'continue-on-error', 'rollback-on-error'}. Last option depends on the *:rollback-on-error* capability
+ :arg error_option: optional; one of {'stop-on-error', 'continue-on-error', 'rollback-on-error'}. Last option depends on the *:rollback-on-error* capability
+ :type error_option: string
+
+ :arg test_option: optional; one of {'test-then-set', 'set'}. Depends on *:validate* capability.
:type test_option: string
:seealso: :ref:`return`
"""
- spec = EditConfig.SPEC.copy()
+ spec = deepcopy(EditConfig.SPEC)
subtree = spec['subtree']
subtree.append(util.store_or_url('target', target, self._assert))
- subtree.append(content.validated_element(config, ('config', content.qualify('config'))))
- if default_operation is not None:
+ if error_option is not None:
+ if error_option == 'rollback-on-error':
+ self._assert(':rollback-on-error')
subtree.append({
- 'tag': 'default-operation',
- 'text': default_operation
+ 'tag': 'error-option',
+ 'text': error_option
})
if test_option is not None:
self._assert(':validate')
'tag': 'test-option',
'text': test_option
})
- if error_option is not None:
- if error_option == 'rollback-on-error':
- self._assert(':rollback-on-error')
+ if default_operation is not None:
subtree.append({
- 'tag': 'error-option',
- 'text': error_option
+ 'tag': 'default-operation',
+ 'text': default_operation
})
+ subtree.append(content.validated_element(config, ('config', content.qualify('config'))))
return self._request(spec)
class DeleteConfig(RPC):
+ # TESTED
+
"*<delete-config>* RPC"
SPEC = {'tag': 'delete-config', 'subtree': []}
:seealso: :ref:`return`
"""
- spec = DeleteConfig.SPEC.copy()
+ spec = deepcopy(DeleteConfig.SPEC)
spec['subtree'].append(util.store_or_url('target', target, self._assert))
return self._request(spec)
class CopyConfig(RPC):
+ # TESTED
+
"*<copy-config>* RPC"
SPEC = {'tag': 'copy-config', 'subtree': []}
:seealso: :ref:`return`
"""
- spec = CopyConfig.SPEC.copy()
- spec['subtree'].append(util.store_or_url('source', source, self._assert))
+ spec = deepcopy(CopyConfig.SPEC)
spec['subtree'].append(util.store_or_url('target', target, self._assert))
+ spec['subtree'].append(util.store_or_url('source', source, self._assert))
return self._request(spec)
class Validate(RPC):
+ # TESTED
+
"*<validate>* RPC. Depends on the *:validate* capability."
DEPENDS = [':validate']
:seealso: :ref:`return`
"""
- spec = Validate.SPEC.copy()
+ spec = deepcopy(Validate.SPEC)
try:
- spec['subtree'].append({
- 'tag': 'source',
- 'subtree':
- content.validated_element(
- config, ('config', content.qualify('config')))
- })
- except:
- spec['subtree'].append(util.store_or_url('source', source, self._assert))
+ src = content.validated_element(source, ('config', content.qualify('config')))
+ except Exception as e:
+ logger.debug(e)
+ src = util.store_or_url('source', source, self._assert)
+ spec['subtree'].append({
+ 'tag': 'source',
+ 'subtree': src
+ })
return self._request(spec)
class Commit(RPC):
+ # TESTED
+
"*<commit>* RPC. Depends on the *:candidate* capability."
DEPENDS = [':candidate']
:seealso: :ref:`return`
"""
- spec = SPEC.copy()
+ spec = deepcopy(Commit.SPEC)
if confirmed:
self._assert(':confirmed-commit')
spec['subtree'].append({'tag': 'confirmed'})
class DiscardChanges(RPC):
+ # TESTED
+
"*<discard-changes>* RPC. Depends on the *:candidate* capability."
DEPENDS = [':candidate']
SPEC = {'tag': 'discard-changes'}
+
+ def request(self):
+ ":seealso: :ref:`return`"
+ return self._request(DiscardChanges.SPEC)