Server IP : 85.214.239.14 / Your IP : 18.118.184.76 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /usr/lib/python3/dist-packages/ansible_collections/ovirt/ovirt/plugins/modules/ |
Upload File : |
#!/usr/bin/python # -*- coding: utf-8 -*- # # Copyright (c) 2016 Red Hat, Inc. # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see <http://www.gnu.org/licenses/>. # from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = ''' --- module: ovirt_vmpool short_description: Module to manage VM pools in oVirt/RHV version_added: "1.0.0" author: - "Ondra Machacek (@machacekondra)" - "Martin Necas (@mnecas)" description: - "Module to manage VM pools in oVirt/RHV." options: id: description: - "ID of the vmpool to manage." type: str name: description: - "Name of the VM pool to manage." type: str required: true comment: description: - Comment of the Virtual Machine pool. type: str state: description: - "Should the VM pool be present/absent." - "Note that when C(state) is I(absent) all VMs in VM pool are stopped and removed." choices: ['present', 'absent'] default: present type: str template: description: - "Name of the template, which will be used to create VM pool." type: str description: description: - "Description of the VM pool." type: str cluster: description: - "Name of the cluster, where VM pool should be created." type: str type: description: - "Type of the VM pool. Either manual or automatic." - "C(manual) - The administrator is responsible for explicitly returning the virtual machine to the pool. The virtual machine reverts to the original base image after the administrator returns it to the pool." - "C(Automatic) - When the virtual machine is shut down, it automatically reverts to its base image and is returned to the virtual machine pool." - "Default value is set by engine." choices: ['manual', 'automatic'] type: str vm_per_user: description: - "Maximum number of VMs a single user can attach to from this pool." - "Default value is set by engine." type: int prestarted: description: - "Number of pre-started VMs defines the number of VMs in run state, that are waiting to be attached to Users." - "Default value is set by engine." type: int vm_count: description: - "Number of VMs in the pool." - "Default value is set by engine." type: int vm: description: - "For creating vm pool without editing template." - "Note: You can use C(vm) only for creating vm pool." type: dict suboptions: comment: description: - Comment of the Virtual Machine. timezone: description: - Sets time zone offset of the guest hardware clock. - For example C(Etc/GMT) memory: description: - Amount of memory of the Virtual Machine. Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB). - Default value is set by engine. memory_guaranteed: description: - Amount of minimal guaranteed memory of the Virtual Machine. Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB). - C(memory_guaranteed) parameter can't be lower than C(memory) parameter. - Default value is set by engine. memory_max: description: - Upper bound of virtual machine memory up to which memory hot-plug can be performed. Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB). - Default value is set by engine. cloud_init: description: - Dictionary with values for Unix-like Virtual Machine initialization using cloud init. - C(host_name) - Hostname to be set to Virtual Machine when deployed. - C(timezone) - Timezone to be set to Virtual Machine when deployed. - C(user_name) - Username to be used to set password to Virtual Machine when deployed. - C(root_password) - Password to be set for user specified by C(user_name) parameter. - C(authorized_ssh_keys) - Use this SSH keys to login to Virtual Machine. - C(regenerate_ssh_keys) - If I(True) SSH keys will be regenerated on Virtual Machine. - C(custom_script) - Cloud-init script which will be executed on Virtual Machine when deployed. This is appended to the end of the cloud-init script generated by any other options. For further information, refer to cloud-init User-Data documentation. - C(dns_servers) - DNS servers to be configured on Virtual Machine, maximum of two, space-separated. - C(dns_search) - DNS search domains to be configured on Virtual Machine. - C(nic_boot_protocol) - Set boot protocol of the network interface of Virtual Machine. Can be one of C(none), C(dhcp) or C(static). - C(nic_ip_address) - If boot protocol is static, set this IP address to network interface of Virtual Machine. - C(nic_netmask) - If boot protocol is static, set this netmask to network interface of Virtual Machine. - C(nic_gateway) - If boot protocol is static, set this gateway to network interface of Virtual Machine. - C(nic_name) - Set name to network interface of Virtual Machine. sso: description: - "I(True) enable Single Sign On by Guest Agent, I(False) to disable it. By default is chosen by oVirt/RHV engine." type: bool smartcard_enabled: description: - "If I(true), use smart card authentication." type: bool nics: description: - List of NICs, which should be attached to Virtual Machine. NIC is described by following dictionary. - C(name) - Name of the NIC. - C(profile_name) - Profile name where NIC should be attached. - C(interface) - Type of the network interface. One of following I(virtio), I(e1000), I(rtl8139), default is I(virtio). - C(mac_address) - Custom MAC address of the network interface, by default it's obtained from MAC pool. - NOTE - This parameter is used only when C(state) is I(running) or I(present) and is able to only create NICs. - To manage NICs of the VM in more depth please use M(ovirt.ovirt.ovirt_nics) module instead. extends_documentation_fragment: ovirt.ovirt.ovirt ''' EXAMPLES = ''' # Examples don't contain auth parameter for simplicity, # look at ovirt_auth module to see how to reuse authentication: - name: Create VM pool from template ovirt.ovirt.ovirt_vmpool: cluster: mycluster name: myvmpool template: rhel7 vm_count: 2 prestarted: 2 vm_per_user: 1 - name: Remove vmpool, note that all VMs in pool will be stopped and removed ovirt.ovirt.ovirt_vmpool: state: absent name: myvmpool - name: Change Pool Name ovirt.ovirt.ovirt_vmpool: id: 00000000-0000-0000-0000-000000000000 name: "new_pool_name" - name: Create vm pool and override the pool values ovirt.ovirt.ovirt_vmpool: cluster: mycluster name: vmpool template: blank vm_count: 2 prestarted: 1 vm_per_user: 1 vm: memory: 4GiB memory_guaranteed: 4GiB memory_max: 10GiB comment: vncomment cloud_init: nic_boot_protocol: static nic_ip_address: 10.34.60.86 nic_netmask: 255.255.252.0 nic_gateway: 10.34.63.254 nic_name: eth1 host_name: example.com custom_script: | write_files: - content: | Hello, world! path: /tmp/greeting.txt permissions: '0644' user_name: root root_password: super_password nics: - name: nicname interface: virtio profile_name: network ''' RETURN = ''' id: description: ID of the VM pool which is managed returned: On success if VM pool is found. type: str sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c vm_pool: description: "Dictionary of all the VM pool attributes. VM pool attributes can be found on your oVirt/RHV instance at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm_pool." returned: On success if VM pool is found. type: dict ''' try: import ovirtsdk4.types as otypes except ImportError: pass import traceback from ansible.module_utils.basic import AnsibleModule from ansible_collections.ovirt.ovirt.plugins.module_utils.ovirt import ( BaseModule, check_params, check_sdk, create_connection, equal, get_link_name, ovirt_full_argument_spec, wait, convert_to_bytes, search_by_name, ) class VmPoolsModule(BaseModule): def __init__(self, *args, **kwargs): super(VmPoolsModule, self).__init__(*args, **kwargs) self._initialization = None def build_entity(self): vm = self.param('vm') return otypes.VmPool( id=self._module.params['id'], name=self._module.params['name'], description=self._module.params['description'], comment=self._module.params['comment'], cluster=otypes.Cluster( name=self._module.params['cluster'] ) if self._module.params['cluster'] else None, template=otypes.Template( name=self._module.params['template'] ) if self._module.params['template'] else None, max_user_vms=self._module.params['vm_per_user'], prestarted_vms=self._module.params['prestarted'], size=self._module.params['vm_count'], type=otypes.VmPoolType( self._module.params['type'] ) if self._module.params['type'] else None, vm=self.build_vm(vm) if self._module.params['vm'] else None, ) def build_vm(self, vm): return otypes.Vm( comment=vm.get('comment'), memory=convert_to_bytes( vm.get('memory') ) if vm.get('memory') else None, memory_policy=otypes.MemoryPolicy( guaranteed=convert_to_bytes(vm.get('memory_guaranteed')), max=convert_to_bytes(vm.get('memory_max')), ) if any(( vm.get('memory_guaranteed'), vm.get('memory_max') )) else None, initialization=self.get_initialization(vm), display=otypes.Display( smartcard_enabled=vm.get('smartcard_enabled') ) if vm.get('smartcard_enabled') is not None else None, sso=( otypes.Sso( methods=[otypes.Method(id=otypes.SsoMethod.GUEST_AGENT)] if vm.get('sso') else [] ) ) if vm.get('sso') is not None else None, time_zone=otypes.TimeZone( name=vm.get('timezone'), ) if vm.get('timezone') else None, ) def get_initialization(self, vm): if self._initialization is not None: return self._initialization sysprep = vm.get('sysprep') cloud_init = vm.get('cloud_init') cloud_init_nics = vm.get('cloud_init_nics') or [] if cloud_init is not None: cloud_init_nics.append(cloud_init) if cloud_init or cloud_init_nics: self._initialization = otypes.Initialization( nic_configurations=[ otypes.NicConfiguration( boot_protocol=otypes.BootProtocol( nic.pop('nic_boot_protocol').lower() ) if nic.get('nic_boot_protocol') else None, name=nic.pop('nic_name', None), on_boot=True, ip=otypes.Ip( address=nic.pop('nic_ip_address', None), netmask=nic.pop('nic_netmask', None), gateway=nic.pop('nic_gateway', None), ) if ( nic.get('nic_gateway') is not None or nic.get('nic_netmask') is not None or nic.get('nic_ip_address') is not None ) else None, ) for nic in cloud_init_nics if ( nic.get('nic_gateway') is not None or nic.get('nic_netmask') is not None or nic.get('nic_ip_address') is not None or nic.get('nic_boot_protocol') is not None ) ] if cloud_init_nics else None, **cloud_init ) elif sysprep: self._initialization = otypes.Initialization( **sysprep ) return self._initialization def get_vms(self, entity): vms = self._connection.system_service().vms_service().list() resp = [] for vm in vms: if vm.vm_pool is not None and vm.vm_pool.id == entity.id: resp.append(vm) return resp def post_create(self, entity): vm_param = self.param('vm') if vm_param is not None and vm_param.get('nics') is not None: vms = self.get_vms(entity) for vm in vms: self.__attach_nics(vm, vm_param) def __attach_nics(self, entity, vm_param): # Attach NICs to VM, if specified: vms_service = self._connection.system_service().vms_service() nics_service = vms_service.service(entity.id).nics_service() for nic in vm_param.get('nics'): if search_by_name(nics_service, nic.get('name')) is None: if not self._module.check_mode: nics_service.add( otypes.Nic( name=nic.get('name'), interface=otypes.NicInterface( nic.get('interface', 'virtio') ), vnic_profile=otypes.VnicProfile( id=self.__get_vnic_profile_id(nic), ) if nic.get('profile_name') else None, mac=otypes.Mac( address=nic.get('mac_address') ) if nic.get('mac_address') else None, ) ) self.changed = True def __get_vnic_profile_id(self, nic): """ Return VNIC profile ID looked up by it's name, because there can be more VNIC profiles with same name, other criteria of filter is cluster. """ vnics_service = self._connection.system_service().vnic_profiles_service() clusters_service = self._connection.system_service().clusters_service() cluster = search_by_name(clusters_service, self.param('cluster')) profiles = [ profile for profile in vnics_service.list() if profile.name == nic.get('profile_name') ] cluster_networks = [ net.id for net in self._connection.follow_link(cluster.networks) ] try: return next( profile.id for profile in profiles if profile.network.id in cluster_networks ) except StopIteration: raise Exception( "Profile '%s' was not found in cluster '%s'" % ( nic.get('profile_name'), self.param('cluster') ) ) def update_check(self, entity): return ( equal(self._module.params.get('name'), entity.name) and equal(self._module.params.get('cluster'), get_link_name(self._connection, entity.cluster)) and equal(self._module.params.get('description'), entity.description) and equal(self._module.params.get('comment'), entity.comment) and equal(self._module.params.get('vm_per_user'), entity.max_user_vms) and equal(self._module.params.get('prestarted'), entity.prestarted_vms) and equal(self._module.params.get('vm_count'), entity.size) ) def main(): argument_spec = ovirt_full_argument_spec( id=dict(default=None), state=dict( choices=['present', 'absent'], default='present', ), name=dict(required=True), template=dict(default=None), cluster=dict(default=None), description=dict(default=None), vm=dict(default=None, type='dict'), comment=dict(default=None), vm_per_user=dict(default=None, type='int'), prestarted=dict(default=None, type='int'), vm_count=dict(default=None, type='int'), type=dict(default=None, choices=['automatic', 'manual']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) check_sdk(module) check_params(module) try: auth = module.params.pop('auth') connection = create_connection(auth) vm_pools_service = connection.system_service().vm_pools_service() vm_pools_module = VmPoolsModule( connection=connection, module=module, service=vm_pools_service, ) state = module.params['state'] if state == 'present': ret = vm_pools_module.create() # Wait for all VM pool VMs to be created: if module.params['wait']: vms_service = connection.system_service().vms_service() for vm in vms_service.list(search='pool=%s' % module.params['name']): wait( service=vms_service.service(vm.id), condition=lambda vm: vm.status in [otypes.VmStatus.DOWN, otypes.VmStatus.UP], timeout=module.params['timeout'], ) elif state == 'absent': ret = vm_pools_module.remove() module.exit_json(**ret) except Exception as e: module.fail_json(msg=str(e), exception=traceback.format_exc()) finally: connection.close(logout=auth.get('token') is None) if __name__ == "__main__": main()