Skip to content

Commit

Permalink
vmware_content_deploy_ovf_template - create VMs from OVF templates (a…
Browse files Browse the repository at this point in the history
…nsible-collections#114)

vmware_content_deploy_ovf_template - create VMs from OVF templates

Reviewed-by: https://github.com/apps/ansible-zuul
  • Loading branch information
ultral authored and Michal Novacek committed Jun 5, 2020
1 parent 6ba728e commit 3844fd6
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- add vmware_content_deploy_ovf_template module for creating VMs from OVF templates
235 changes: 235 additions & 0 deletions plugins/modules/vmware_content_deploy_ovf_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2020, Lev Goncharov <lev@goncharov.xyz>
# 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

ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}

DOCUMENTATION = r'''
---
module: vmware_content_deploy_ovf_template
short_description: Deploy Virtual Machine from ovf template stored in content library.
description:
- Module to deploy virtual machine from ovf template in content library.
- All variables and VMware object names are case sensitive.
author:
- Lev Goncharv (@ultral)
notes:
- Tested on vSphere 6.7
requirements:
- python >= 2.6
- PyVmomi
- vSphere Automation SDK
options:
ovf_template:
description:
- The name of OVF template from which VM to be deployed.
type: str
required: True
aliases: ['ovf', 'template_src']
name:
description:
- The name of the VM to be deployed.
type: str
required: True
aliases: ['vm_name']
datacenter:
description:
- Name of the datacenter, where VM to be deployed.
type: str
required: True
datastore:
description:
- Name of the datastore to store deployed VM and disk.
type: str
required: True
folder:
description:
- Name of the folder in datacenter in which to place deployed VM.
type: str
required: True
host:
description:
- Name of the ESX Host in datacenter in which to place deployed VM.
type: str
required: True
resource_pool:
description:
- Name of the resourcepool in datacenter in which to place deployed VM.
type: str
required: False
cluster:
description:
- Name of the cluster in datacenter in which to place deployed VM.
type: str
required: False
extends_documentation_fragment: vmware_rest_client.documentation
'''

EXAMPLES = r'''
- name: Deploy Virtual Machine from OVF template in content library
vmware_content_deploy_ovf_template:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
ovf_template: rhel_test_template
datastore: Shared_NFS_Volume
folder: vm
datacenter: Sample_DC_1
name: Sample_VM
resource_pool: test_rp
validate_certs: False
delegate_to: localhost
'''

RETURN = r'''
vm_deploy_info:
description: Virtual machine deployment message and vm_id
returned: on success
type: dict
sample: {
"msg": "Deployed Virtual Machine 'Sample_VM'.",
"vm_id": "vm-1009"
}
'''

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.vmware_rest_client import VmwareRestClient
from ansible.module_utils.vmware import PyVmomi

HAS_VAUTOMATION_PYTHON_SDK = False
try:
from com.vmware.vcenter.ovf_client import LibraryItem
HAS_VAUTOMATION_PYTHON_SDK = True
except ImportError:
pass


class VmwareContentDeployOvfTemplate(VmwareRestClient):
def __init__(self, module):
"""Constructor."""
super(VmwareContentDeployOvfTemplate, self).__init__(module)
self.ovf_template_name = self.params.get('ovf_template')
self.vm_name = self.params.get('name')
self.datacenter = self.params.get('datacenter')
self.datastore = self.params.get('datastore')
self.folder = self.params.get('folder')
self.resourcepool = self.params.get('resource_pool')
self.cluster = self.params.get('cluster')
self.host = self.params.get('host')

def deploy_vm_from_ovf_template(self):
# Find the datacenter by the given datacenter name
self.datacenter_id = self.get_datacenter_by_name(datacenter_name=self.datacenter)
if not self.datacenter_id:
self.module.fail_json(msg="Failed to find the datacenter %s" % self.datacenter)
# Find the datastore by the given datastore name
self.datastore_id = self.get_datastore_by_name(self.datacenter, self.datastore)
if not self.datastore_id:
self.module.fail_json(msg="Failed to find the datastore %s" % self.datastore)
# Find the LibraryItem (Template) by the given LibraryItem name
self.library_item_id = self.get_library_item_by_name(self.ovf_template_name)
if not self.library_item_id:
self.module.fail_json(msg="Failed to find the library Item %s" % self.ovf_template_name)
# Find the folder by the given folder name
self.folder_id = self.get_folder_by_name(self.datacenter, self.folder)
if not self.folder_id:
self.module.fail_json(msg="Failed to find the folder %s" % self.folder)
# Find the Host by given HostName
self.host_id = self.get_host_by_name(self.datacenter, self.host)
if not self.host_id:
self.module.fail_json(msg="Failed to find the Host %s" % self.host)
# Find the resourcepool by the given resourcepool name
self.resourcepool_id = None
if self.resourcepool:
self.resourcepool_id = self.get_resource_pool_by_name(self.datacenter, self.resourcepool)
if not self.resourcepool_id:
self.module.fail_json(msg="Failed to find the resource_pool %s" % self.resourcepool)
# Find the Cluster by the given Cluster name
self.cluster_id = None
if self.cluster:
self.cluster_id = self.get_cluster_by_name(self.datacenter, self.cluster)
if not self.cluster_id:
self.module.fail_json(msg="Failed to find the Cluster %s" % self.cluster)

deployment_target = LibraryItem.DeploymentTarget(
resource_pool_id=self.resourcepool_id,
folder_id=self.folder_id
)

self.ovf_summary = self.api_client.vcenter.ovf.LibraryItem.filter(
ovf_library_item_id=self.library_item_id,
target=deployment_target)

self.deploy_spec = LibraryItem.ResourcePoolDeploymentSpec(
name=self.vm_name,
annotation=self.ovf_summary.annotation,
accept_all_eula=True,
network_mappings=None,
storage_mappings=None,
storage_provisioning=None,
storage_profile_id=None,
locale=None,
flags=None,
additional_parameters=None,
default_datastore_id=None)

result = self.api_client.vcenter.ovf.LibraryItem.deploy(self.library_item_id, deployment_target, self.deploy_spec)

if result.succeeded:
self.module.exit_json(
changed=True,
vm_deploy_info=dict(
msg="Deployed Virtual Machine '%s'." % self.vm_name,
vm_id=result.resource_id.id,
)
)
self.module.exit_json(changed=False,
vm_deploy_info=dict(msg="Virtual Machine deployment failed", vm_id=''))


def main():
argument_spec = VmwareRestClient.vmware_client_argument_spec()
argument_spec.update(
ovf_template=dict(type='str', aliases=['template_src', 'ovf'], required=True),
name=dict(type='str', required=True, aliases=['vm_name']),
datacenter=dict(type='str', required=True),
datastore=dict(type='str', required=True),
folder=dict(type='str', required=True),
host=dict(type='str', required=True),
resource_pool=dict(type='str', required=False),
cluster=dict(type='str', required=False),
)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
result = {'failed': False, 'changed': False}
pyv = PyVmomi(module=module)
vm = pyv.get_vm()
if vm:
module.exit_json(
changed=False,
vm_deploy_info=dict(
msg="Virtual Machine '%s' already Exists." % module.params['name'],
vm_id=vm._moId,
)
)
vmware_contentlib_create = VmwareContentDeployOvfTemplate(module)
if module.check_mode:
result.update(
vm_name=module.params['name'],
changed=True,
desired_operation='Create VM with PowerOff State',
)
module.exit_json(**result)
vmware_contentlib_create.deploy_vm_from_ovf_template()


if __name__ == '__main__':
main()

0 comments on commit 3844fd6

Please sign in to comment.