#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright: (c) 2017, Davis Phillips davis.phillips@gmail.com # 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 = ''' --- module: vmware_resource_pool short_description: Add/remove resource pools to/from vCenter description: - This module can be used to add/remove a resource pool to/from vCenter version_added: 2.3 author: - Davis Phillips (@dav1x) notes: - Tested on vSphere 6.5 requirements: - "python >= 2.6" - PyVmomi options: datacenter: description: - Name of the datacenter to add the host. required: True cluster: description: - Name of the cluster to add the host. required: True resource_pool: description: - Resource pool name to manage. required: True cpu_expandable_reservations: description: - In a resource pool with an expandable reservation, the reservation on a resource pool can grow beyond the specified value. default: True type: bool cpu_reservation: description: - Amount of resource that is guaranteed available to the virtual machine or resource pool. default: 0 cpu_limit: description: - The utilization of a virtual machine/resource pool will not exceed this limit, even if there are available resources. - The default value -1 indicates no limit. default: -1 cpu_shares: description: - Memory shares are used in case of resource contention. choices: - high - custom - low - normal default: normal mem_expandable_reservations: description: - In a resource pool with an expandable reservation, the reservation on a resource pool can grow beyond the specified value. default: True type: bool mem_reservation: description: - Amount of resource that is guaranteed available to the virtual machine or resource pool. default: 0 mem_limit: description: - The utilization of a virtual machine/resource pool will not exceed this limit, even if there are available resources. - The default value -1 indicates no limit. default: -1 mem_shares: description: - Memory shares are used in case of resource contention. choices: - high - custom - low - normal default: normal state: description: - Add or remove the resource pool default: 'present' choices: - 'present' - 'absent' extends_documentation_fragment: vmware.documentation ''' EXAMPLES = ''' - name: Add resource pool to vCenter vmware_resource_pool: hostname: '{{ vcenter_hostname }}' username: '{{ vcenter_username }}' password: '{{ vcenter_password }}' datacenter: '{{ datacenter_name }}' cluster: '{{ cluster_name }}' resource_pool: '{{ resource_pool_name }}' mem_shares: normal mem_limit: -1 mem_reservation: 0 mem_expandable_reservations: yes cpu_shares: normal cpu_limit: -1 cpu_reservation: 0 cpu_expandable_reservations: yes state: present delegate_to: localhost ''' RETURN = """ instance: description: metadata about the new resource pool returned: always type: dict sample: None """ try: from pyVmomi import vim, vmodl HAS_PYVMOMI = True except ImportError: HAS_PYVMOMI = False from ansible.module_utils.vmware import get_all_objs, connect_to_api, vmware_argument_spec, find_datacenter_by_name, \ find_cluster_by_name, wait_for_task, find_host_by_cluster_datacenter from ansible.module_utils.basic import AnsibleModule class VMwareResourcePool(object): def __init__(self, module): self.module = module self.datacenter = module.params['datacenter'] self.cluster = module.params['cluster'] self.resource_pool = module.params['resource_pool'] self.hostname = module.params['hostname'] self.username = module.params['username'] self.password = module.params['password'] self.state = module.params['state'] self.mem_shares = module.params['mem_shares'] self.mem_limit = module.params['mem_limit'] self.mem_reservation = module.params['mem_reservation'] self.mem_expandable_reservations = module.params[ 'cpu_expandable_reservations'] self.cpu_shares = module.params['cpu_shares'] self.cpu_limit = module.params['cpu_limit'] self.cpu_reservation = module.params['cpu_reservation'] self.cpu_expandable_reservations = module.params[ 'cpu_expandable_reservations'] self.dc_obj = None self.cluster_obj = None self.host_obj = None self.resource_pool_obj = None self.content = connect_to_api(module) def select_resource_pool(self, host): pool_obj = None resource_pools = get_all_objs(self.content, [vim.ResourcePool]) pool_selections = self.get_obj( [vim.ResourcePool], self.resource_pool, return_all=True ) if pool_selections: for p in pool_selections: if p in resource_pools: pool_obj = p break return pool_obj def get_obj(self, vimtype, name, return_all=False): obj = list() container = self.content.viewManager.CreateContainerView( self.content.rootFolder, vimtype, True) for c in container.view: if name in [c.name, c._GetMoId()]: if return_all is False: return c else: obj.append(c) if len(obj) > 0: return obj else: # for backwards-compat return None def process_state(self): try: rp_states = { 'absent': { 'present': self.state_remove_rp, 'absent': self.state_exit_unchanged, }, 'present': { 'present': self.state_exit_unchanged, 'absent': self.state_add_rp, } } rp_states[self.state][self.check_rp_state()]() except vmodl.RuntimeFault as runtime_fault: self.module.fail_json(msg=runtime_fault.msg) except vmodl.MethodFault as method_fault: self.module.fail_json(msg=method_fault.msg) except Exception as e: self.module.fail_json(msg=str(e)) def state_exit_unchanged(self): self.module.exit_json(changed=False) def state_remove_rp(self): changed = True result = None resource_pool = self.select_resource_pool(self.host_obj) try: task = self.resource_pool_obj.Destroy() success, result = wait_for_task(task) except: self.module.fail_json(msg="Failed to remove resource pool '%s' '%s'" % ( self.resource_pool, resource_pool)) self.module.exit_json(changed=changed, result=str(result)) def state_add_rp(self): changed = True rp_spec = vim.ResourceConfigSpec() cpu_alloc = vim.ResourceAllocationInfo() cpu_alloc.expandableReservation = self.cpu_expandable_reservations cpu_alloc.limit = int(self.cpu_limit) cpu_alloc.reservation = int(self.cpu_reservation) cpu_alloc_shares = vim.SharesInfo() cpu_alloc_shares.level = self.cpu_shares cpu_alloc.shares = cpu_alloc_shares rp_spec.cpuAllocation = cpu_alloc mem_alloc = vim.ResourceAllocationInfo() mem_alloc.limit = int(self.mem_limit) mem_alloc.expandableReservation = self.mem_expandable_reservations mem_alloc.reservation = int(self.mem_reservation) mem_alloc_shares = vim.SharesInfo() mem_alloc_shares.level = self.mem_shares mem_alloc.shares = mem_alloc_shares rp_spec.memoryAllocation = mem_alloc self.dc_obj = find_datacenter_by_name(self.content, self.datacenter) if self.dc_obj is None: self.module.fail_json(msg="Unable to find datacenter with name %s" % self.datacenter) self.cluster_obj = find_cluster_by_name(self.content, self.cluster, datacenter=self.dc_obj) if self.cluster_obj is None: self.module.fail_json(msg="Unable to find cluster with name %s" % self.cluster) rootResourcePool = self.cluster_obj.resourcePool rootResourcePool.CreateResourcePool(self.resource_pool, rp_spec) self.module.exit_json(changed=changed) def check_rp_state(self): self.host_obj, self.cluster_obj = find_host_by_cluster_datacenter(self.module, self.content, self.datacenter, self.cluster, self.hostname) self.resource_pool_obj = self.select_resource_pool(self.host_obj) if self.resource_pool_obj is None: return 'absent' else: return 'present' def main(): argument_spec = vmware_argument_spec() argument_spec.update(dict(datacenter=dict(required=True, type='str'), cluster=dict(required=True, type='str'), resource_pool=dict(required=True, type='str'), mem_shares=dict(type='str', default="normal", choices=[ 'high', 'custom', 'normal', 'low']), mem_limit=dict(type='int', default=-1), mem_reservation=dict(type='int', default=0), mem_expandable_reservations=dict( type='bool', default="True"), cpu_shares=dict(type='str', default="normal", choices=[ 'high', 'custom', 'normal', 'low']), cpu_limit=dict(type='int', default=-1), cpu_reservation=dict(type='int', default=0), cpu_expandable_reservations=dict( type='bool', default="True"), state=dict(default='present', choices=['present', 'absent'], type='str'))) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_PYVMOMI: module.fail_json(msg='pyvmomi is required for this module') vmware_rp = VMwareResourcePool(module) vmware_rp.process_state() if __name__ == '__main__': main()