Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Proxmox Snapshot Restoring #4377

Merged
merged 14 commits into from
Apr 25, 2022
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- proxmox - add restore snapshot option (https://github.com/ansible-collections/community.general/pull/4377).
74 changes: 65 additions & 9 deletions plugins/modules/cloud/misc/proxmox_snap.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function

__metaclass__ = type

DOCUMENTATION = r'''
Expand All @@ -28,7 +29,8 @@
state:
description:
- Indicate desired state of the instance snapshot.
choices: ['present', 'absent']
- The C(rollback) value was added in community.general 4.7.0.
EinDev marked this conversation as resolved.
Show resolved Hide resolved
choices: ['present', 'absent', 'rollback']
default: present
type: str
force:
Expand Down Expand Up @@ -84,6 +86,15 @@
vmid: 100
state: absent
snapname: pre-updates

- name: Rollback container snapshot
community.general.proxmox_snap:
api_user: root@pam
api_password: 1q2w3e
api_host: node1
vmid: 100
state: rollback
snapname: pre-updates
'''

RETURN = r'''#'''
Expand All @@ -93,7 +104,9 @@

from ansible.module_utils.basic import AnsibleModule, missing_required_lib, env_fallback
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.general.plugins.module_utils.proxmox import (proxmox_auth_argument_spec, ProxmoxAnsible, HAS_PROXMOXER, PROXMOXER_IMP_ERR)
from ansible_collections.community.general.plugins.module_utils.proxmox import (proxmox_auth_argument_spec,
ProxmoxAnsible, HAS_PROXMOXER,
PROXMOXER_IMP_ERR)


class ProxmoxSnapAnsible(ProxmoxAnsible):
Expand All @@ -114,8 +127,9 @@ def snapshot_create(self, vm, vmid, timeout, snapname, description, vmstate):
return True
timeout -= 1
EinDev marked this conversation as resolved.
Show resolved Hide resolved
if timeout == 0:
self.module.fail_json(msg='Reached timeout while waiting for creating VM snapshot. Last line in task before timeout: %s' %
self.proxmox_api.nodes(vm['node']).tasks(taskid).log.get()[:1])
self.module.fail_json(
msg='Reached timeout while waiting for creating VM snapshot. Last line in task before timeout: %s' %
self.proxmox_api.nodes(vm['node']).tasks(taskid).log.get()[:1])
EinDev marked this conversation as resolved.
Show resolved Hide resolved

time.sleep(1)
return False
Expand All @@ -131,8 +145,27 @@ def snapshot_remove(self, vm, vmid, timeout, snapname, force):
return True
timeout -= 1
if timeout == 0:
self.module.fail_json(msg='Reached timeout while waiting for removing VM snapshot. Last line in task before timeout: %s' %
self.proxmox_api.nodes(vm['node']).tasks(taskid).log.get()[:1])
self.module.fail_json(
msg='Reached timeout while waiting for removing VM snapshot. Last line in task before timeout: %s' %
self.proxmox_api.nodes(vm['node']).tasks(taskid).log.get()[:1])

time.sleep(1)
return False

def snapshot_rollback(self, vm, vmid, timeout, snapname):
if self.module.check_mode:
return True

taskid = self.snapshot(vm, vmid)(snapname).post("rollback")
while timeout:
if (self.proxmox_api.nodes(vm['node']).tasks(taskid).status.get()['status'] == 'stopped' and
self.proxmox_api.nodes(vm['node']).tasks(taskid).status.get()['exitstatus'] == 'OK'):
EinDev marked this conversation as resolved.
Show resolved Hide resolved
return True
timeout -= 1
if timeout == 0:
felixfontein marked this conversation as resolved.
Show resolved Hide resolved
self.module.fail_json(
msg='Reached timeout while waiting for rolling back VM snapshot. Last line in task before timeout: %s' %
self.proxmox_api.nodes(vm['node']).tasks(taskid).log.get()[:1])

time.sleep(1)
return False
Expand All @@ -144,7 +177,7 @@ def main():
vmid=dict(required=False),
hostname=dict(),
timeout=dict(type='int', default=30),
state=dict(default='present', choices=['present', 'absent']),
state=dict(default='present', choices=['present', 'absent', 'rollback']),
description=dict(type='str'),
snapname=dict(type='str', default='ansible_snap'),
force=dict(type='bool', default='no'),
Expand Down Expand Up @@ -189,7 +222,8 @@ def main():
module.exit_json(changed=True, msg="Snapshot %s created" % snapname)

except Exception as e:
module.fail_json(msg="Creating snapshot %s of VM %s failed with exception: %s" % (snapname, vmid, to_native(e)))
module.fail_json(
msg="Creating snapshot %s of VM %s failed with exception: %s" % (snapname, vmid, to_native(e)))

elif state == 'absent':
try:
Expand All @@ -210,7 +244,29 @@ def main():
module.exit_json(changed=True, msg="Snapshot %s removed" % snapname)

except Exception as e:
module.fail_json(msg="Removing snapshot %s of VM %s failed with exception: %s" % (snapname, vmid, to_native(e)))
module.fail_json(
msg="Removing snapshot %s of VM %s failed with exception: %s" % (snapname, vmid, to_native(e)))
elif state == 'rollback':
try:
snap_exist = False

for i in proxmox.snapshot(vm, vmid).get():
if i['name'] == snapname:
snap_exist = True
continue

if not snap_exist:
module.exit_json(changed=False, msg="Snapshot %s does not exist" % snapname)
else:
if proxmox.snapshot_rollback(vm, vmid, timeout, snapname):
if module.check_mode:
module.exit_json(changed=False, msg="Snapshot %s would be rolled back" % snapname)
else:
module.exit_json(changed=True, msg="Snapshot %s rolled back" % snapname)
EinDev marked this conversation as resolved.
Show resolved Hide resolved

except Exception as e:
module.fail_json(
msg="Rollback of snapshot %s of VM %s failed with exception: %s" % (snapname, vmid, to_native(e)))


if __name__ == '__main__':
Expand Down