misc; no functional changes
[ncclient] / ncclient / operations / edit.py
index 8f72211..f123d50 100644 (file)
 # 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': []}
@@ -38,19 +47,23 @@ class EditConfig(RPC):
         :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')
@@ -58,17 +71,18 @@ class EditConfig(RPC):
                 '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': []}
@@ -80,13 +94,15 @@ class DeleteConfig(RPC):
 
         :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': []}
@@ -101,14 +117,16 @@ class CopyConfig(RPC):
 
         :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']
@@ -122,21 +140,23 @@ class Validate(RPC):
 
         :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']
@@ -159,7 +179,7 @@ class Commit(RPC):
 
         :seealso: :ref:`return`
         """
-        spec = SPEC.copy()
+        spec = deepcopy(Commit.SPEC)
         if confirmed:
             self._assert(':confirmed-commit')
             spec['subtree'].append({'tag': 'confirmed'})
@@ -173,8 +193,14 @@ class Commit(RPC):
 
 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)