Skip to content

Commit f94611b

Browse files
authored
Add snapshot_id option to vmware_guest_snapshot module (#1847)
Add snapshot_id option to vmware_guest_snapshot module SUMMARY This PR is to add snapshot_id option to the module. fixes: #1844 ISSUE TYPE Feature Pull Request COMPONENT NAME changelogs/fragments/1847_vmware_guest_snapshot.yml docs/community.vmware.vmware_guest_snapshot_module.rst plugins/modules/vmware_guest_snapshot.py tests/integration/targets/vmware_guest_snapshot/tasks/main.yml ADDITIONAL INFORMATION I will add the integration test in a few days. Done Reviewed-by: Mario Lenz <m@riolenz.de>
1 parent 169de3f commit f94611b

File tree

4 files changed

+164
-19
lines changed

4 files changed

+164
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
minor_changes:
2+
- add new snapshot_id option to the vmware_guest_snapshot module(https://github.com/ansible-collections/community.vmware/pull/1847).

docs/community.vmware.vmware_guest_snapshot_module.rst

+30-1
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,23 @@ Parameters
322322
<div>If set to <code>true</code> and state is set to <code>absent</code>, then entire snapshot subtree is set for removal.</div>
323323
</td>
324324
</tr>
325+
<tr>
326+
<td colspan="1">
327+
<div class="ansibleOptionAnchor" id="parameter-"></div>
328+
<b>snapshot_id</b>
329+
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
330+
<div style="font-size: small">
331+
<span style="color: purple">integer</span>
332+
</div>
333+
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.10.0</div>
334+
</td>
335+
<td>
336+
</td>
337+
<td>
338+
<div>Sets the snapshot id to manage.</div>
339+
<div>This param is available when state is <code>absent</code>.</div>
340+
</td>
341+
</tr>
325342
<tr>
326343
<td colspan="1">
327344
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -335,7 +352,7 @@ Parameters
335352
</td>
336353
<td>
337354
<div>Sets the snapshot name to manage.</div>
338-
<div>This param is required only if state is not <code>remove_all</code></div>
355+
<div>This param or <code>snapshot_id</code> is required only if state is not <code>remove_all</code></div>
339356
</td>
340357
</tr>
341358
<tr>
@@ -545,6 +562,18 @@ Examples
545562
snapshot_name: snap1
546563
delegate_to: localhost
547564
565+
- name: Remove a snapshot with a snapshot id
566+
community.vmware.vmware_guest_snapshot:
567+
hostname: "{{ vcenter_hostname }}"
568+
username: "{{ vcenter_username }}"
569+
password: "{{ vcenter_password }}"
570+
datacenter: "{{ datacenter_name }}"
571+
folder: "/{{ datacenter_name }}/vm/"
572+
name: "{{ guest_name }}"
573+
snapshot_id: 10
574+
state: absent
575+
delegate_to: localhost
576+
548577
- name: Rename a snapshot
549578
community.vmware.vmware_guest_snapshot:
550579
hostname: "{{ vcenter_hostname }}"

plugins/modules/vmware_guest_snapshot.py

+41-4
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,14 @@
8484
snapshot_name:
8585
description:
8686
- Sets the snapshot name to manage.
87-
- This param is required only if state is not C(remove_all)
87+
- This param or C(snapshot_id) is required only if state is not C(remove_all)
8888
type: str
89+
snapshot_id:
90+
description:
91+
- Sets the snapshot id to manage.
92+
- This param is available when state is C(absent).
93+
type: int
94+
version_added: 3.10.0
8995
description:
9096
description:
9197
- Define an arbitrary description to attach to snapshot.
@@ -214,6 +220,18 @@
214220
snapshot_name: snap1
215221
delegate_to: localhost
216222
223+
- name: Remove a snapshot with a snapshot id
224+
community.vmware.vmware_guest_snapshot:
225+
hostname: "{{ vcenter_hostname }}"
226+
username: "{{ vcenter_username }}"
227+
password: "{{ vcenter_password }}"
228+
datacenter: "{{ datacenter_name }}"
229+
folder: "/{{ datacenter_name }}/vm/"
230+
name: "{{ guest_name }}"
231+
snapshot_id: 10
232+
state: absent
233+
delegate_to: localhost
234+
217235
- name: Rename a snapshot
218236
community.vmware.vmware_guest_snapshot:
219237
hostname: "{{ vcenter_hostname }}"
@@ -293,6 +311,16 @@ def get_snapshots_by_name_recursively(self, snapshots, snapname):
293311
snap_obj = snap_obj + self.get_snapshots_by_name_recursively(snapshot.childSnapshotList, snapname)
294312
return snap_obj
295313

314+
def get_snapshots_by_id_recursively(self, snapshots, snapid):
315+
snap_obj = []
316+
for snapshot in snapshots:
317+
if snapshot.id == snapid:
318+
snap_obj.append(snapshot)
319+
else:
320+
snap_obj = snap_obj + self.get_snapshots_by_id_recursively(snapshot.childSnapshotList, snapid)
321+
322+
return snap_obj
323+
296324
def snapshot_vm(self, vm):
297325
memory_dump = False
298326
quiesce = False
@@ -357,8 +385,13 @@ def remove_or_revert_snapshot(self, vm):
357385
self.module.exit_json(msg="virtual machine - %s doesn't have any"
358386
" snapshots to remove." % vm_name)
359387

360-
snap_obj = self.get_snapshots_by_name_recursively(vm.snapshot.rootSnapshotList,
361-
self.module.params["snapshot_name"])
388+
if self.module.params["snapshot_name"]:
389+
snap_obj = self.get_snapshots_by_name_recursively(vm.snapshot.rootSnapshotList,
390+
self.module.params["snapshot_name"])
391+
elif self.module.params["snapshot_id"]:
392+
snap_obj = self.get_snapshots_by_id_recursively(vm.snapshot.rootSnapshotList,
393+
self.module.params["snapshot_id"])
394+
362395
task = None
363396
if len(snap_obj) == 1:
364397
snap_obj = snap_obj[0].snapshot
@@ -414,6 +447,7 @@ def main():
414447
folder=dict(type='str'),
415448
datacenter=dict(required=True, type='str'),
416449
snapshot_name=dict(type='str'),
450+
snapshot_id=dict(type='int'),
417451
description=dict(type='str', default=''),
418452
quiesce=dict(type='bool', default=False),
419453
memory_dump=dict(type='bool', default=False),
@@ -429,6 +463,9 @@ def main():
429463
required_one_of=[
430464
['name', 'uuid', 'moid']
431465
],
466+
mutually_exclusive=[
467+
['snapshot_name', 'snapshot_id']
468+
]
432469
)
433470

434471
if module.params['folder']:
@@ -444,7 +481,7 @@ def main():
444481
vm_id = (module.params.get('uuid') or module.params.get('name') or module.params.get('moid'))
445482
module.fail_json(msg="Unable to manage snapshots for non-existing VM %s" % vm_id)
446483

447-
if not module.params['snapshot_name'] and module.params['state'] != 'remove_all':
484+
if not (module.params['snapshot_name'] or module.params['snapshot_id']) and module.params['state'] != 'remove_all':
448485
module.fail_json(msg="snapshot_name param is required when state is '%(state)s'" % module.params)
449486

450487
result = pyv.apply_snapshot_op(vm)

tests/integration/targets/vmware_guest_snapshot/tasks/main.yml

+91-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# Test0001: Try to delete the non-existent snapshot
99
- name: 0001 - Delete non-existent snapshot
10-
vmware_guest_snapshot:
10+
community.vmware.vmware_guest_snapshot:
1111
validate_certs: false
1212
hostname: '{{ vcenter_hostname }}'
1313
username: '{{ vcenter_username }}'
@@ -20,7 +20,7 @@
2020

2121
# Test0002: Create two snapshots
2222
- name: 0002 - Create snapshot
23-
vmware_guest_snapshot:
23+
community.vmware.vmware_guest_snapshot:
2424
validate_certs: false
2525
hostname: '{{ vcenter_hostname }}'
2626
username: '{{ vcenter_username }}'
@@ -37,7 +37,7 @@
3737

3838
# Test0003: Reanme a to c
3939
- name: 0003 - Rename snapshot
40-
vmware_guest_snapshot:
40+
community.vmware.vmware_guest_snapshot:
4141
validate_certs: false
4242
hostname: '{{ vcenter_hostname }}'
4343
username: '{{ vcenter_username }}'
@@ -51,7 +51,7 @@
5151

5252
# Test0004: Create snap_a again
5353
- name: 0004 - Re-create snapshot a
54-
vmware_guest_snapshot:
54+
community.vmware.vmware_guest_snapshot:
5555
validate_certs: false
5656
hostname: '{{ vcenter_hostname }}'
5757
username: '{{ vcenter_username }}'
@@ -65,7 +65,7 @@
6565

6666
# Test0005: Change description of snap_c
6767
- name: 0005 - Change description of snap_c
68-
vmware_guest_snapshot:
68+
community.vmware.vmware_guest_snapshot:
6969
validate_certs: false
7070
hostname: '{{ vcenter_hostname }}'
7171
username: '{{ vcenter_username }}'
@@ -79,7 +79,7 @@
7979

8080
# Test0006: Delete snap_b with child remove
8181
- name: 0006 - Delete snap_b with child remove
82-
vmware_guest_snapshot:
82+
community.vmware.vmware_guest_snapshot:
8383
validate_certs: false
8484
hostname: '{{ vcenter_hostname }}'
8585
username: '{{ vcenter_username }}'
@@ -93,7 +93,7 @@
9393

9494
# Test0007: Delete all snapshots
9595
- name: 0007 - Delete all snapshots
96-
vmware_guest_snapshot:
96+
community.vmware.vmware_guest_snapshot:
9797
validate_certs: false
9898
hostname: '{{ vcenter_hostname }}'
9999
username: '{{ vcenter_username }}'
@@ -105,7 +105,7 @@
105105

106106
# Test0008: Create snap_a again and revert to it
107107
- name: 0008 - Re-create snapshot a
108-
vmware_guest_snapshot:
108+
community.vmware.vmware_guest_snapshot:
109109
validate_certs: false
110110
hostname: '{{ vcenter_hostname }}'
111111
username: '{{ vcenter_username }}'
@@ -118,7 +118,7 @@
118118
description: "snap named a"
119119

120120
- name: 0008 - Revert to snap_a
121-
vmware_guest_snapshot:
121+
community.vmware.vmware_guest_snapshot:
122122
validate_certs: false
123123
hostname: '{{ vcenter_hostname }}'
124124
username: '{{ vcenter_username }}'
@@ -131,7 +131,7 @@
131131

132132
# Test0009: Create snap_a and check in result
133133
- name: 0009 - create snapshot a
134-
vmware_guest_snapshot:
134+
community.vmware.vmware_guest_snapshot:
135135
validate_certs: false
136136
hostname: '{{ vcenter_hostname }}'
137137
username: '{{ vcenter_username }}'
@@ -144,16 +144,16 @@
144144
description: "snap named a"
145145
register: snapshot_details
146146

147-
- debug: var=snapshot_details
147+
- ansible.builtin.debug: var=snapshot_details
148148

149149
- name: Check if snapshot details available or not
150-
assert:
150+
ansible.builtin.assert:
151151
that:
152152
- "snapshot_details['msg'] == 'Snapshot named [snap_a] already exists and is current.'"
153153

154154
# Test0011: Failure sceanrios - when name and UUID is not specified
155155
- name: 0011 - name and UUID is missing
156-
vmware_guest_snapshot:
156+
community.vmware.vmware_guest_snapshot:
157157
validate_certs: false
158158
hostname: '{{ vcenter_hostname }}'
159159
username: '{{ vcenter_username }}'
@@ -166,7 +166,84 @@
166166
ignore_errors: true
167167

168168
- name: Check if error is shown
169-
assert:
169+
ansible.builtin.assert:
170170
that:
171171
- "'one of the following is required: name, uuid' in snapshot_failure_details['msg']"
172172
- "snapshot_failure_details.changed == false"
173+
174+
# Test0010 : Test for revert and remove a snapshot to specify snapshot_id
175+
- name: 0012 - Create snapshot
176+
community.vmware.vmware_guest_snapshot:
177+
validate_certs: false
178+
hostname: '{{ vcenter_hostname }}'
179+
username: '{{ vcenter_username }}'
180+
password: '{{ vcenter_password }}'
181+
datacenter: "{{ dc1 }}"
182+
name: "{{ virtual_machines[0].name }}"
183+
folder: "{{ virtual_machines[0].folder }}"
184+
state: present
185+
snapshot_name: "snap_{{item}}"
186+
description: "snap named {{item}}"
187+
with_items:
188+
- b
189+
- c
190+
register: snapshot_creation_result0012
191+
192+
- name: Create the snapshot_ids variable
193+
ansible.builtin.set_fact:
194+
snapshot_ids: >-
195+
{{ snapshot_ids | default([])
196+
+ [({
197+
'name': item.snapshot_results.current_snapshot.name,
198+
'snapshot_id': item.snapshot_results.current_snapshot.id
199+
})]
200+
}}
201+
loop: "{{ snapshot_creation_result0012.results }}"
202+
203+
- name: 0013 - Revert to snap_b with snapshot_id
204+
community.vmware.vmware_guest_snapshot:
205+
validate_certs: false
206+
hostname: '{{ vcenter_hostname }}'
207+
username: '{{ vcenter_username }}'
208+
password: '{{ vcenter_password }}'
209+
datacenter: "{{ dc1 }}"
210+
name: "{{ virtual_machines[0].name }}"
211+
folder: "{{ virtual_machines[0].folder }}"
212+
state: revert
213+
snapshot_id: "{{ item.snapshot_id }}"
214+
loop: "{{ snapshot_ids }}"
215+
when:
216+
- item.name == "snap_b"
217+
register: revert_snapshot_with_id_result
218+
219+
- name: Make sure whether reverted with snapshot_id
220+
ansible.builtin.assert:
221+
that:
222+
- item.changed is sameas true
223+
loop: "{{ revert_snapshot_with_id_result.results }}"
224+
when:
225+
- item.item.name == "snap_b"
226+
227+
- name: 0014 - Remove snap_b with snapshot_id
228+
community.vmware.vmware_guest_snapshot:
229+
validate_certs: false
230+
hostname: '{{ vcenter_hostname }}'
231+
username: '{{ vcenter_username }}'
232+
password: '{{ vcenter_password }}'
233+
datacenter: "{{ dc1 }}"
234+
name: "{{ virtual_machines[0].name }}"
235+
folder: "{{ virtual_machines[0].folder }}"
236+
state: absent
237+
snapshot_id: "{{ item.snapshot_id }}"
238+
loop: "{{ snapshot_ids }}"
239+
when:
240+
- item.name == "snap_b"
241+
register: remove_snapshot_with_id_result
242+
243+
- name: Make sure whether removed with snapshot_id
244+
ansible.builtin.assert:
245+
that:
246+
- item.changed is sameas true
247+
loop: "{{ remove_snapshot_with_id_result.results }}"
248+
when:
249+
- item.item.name == "snap_b"

0 commit comments

Comments
 (0)