Browse code

Fix rollback in junos_config (#31424) (#31563)

* Fix rollback in junos_config (#31424)

* Fix rollback in junos_config

Fixes #30778

* Call `load_configuration` with rollback id in case
the id is given as input
* Pass rollback id to `get_diff()` to fetch diff from device

* Fix unit test

(cherry picked from commit 88da95bb77cf20f56035e7ba5d0230c0a2785f2b)

* Update changelog

Ganesh Nalawade authored on 2017/10/11 18:58:42
Showing 5 changed files
... ...
@@ -123,6 +123,7 @@ Ansible Changes By Release
123 123
 * Fix for aws_s3 metadata to use the correct parameters when uploading a file (https://github.com/ansible/ansible/issues/31232)
124 124
 * Fix for the yum module when installing from file/url crashes (https://github.com/ansible/ansible/pull/31529)
125 125
 * Improved error messaging for Windows become/runas when username is bogus (https://github.com/ansible/ansible/pull/31551)
126
+* Fix rollback feature in junos_config to now allow configuration rollback on device (https://github.com/ansible/ansible/pull/31424)
126 127
 
127 128
 <a id="2.4"></a>
128 129
 
... ...
@@ -178,9 +178,9 @@ def locked_config(module):
178 178
         unlock_configuration(module)
179 179
 
180 180
 
181
-def get_diff(module):
181
+def get_diff(module, rollback='0'):
182 182
 
183
-    reply = get_configuration(module, compare=True, format='text')
183
+    reply = get_configuration(module, compare=True, format='text', rollback=rollback)
184 184
     # if warning is received from device diff is empty.
185 185
     if isinstance(reply, list):
186 186
         return None
... ...
@@ -191,7 +191,7 @@ import json
191 191
 from ansible.module_utils.basic import AnsibleModule
192 192
 from ansible.module_utils.junos import get_diff, load_config, get_configuration
193 193
 from ansible.module_utils.junos import commit_configuration, discard_changes, locked_config
194
-from ansible.module_utils.junos import junos_argument_spec
194
+from ansible.module_utils.junos import junos_argument_spec, load_configuration
195 195
 from ansible.module_utils.junos import check_args as junos_check_args
196 196
 from ansible.module_utils.netconf import send_request
197 197
 from ansible.module_utils.six import string_types
... ...
@@ -227,8 +227,8 @@ def zeroize(ele):
227 227
     return send_request(ele, Element('request-system-zeroize'))
228 228
 
229 229
 
230
-def rollback(ele):
231
-    return get_diff(ele)
230
+def rollback(ele, id='0'):
231
+    return get_diff(ele, id)
232 232
 
233 233
 
234 234
 def guess_format(config):
... ...
@@ -346,9 +346,16 @@ def main():
346 346
 
347 347
         result['__backup__'] = match.text.strip()
348 348
 
349
-    if module.params['rollback']:
349
+    rollback_id = module.params['rollback']
350
+    if rollback_id:
351
+        diff = rollback(module, rollback_id)
350 352
         if commit:
351
-            diff = rollback(module)
353
+            kwargs = {
354
+                'comment': module.params['comment']
355
+            }
356
+            with locked_config(module):
357
+                load_configuration(module, rollback=rollback_id)
358
+                commit_configuration(module, **kwargs)
352 359
             if module._diff:
353 360
                 result['diff'] = {'prepared': diff}
354 361
         result['changed'] = True
... ...
@@ -41,6 +41,37 @@
41 41
     that:
42 42
       - "result.changed == true"
43 43
 
44
+- name: teardown for rollback test
45
+  junos_config:
46
+    lines:
47
+    - delete system syslog file test1
48
+    provider: "{{ netconf }}"
49
+
50
+- name: Configure syslog file
51
+  junos_config:
52
+    lines:
53
+    - set system syslog file test1 any any
54
+    provider: "{{ netconf }}"
55
+  register: result
56
+
57
+- assert:
58
+    that:
59
+      - "result.changed == true"
60
+      - result.diff.prepared | search("\+ *file test1")
61
+      - result.diff.prepared | search("\+ *any any")
62
+
63
+- name: Rollback junos config
64
+  junos_config:
65
+    rollback: 1
66
+    provider: "{{ netconf }}"
67
+  register: result
68
+
69
+- assert:
70
+    that:
71
+      - "result.changed == true"
72
+      - result.diff.prepared | search("\+ *file test1")
73
+      - result.diff.prepared | search("\+ *any any")
74
+
44 75
 - name: teardown
45 76
   junos_config:
46 77
     lines:
... ...
@@ -36,6 +36,9 @@ class TestJunosConfigModule(TestJunosModule):
36 36
         self.mock_load_config = patch('ansible.modules.network.junos.junos_config.load_config')
37 37
         self.load_config = self.mock_load_config.start()
38 38
 
39
+        self.mock_load_configuration = patch('ansible.modules.network.junos.junos_config.load_configuration')
40
+        self.load_configuration = self.mock_load_configuration.start()
41
+
39 42
         self.mock_lock_configuration = patch('ansible.module_utils.junos.lock_configuration')
40 43
         self.lock_configuration = self.mock_lock_configuration.start()
41 44
 
... ...
@@ -59,6 +62,7 @@ class TestJunosConfigModule(TestJunosModule):
59 59
         self.mock_commit_configuration.stop()
60 60
         self.mock_get_diff.stop()
61 61
         self.mock_send_request.stop()
62
+        self.load_configuration.stop()
62 63
 
63 64
     def load_fixtures(self, commands=None, format='text', changed=False):
64 65
         self.get_config.return_value = load_fixture('get_configuration_rpc_reply.txt')
... ...
@@ -101,9 +105,14 @@ class TestJunosConfigModule(TestJunosModule):
101 101
         self.assertEqual(kwargs['confirm_timeout'], 40)
102 102
 
103 103
     def test_junos_config_rollback(self):
104
-        set_module_args(dict(rollback=10))
104
+        rollback = 10
105
+        set_module_args(dict(rollback=rollback))
105 106
         self.execute_module(changed=True)
106 107
         self.assertEqual(self.get_diff.call_count, 1)
108
+        self.assertEqual(self.load_configuration.call_count, 1)
109
+        self.assertEqual(self.commit_configuration.call_count, 1)
110
+        load_configuration_args = self.load_configuration.call_args
111
+        self.assertEqual(rollback, load_configuration_args[1].get('rollback'))
107 112
 
108 113
     def test_junos_config_src_text(self):
109 114
         src = load_fixture('junos_config.text', content='str')