summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsible Core Team <info@ansible.com>2020-03-09 09:40:36 +0000
committerAnsible Core Team <info@ansible.com>2020-03-09 09:40:36 +0000
commita3be23f78125630182c6b2c3e43b5f1d821aea7b (patch)
treeccea9e5c312615fa4d333dd412b2d478a3cc1029
parent48fa7e27b03f0cd5370d8892173a1fbfe6efb220 (diff)
downloadansible-a3be23f78125630182c6b2c3e43b5f1d821aea7b.tar.gz
Migrated to ovirt.ovirt
-rw-r--r--lib/ansible/module_utils/ovirt.py868
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py329
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py210
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py182
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_api_info.py98
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_auth.py300
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_cluster.py745
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py120
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py233
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py103
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_disk.py838
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py120
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_event.py249
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_event_info.py170
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py406
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py161
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_group.py185
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_group_info.py118
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_host.py701
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_host_info.py144
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_host_network.py601
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py261
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py182
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py592
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_job.py236
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py181
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_network.py360
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_network_info.py120
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_nic.py318
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py138
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_permission.py320
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py161
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_quota.py319
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py138
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_role.py190
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py137
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py551
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py133
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py285
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py809
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py120
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py138
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py138
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_tag.py257
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py167
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_template.py1087
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_template_info.py120
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_user.py176
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_user_info.py118
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_vm.py2727
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py160
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py485
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py118
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py321
-rw-r--r--lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile_info.py119
-rw-r--r--lib/ansible/plugins/doc_fragments/ovirt.py102
-rw-r--r--lib/ansible/plugins/doc_fragments/ovirt_info.py57
-rw-r--r--test/sanity/ignore.txt256
58 files changed, 0 insertions, 18978 deletions
diff --git a/lib/ansible/module_utils/ovirt.py b/lib/ansible/module_utils/ovirt.py
deleted file mode 100644
index 38b048f95e..0000000000
--- a/lib/ansible/module_utils/ovirt.py
+++ /dev/null
@@ -1,868 +0,0 @@
-# -*- 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/>.
-#
-
-import inspect
-import os
-import time
-
-from abc import ABCMeta, abstractmethod
-from datetime import datetime
-from distutils.version import LooseVersion
-
-from ansible.module_utils.cloud import CloudRetry
-from ansible.module_utils.common._collections_compat import Mapping
-
-try:
- from enum import Enum # enum is a ovirtsdk4 requirement
- import ovirtsdk4 as sdk
- import ovirtsdk4.version as sdk_version
- import ovirtsdk4.types as otypes
- HAS_SDK = LooseVersion(sdk_version.VERSION) >= LooseVersion('4.3.0')
-except ImportError:
- HAS_SDK = False
-
-
-BYTES_MAP = {
- 'kib': 2**10,
- 'mib': 2**20,
- 'gib': 2**30,
- 'tib': 2**40,
- 'pib': 2**50,
-}
-
-
-def check_sdk(module):
- if not HAS_SDK:
- module.fail_json(
- msg='ovirtsdk4 version 4.3.0 or higher is required for this module'
- )
-
-
-def get_dict_of_struct(struct, connection=None, fetch_nested=False, attributes=None):
- """
- Convert SDK Struct type into dictionary.
- """
- res = {}
-
- def resolve_href(value):
- # Fetch nested values of struct:
- try:
- value = connection.follow_link(value)
- except sdk.Error:
- value = None
- nested_obj = dict(
- (attr, convert_value(getattr(value, attr)))
- for attr in attributes if getattr(value, attr, None) is not None
- )
- nested_obj['id'] = getattr(value, 'id', None)
- nested_obj['href'] = getattr(value, 'href', None)
- return nested_obj
-
- def remove_underscore(val):
- if val.startswith('_'):
- val = val[1:]
- remove_underscore(val)
- return val
-
- def convert_value(value):
- nested = False
-
- if isinstance(value, sdk.Struct):
- if not fetch_nested or not value.href:
- return get_dict_of_struct(value)
- return resolve_href(value)
-
- elif isinstance(value, Enum) or isinstance(value, datetime):
- return str(value)
- elif isinstance(value, list) or isinstance(value, sdk.List):
- if isinstance(value, sdk.List) and fetch_nested and value.href:
- try:
- value = connection.follow_link(value)
- nested = True
- except sdk.Error:
- value = []
-
- ret = []
- for i in value:
- if isinstance(i, sdk.Struct):
- if not nested and fetch_nested and i.href:
- ret.append(resolve_href(i))
- elif not nested:
- ret.append(get_dict_of_struct(i))
- else:
- nested_obj = dict(
- (attr, convert_value(getattr(i, attr)))
- for attr in attributes if getattr(i, attr, None)
- )
- nested_obj['id'] = getattr(i, 'id', None)
- ret.append(nested_obj)
- elif isinstance(i, Enum):
- ret.append(str(i))
- else:
- ret.append(i)
- return ret
- else:
- return value
-
- if struct is not None:
- for key, value in struct.__dict__.items():
- if value is None:
- continue
-
- key = remove_underscore(key)
- res[key] = convert_value(value)
-
- return res
-
-
-def engine_version(connection):
- """
- Return string representation of oVirt engine version.
- """
- engine_api = connection.system_service().get()
- engine_version = engine_api.product_info.version
- return '%s.%s' % (engine_version.major, engine_version.minor)
-
-
-def create_connection(auth):
- """
- Create a connection to Python SDK, from task `auth` parameter.
- If user doesnt't have SSO token the `auth` dictionary has following parameters mandatory:
- url, username, password
-
- If user has SSO token the `auth` dictionary has following parameters mandatory:
- url, token
-
- The `ca_file` parameter is mandatory in case user want to use secure connection,
- in case user want to use insecure connection, it's mandatory to send insecure=True.
-
- :param auth: dictionary which contains needed values for connection creation
- :return: Python SDK connection
- """
-
- url = auth.get('url')
- if url is None and auth.get('hostname') is not None:
- url = 'https://{0}/ovirt-engine/api'.format(auth.get('hostname'))
-
- return sdk.Connection(
- url=url,
- username=auth.get('username'),
- password=auth.get('password'),
- ca_file=auth.get('ca_file', None),
- insecure=auth.get('insecure', False),
- token=auth.get('token', None),
- kerberos=auth.get('kerberos', None),
- headers=auth.get('headers', None),
- )
-
-
-def convert_to_bytes(param):
- """
- This method convert units to bytes, which follow IEC standard.
-
- :param param: value to be converted
- """
- if param is None:
- return None
-
- # Get rid of whitespaces:
- param = ''.join(param.split())
-
- # Convert to bytes:
- if len(param) > 3 and param[-3].lower() in ['k', 'm', 'g', 't', 'p']:
- return int(param[:-3]) * BYTES_MAP.get(param[-3:].lower(), 1)
- elif param.isdigit():
- return int(param) * 2**10
- else:
- raise ValueError(
- "Unsupported value(IEC supported): '{value}'".format(value=param)
- )
-
-
-def follow_link(connection, link):
- """
- This method returns the entity of the element which link points to.
-
- :param connection: connection to the Python SDK
- :param link: link of the entity
- :return: entity which link points to
- """
-
- if link:
- return connection.follow_link(link)
- else:
- return None
-
-
-def get_link_name(connection, link):
- """
- This method returns the name of the element which link points to.
-
- :param connection: connection to the Python SDK
- :param link: link of the entity
- :return: name of the entity, which link points to
- """
-
- if link:
- return connection.follow_link(link).name
- else:
- return None
-
-
-def equal(param1, param2, ignore_case=False):
- """
- Compare two parameters and return if they are equal.
- This parameter doesn't run equal operation if first parameter is None.
- With this approach we don't run equal operation in case user don't
- specify parameter in their task.
-
- :param param1: user inputted parameter
- :param param2: value of entity parameter
- :return: True if parameters are equal or first parameter is None, otherwise False
- """
- if param1 is not None:
- if ignore_case:
- return param1.lower() == param2.lower()
- return param1 == param2
- return True
-
-
-def search_by_attributes(service, list_params=None, **kwargs):
- """
- Search for the entity by attributes. Nested entities don't support search
- via REST, so in case using search for nested entity we return all entities
- and filter them by specified attributes.
- """
- list_params = list_params or {}
- # Check if 'list' method support search(look for search parameter):
- if 'search' in inspect.getargspec(service.list)[0]:
- res = service.list(
- # There must be double quotes around name, because some oVirt resources it's possible to create then with space in name.
- search=' and '.join('{0}="{1}"'.format(k, v) for k, v in kwargs.items()),
- **list_params
- )
- else:
- res = [
- e for e in service.list(**list_params) if len([
- k for k, v in kwargs.items() if getattr(e, k, None) == v
- ]) == len(kwargs)
- ]
-
- res = res or [None]
- return res[0]
-
-
-def search_by_name(service, name, **kwargs):
- """
- Search for the entity by its name. Nested entities don't support search
- via REST, so in case using search for nested entity we return all entities
- and filter them by name.
-
- :param service: service of the entity
- :param name: name of the entity
- :return: Entity object returned by Python SDK
- """
- # Check if 'list' method support search(look for search parameter):
- if 'search' in inspect.getargspec(service.list)[0]:
- res = service.list(
- # There must be double quotes around name, because some oVirt resources it's possible to create then with space in name.
- search='name="{name}"'.format(name=name)
- )
- else:
- res = [e for e in service.list() if e.name == name]
-
- if kwargs:
- res = [
- e for e in service.list() if len([
- k for k, v in kwargs.items() if getattr(e, k, None) == v
- ]) == len(kwargs)
- ]
-
- res = res or [None]
- return res[0]
-
-
-def get_entity(service, get_params=None):
- """
- Ignore SDK Error in case of getting an entity from service.
- """
- entity = None
- try:
- if get_params is not None:
- entity = service.get(**get_params)
- else:
- entity = service.get()
- except sdk.Error:
- # We can get here 404, we should ignore it, in case
- # of removing entity for example.
- pass
- return entity
-
-
-def get_id_by_name(service, name, raise_error=True, ignore_case=False):
- """
- Search an entity ID by it's name.
- """
- entity = search_by_name(service, name)
-
- if entity is not None:
- return entity.id
-
- if raise_error:
- raise Exception("Entity '%s' was not found." % name)
-
-
-def wait(
- service,
- condition,
- fail_condition=lambda e: False,
- timeout=180,
- wait=True,
- poll_interval=3,
-):
- """
- Wait until entity fulfill expected condition.
-
- :param service: service of the entity
- :param condition: condition to be fulfilled
- :param fail_condition: if this condition is true, raise Exception
- :param timeout: max time to wait in seconds
- :param wait: if True wait for condition, if False don't wait
- :param poll_interval: Number of seconds we should wait until next condition check
- """
- # Wait until the desired state of the entity:
- if wait:
- start = time.time()
- while time.time() < start + timeout:
- # Exit if the condition of entity is valid:
- entity = get_entity(service)
- if condition(entity):
- return
- elif fail_condition(entity):
- raise Exception("Error while waiting on result state of the entity.")
-
- # Sleep for `poll_interval` seconds if none of the conditions apply:
- time.sleep(float(poll_interval))
-
- raise Exception("Timeout exceed while waiting on result state of the entity.")
-
-
-def __get_auth_dict():
- OVIRT_URL = os.environ.get('OVIRT_URL')
- OVIRT_HOSTNAME = os.environ.get('OVIRT_HOSTNAME')
- OVIRT_USERNAME = os.environ.get('OVIRT_USERNAME')
- OVIRT_PASSWORD = os.environ.get('OVIRT_PASSWORD')
- OVIRT_TOKEN = os.environ.get('OVIRT_TOKEN')
- OVIRT_CAFILE = os.environ.get('OVIRT_CAFILE')
- OVIRT_INSECURE = OVIRT_CAFILE is None
-
- env_vars = None
- if OVIRT_URL is None and OVIRT_HOSTNAME is not None:
- OVIRT_URL = 'https://{0}/ovirt-engine/api'.format(OVIRT_HOSTNAME)
- if OVIRT_URL and ((OVIRT_USERNAME and OVIRT_PASSWORD) or OVIRT_TOKEN):
- env_vars = {
- 'url': OVIRT_URL,
- 'username': OVIRT_USERNAME,
- 'password': OVIRT_PASSWORD,
- 'insecure': OVIRT_INSECURE,
- 'token': OVIRT_TOKEN,
- 'ca_file': OVIRT_CAFILE,
- }
- if env_vars is not None:
- auth = dict(default=env_vars, type='dict')
- else:
- auth = dict(required=True, type='dict')
-
- return auth
-
-
-def ovirt_info_full_argument_spec(**kwargs):
- """
- Extend parameters of info module with parameters which are common to all
- oVirt info modules.
-
- :param kwargs: kwargs to be extended
- :return: extended dictionary with common parameters
- """
- spec = dict(
- auth=__get_auth_dict(),
- fetch_nested=dict(default=False, type='bool'),
- nested_attributes=dict(type='list', default=list()),
- )
- spec.update(kwargs)
- return spec
-
-
-# Left for third-party module compatibility
-def ovirt_facts_full_argument_spec(**kwargs):
- """
- This is deprecated. Please use ovirt_info_full_argument_spec instead!
-
- :param kwargs: kwargs to be extended
- :return: extended dictionary with common parameters
- """
- return ovirt_info_full_argument_spec(**kwargs)
-
-
-def ovirt_full_argument_spec(**kwargs):
- """
- Extend parameters of module with parameters which are common to all oVirt modules.
-
- :param kwargs: kwargs to be extended
- :return: extended dictionary with common parameters
- """
- spec = dict(
- auth=__get_auth_dict(),
- timeout=dict(default=180, type='int'),
- wait=dict(default=True, type='bool'),
- poll_interval=dict(default=3, type='int'),
- fetch_nested=dict(default=False, type='bool'),
- nested_attributes=dict(type='list', default=list()),
- )
- spec.update(kwargs)
- return spec
-
-
-def check_params(module):
- """
- Most modules must have either `name` or `id` specified.
- """
- if module.params.get('name') is None and module.params.get('id') is None:
- module.fail_json(msg='"name" or "id" is required')
-
-
-def engine_supported(connection, version):
- return LooseVersion(engine_version(connection)) >= LooseVersion(version)
-
-
-def check_support(version, connection, module, params):
- """
- Check if parameters used by user are supported by oVirt Python SDK
- and oVirt engine.
- """
- api_version = LooseVersion(engine_version(connection))
- version = LooseVersion(version)
- for param in params:
- if module.params.get(param) is not None:
- return LooseVersion(sdk_version.VERSION) >= version and api_version >= version
-
- return True
-
-
-class BaseModule(object):
- """
- This is base class for oVirt modules. oVirt modules should inherit this
- class and override method to customize specific needs of the module.
- The only abstract method of this class is `build_entity`, which must
- to be implemented in child class.
- """
- __metaclass__ = ABCMeta
-
- def __init__(self, connection, module, service, changed=False):
- self._connection = connection
- self._module = module
- self._service = service
- self._changed = changed
- self._diff = {'after': dict(), 'before': dict()}
-
- @property
- def changed(self):
- return self._changed
-
- @changed.setter
- def changed(self, changed):
- if not self._changed:
- self._changed = changed
-
- @abstractmethod
- def build_entity(self):
- """
- This method should return oVirt Python SDK type, which we want to
- create or update, initialized by values passed by Ansible module.
-
- For example if we want to create VM, we will return following:
- types.Vm(name=self._module.params['vm_name'])
-
- :return: Specific instance of sdk.Struct.
- """
- pass
-
- def param(self, name, default=None):
- """
- Return a module parameter specified by it's name.
- """
- return self._module.params.get(name, default)
-
- def update_check(self, entity):
- """
- This method handle checks whether the entity values are same as values
- passed to ansible module. By default we don't compare any values.
-
- :param entity: Entity we want to compare with Ansible module values.
- :return: True if values are same, so we don't need to update the entity.
- """
- return True
-
- def pre_create(self, entity):
- """
- This method is called right before entity is created.
-
- :param entity: Entity to be created or updated.
- """
- pass
-
- def post_create(self, entity):
- """
- This method is called right after entity is created.
-
- :param entity: Entity which was created.
- """
- pass
-
- def post_update(self, entity):
- """
- This method is called right after entity is updated.
-
- :param entity: Entity which was updated.
- """
- pass
-
- def diff_update(self, after, update):
- for k, v in update.items():
- if isinstance(v, Mapping):
- after[k] = self.diff_update(after.get(k, dict()), v)
- else:
- after[k] = update[k]
- return after
-
- def create(
- self,
- entity=None,
- result_state=None,
- fail_condition=lambda e: False,
- search_params=None,
- update_params=None,
- _wait=None,
- force_create=False,
- **kwargs
- ):
- """
- Method which is called when state of the entity is 'present'. If user
- don't provide `entity` parameter the entity is searched using
- `search_params` parameter. If entity is found it's updated, whether
- the entity should be updated is checked by `update_check` method.
- The corresponding updated entity is build by `build_entity` method.
-
- Function executed after entity is created can optionally be specified
- in `post_create` parameter. Function executed after entity is updated
- can optionally be specified in `post_update` parameter.
-
- :param entity: Entity we want to update, if exists.
- :param result_state: State which should entity has in order to finish task.
- :param fail_condition: Function which checks incorrect state of entity, if it returns `True` Exception is raised.
- :param search_params: Dictionary of parameters to be used for search.
- :param update_params: The params which should be passed to update method.
- :param kwargs: Additional parameters passed when creating entity.
- :return: Dictionary with values returned by Ansible module.
- """
- if entity is None and not force_create:
- entity = self.search_entity(search_params)
-
- self.pre_create(entity)
-
- if entity:
- # Entity exists, so update it:
- entity_service = self._service.service(entity.id)
- if not self.update_check(entity):
- new_entity = self.build_entity()
- if not self._module.check_mode:
- update_params = update_params or {}
- updated_entity = entity_service.update(
- new_entity,
- **update_params
- )
- self.post_update(entity)
-
- # Update diffs only if user specified --diff parameter,
- # so we don't useless overload API:
- if self._module._diff:
- before = get_dict_of_struct(
- entity,
- self._connection,
- fetch_nested=True,
- attributes=['name'],
- )
- after = before.copy()
- self.diff_update(after, get_dict_of_struct(new_entity))
- self._diff['before'] = before
- self._diff['after'] = after
-
- self.changed = True
- else:
- # Entity don't exists, so create it:
- if not self._module.check_mode:
- entity = self._service.add(
- self.build_entity(),
- **kwargs
- )
- self.post_create(entity)
- self.changed = True
-
- if not self._module.check_mode:
- # Wait for the entity to be created and to be in the defined state:
- entity_service = self._service.service(entity.id)
-
- def state_condition(entity):
- return entity
-
- if result_state:
-
- def state_condition(entity):
- return entity and entity.status == result_state
-
- wait(
- service=entity_service,
- condition=state_condition,
- fail_condition=fail_condition,
- wait=_wait if _wait is not None else self._module.params['wait'],
- timeout=self._module.params['timeout'],
- poll_interval=self._module.params['poll_interval'],
- )
-
- return {
- 'changed': self.changed,
- 'id': getattr(entity, 'id', None),
- type(entity).__name__.lower(): get_dict_of_struct(
- struct=entity,
- connection=self._connection,
- fetch_nested=self._module.params.get('fetch_nested'),
- attributes=self._module.params.get('nested_attributes'),
- ),
- 'diff': self._diff,
- }
-
- def pre_remove(self, entity):
- """
- This method is called right before entity is removed.
-
- :param entity: Entity which we want to remove.
- """
- pass
-
- def entity_name(self, entity):
- return "{e_type} '{e_name}'".format(
- e_type=type(entity).__name__.lower(),
- e_name=getattr(entity, 'name', None),
- )
-
- def remove(self, entity=None, search_params=None, **kwargs):
- """
- Method which is called when state of the entity is 'absent'. If user
- don't provide `entity` parameter the entity is searched using
- `search_params` parameter. If entity is found it's removed.
-
- Function executed before remove is executed can optionally be specified
- in `pre_remove` parameter.
-
- :param entity: Entity we want to remove.
- :param search_params: Dictionary of parameters to be used for search.
- :param kwargs: Additional parameters passed when removing entity.
- :return: Dictionary with values returned by Ansible module.
- """
- if entity is None:
- entity = self.search_entity(search_params)
-
- if entity is None:
- return {
- 'changed': self.changed,
- 'msg': "Entity wasn't found."
- }
-
- self.pre_remove(entity)
-
- entity_service = self._service.service(entity.id)
- if not self._module.check_mode:
- entity_service.remove(**kwargs)
- wait(
- service=entity_service,
- condition=lambda entity: not entity,
- wait=self._module.params['wait'],
- timeout=self._module.params['timeout'],
- poll_interval=self._module.params['poll_interval'],
- )
- self.changed = True
-
- return {
- 'changed': self.changed,
- 'id': entity.id,
- type(entity).__name__.lower(): get_dict_of_struct(
- struct=entity,
- connection=self._connection,
- fetch_nested=self._module.params.get('fetch_nested'),
- attributes=self._module.params.get('nested_attributes'),
- ),
- }
-
- def action(
- self,
- action,
- entity=None,
- action_condition=lambda e: e,
- wait_condition=lambda e: e,
- fail_condition=lambda e: False,
- pre_action=lambda e: e,
- post_action=lambda e: None,
- search_params=None,
- **kwargs
- ):
- """
- This method is executed when we want to change the state of some oVirt
- entity. The action to be executed on oVirt service is specified by
- `action` parameter. Whether the action should be executed can be
- specified by passing `action_condition` parameter. State which the
- entity should be in after execution of the action can be specified
- by `wait_condition` parameter.
-
- Function executed before an action on entity can optionally be specified
- in `pre_action` parameter. Function executed after an action on entity can
- optionally be specified in `post_action` parameter.
-
- :param action: Action which should be executed by service on entity.
- :param entity: Entity we want to run action on.
- :param action_condition: Function which is executed when checking if action should be executed.
- :param fail_condition: Function which checks incorrect state of entity, if it returns `True` Exception is raised.
- :param wait_condition: Function which is executed when waiting on result state.
- :param pre_action: Function which is executed before running the action.
- :param post_action: Function which is executed after running the action.
- :param search_params: Dictionary of parameters to be used for search.
- :param kwargs: Additional parameters passed to action.
- :return: Dictionary with values returned by Ansible module.
- """
- if entity is None:
- entity = self.search_entity(search_params)
-
- entity = pre_action(entity)
-
- if entity is None:
- self._module.fail_json(
- msg="Entity not found, can't run action '{0}'.".format(
- action
- )
- )
-
- entity_service = self._service.service(entity.id)
- entity = entity_service.get()
- if action_condition(entity):
- if not self._module.check_mode:
- getattr(entity_service, action)(**kwargs)
- self.changed = True
-
- post_action(entity)
-
- wait(
- service=self._service.service(entity.id),
- condition=wait_condition,
- fail_condition=fail_condition,
- wait=self._module.params['wait'],
- timeout=self._module.params['timeout'],
- poll_interval=self._module.params['poll_interval'],
- )
- return {
- 'changed': self.changed,
- 'id': entity.id,
- type(entity).__name__.lower(): get_dict_of_struct(
- struct=entity,
- connection=self._connection,
- fetch_nested=self._module.params.get('fetch_nested'),
- attributes=self._module.params.get('nested_attributes'),
- ),
- 'diff': self._diff,
- }
-
- def wait_for_import(self, condition=lambda e: True):
- if self._module.params['wait']:
- start = time.time()
- timeout = self._module.params['timeout']
- poll_interval = self._module.params['poll_interval']
- while time.time() < start + timeout:
- entity = self.search_entity()
- if entity and condition(entity):
- return entity
- time.sleep(poll_interval)
-
- def search_entity(self, search_params=None, list_params=None):
- """
- Always first try to search by `ID`, if ID isn't specified,
- check if user constructed special search in `search_params`,
- if not search by `name`.
- """
- entity = None
-
- if 'id' in self._module.params and self._module.params['id'] is not None:
- entity = get_entity(self._service.service(self._module.params['id']), get_params=list_params)
- elif search_params is not None:
- entity = search_by_attributes(self._service, list_params=list_params, **search_params)
- elif self._module.params.get('name') is not None:
- entity = search_by_attributes(self._service, list_params=list_params, name=self._module.params['name'])
-
- return entity
-
- def _get_major(self, full_version):
- if full_version is None or full_version == "":
- return None
- if isinstance(full_version, otypes.Version):
- return int(full_version.major)
- return int(full_version.split('.')[0])
-
- def _get_minor(self, full_version):
- if full_version is None or full_version == "":
- return None
- if isinstance(full_version, otypes.Version):
- return int(full_version.minor)
- return int(full_version.split('.')[1])
-
-
-def _sdk4_error_maybe():
- """
- Allow for ovirtsdk4 not being installed.
- """
- if HAS_SDK:
- return sdk.Error
- return type(None)
-
-
-class OvirtRetry(CloudRetry):
- base_class = _sdk4_error_maybe()
-
- @staticmethod
- def status_code_from_exception(error):
- return error.code
-
- @staticmethod
- def found(response_code, catch_extra_error_codes=None):
- # This is a list of error codes to retry.
- retry_on = [
- # HTTP status: Conflict
- 409,
- ]
- if catch_extra_error_codes:
- retry_on.extend(catch_extra_error_codes)
-
- return response_code in retry_on
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py b/lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py
deleted file mode 100644
index 0711c2e24b..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py
+++ /dev/null
@@ -1,329 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2017, Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_affinity_group
-short_description: Module to manage affinity groups in oVirt/RHV
-version_added: "2.3"
-author:
-- Ondra Machacek (@machacekondra)
-description:
- - "This module manage affinity groups in oVirt/RHV. It can also manage assignments
- of those groups to VMs."
-options:
- name:
- description:
- - Name of the affinity group to manage.
- required: true
- state:
- description:
- - Should the affinity group be present or absent.
- choices: [ absent, present ]
- default: present
- cluster:
- description:
- - Name of the cluster of the affinity group.
- description:
- description:
- - Description of the affinity group.
- host_enforcing:
- description:
- - If I(yes) VM cannot start on host if it does not satisfy the C(host_rule).
- - This parameter is support since oVirt/RHV 4.1 version.
- type: bool
- host_rule:
- description:
- - If I(positive) I(all) VMs in this group should run on the this host.
- - If I(negative) I(no) VMs in this group should run on the this host.
- - If I(disabled) this affinity group doesn't take effect.
- - This parameter is support since oVirt/RHV 4.1 version.
- choices: [ disabled, negative, positive ]
- vm_enforcing:
- description:
- - If I(yes) VM cannot start if it does not satisfy the C(vm_rule).
- type: bool
- vm_rule:
- description:
- - If I(positive) I(all) VMs in this group should run on the host defined by C(host_rule).
- - If I(negative) I(no) VMs in this group should run on the host defined by C(host_rule).
- - If I(disabled) this affinity group doesn't take effect.
- choices: [ disabled, negative, positive ]
- vms:
- description:
- - List of the VMs names, which should have assigned this affinity group.
- hosts:
- description:
- - List of the hosts names, which should have assigned this affinity group.
- - This parameter is support since oVirt/RHV 4.1 version.
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-- name: Create(if not exists) and assign affinity group to VMs vm1 and vm2 and host host1
- ovirt_affinity_group:
- name: mygroup
- cluster: mycluster
- vm_enforcing: true
- vm_rule: positive
- host_enforcing: true
- host_rule: positive
- vms:
- - vm1
- - vm2
- hosts:
- - host1
-
-- name: Detach VMs from affinity group and disable VM rule
- ovirt_affinity_group:
- name: mygroup
- cluster: mycluster
- vm_enforcing: false
- vm_rule: disabled
- host_enforcing: true
- host_rule: positive
- vms: []
- hosts:
- - host1
- - host2
-
-- name: Remove affinity group
- ovirt_affinity_group:
- state: absent
- cluster: mycluster
- name: mygroup
-'''
-
-RETURN = '''
-id:
- description: ID of the affinity group which is managed
- returned: On success if affinity group is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-affinity_group:
- description: "Dictionary of all the affinity group attributes. Affinity group attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/affinity_group."
- returned: On success if affinity group is found.
- type: str
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_support,
- create_connection,
- get_id_by_name,
- equal,
- engine_supported,
- ovirt_full_argument_spec,
- search_by_name,
-)
-
-
-class AffinityGroupsModule(BaseModule):
-
- def __init__(self, vm_ids, host_ids, *args, **kwargs):
- super(AffinityGroupsModule, self).__init__(*args, **kwargs)
- self._vm_ids = vm_ids
- self._host_ids = host_ids
-
- def update_vms(self, affinity_group):
- """
- This method iterate via the affinity VM assignments and datech the VMs
- which should not be attached to affinity and attach VMs which should be
- attached to affinity.
- """
- assigned_vms = self.assigned_vms(affinity_group)
- to_remove = [vm for vm in assigned_vms if vm not in self._vm_ids]
- to_add = [vm for vm in self._vm_ids if vm not in assigned_vms]
- ag_service = self._service.group_service(affinity_group.id)
- for vm in to_remove:
- ag_service.vms_service().vm_service(vm).remove()
- for vm in to_add:
- # API return <action> element instead of VM element, so we
- # need to WA this issue, for oVirt/RHV versions having this bug:
- try:
- ag_service.vms_service().add(otypes.Vm(id=vm))
- except ValueError as ex:
- if 'complete' not in str(ex):
- raise ex
-
- def post_create(self, affinity_group):
- self.update_vms(affinity_group)
-
- def post_update(self, affinity_group):
- self.update_vms(affinity_group)
-
- def build_entity(self):
- affinity_group = otypes.AffinityGroup(
- name=self._module.params['name'],
- description=self._module.params['description'],
- positive=(
- self._module.params['vm_rule'] == 'positive'
- ) if self._module.params['vm_rule'] is not None else None,
- enforcing=(
- self._module.params['vm_enforcing']
- ) if self._module.params['vm_enforcing'] is not None else None,
- )
-
- # Those attributes are Supported since 4.1:
- if not engine_supported(self._connection, '4.1'):
- return affinity_group
-
- affinity_group.hosts_rule = otypes.AffinityRule(
- positive=(
- self.param('host_rule') == 'positive'
- ) if self.param('host_rule') is not None else None,
- enforcing=self.param('host_enforcing'),
- ) if (
- self.param('host_enforcing') is not None or
- self.param('host_rule') is not None
- ) else None
-
- affinity_group.vms_rule = otypes.AffinityRule(
- positive=(
- self.param('vm_rule') == 'positive'
- ) if self.param('vm_rule') is not None else None,
- enforcing=self.param('vm_enforcing'),
- enabled=(
- self.param('vm_rule') in ['negative', 'positive']
- ) if self.param('vm_rule') is not None else None,
- ) if (
- self.param('vm_enforcing') is not None or
- self.param('vm_rule') is not None
- ) else None
-
- affinity_group.hosts = [
- otypes.Host(id=host_id) for host_id in self._host_ids
- ] if self._host_ids is not None else None
-
- return affinity_group
-
- def assigned_vms(self, affinity_group):
- if getattr(affinity_group.vms, 'href', None):
- return sorted([
- vm.id for vm in self._connection.follow_link(affinity_group.vms)
- ])
- else:
- return sorted([vm.id for vm in affinity_group.vms])
-
- def update_check(self, entity):
- assigned_vms = self.assigned_vms(entity)
- do_update = (
- equal(self.param('description'), entity.description) and equal(self.param('vm_enforcing'), entity.enforcing) and equal(
- self.param('vm_rule') == 'positive' if self.param('vm_rule') else None,
- entity.positive
- ) and equal(self._vm_ids, assigned_vms)
- )
- # Following attributes is supported since 4.1,
- # so return if it doesn't exist:
- if not engine_supported(self._connection, '4.1'):
- return do_update
-
- # Following is supported since 4.1:
- return do_update and (
- equal(
- self.param('host_rule') == 'positive' if self.param('host_rule') else None,
- entity.hosts_rule.positive) and equal(self.param('host_enforcing'), entity.hosts_rule.enforcing) and equal(
- self.param('vm_rule') in ['negative', 'positive'] if self.param('vm_rule') else None,
- entity.vms_rule.enabled) and equal(self._host_ids, sorted([host.id for host in entity.hosts]))
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(type='str', default='present', choices=['absent', 'present']),
- cluster=dict(type='str', required=True),
- name=dict(type='str', required=True),
- description=dict(type='str'),
- vm_enforcing=dict(type='bool'),
- vm_rule=dict(type='str', choices=['disabled', 'negative', 'positive']),
- host_enforcing=dict(type='bool'),
- host_rule=dict(type='str', choices=['disabled', 'negative', 'positive']),
- vms=dict(type='list'),
- hosts=dict(type='list'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- # Check if unsupported parameters were passed:
- supported_41 = ('host_enforcing', 'host_rule', 'hosts')
- if not check_support(
- version='4.1',
- connection=connection,
- module=module,
- params=supported_41,
- ):
- module.fail_json(
- msg='Following parameters are supported since 4.1: {params}'.format(
- params=supported_41,
- )
- )
- clusters_service = connection.system_service().clusters_service()
- vms_service = connection.system_service().vms_service()
- hosts_service = connection.system_service().hosts_service()
- cluster_name = module.params['cluster']
- cluster = search_by_name(clusters_service, cluster_name)
- if cluster is None:
- raise Exception("Cluster '%s' was not found." % cluster_name)
- cluster_service = clusters_service.cluster_service(cluster.id)
- affinity_groups_service = cluster_service.affinity_groups_service()
-
- # Fetch VM ids which should be assigned to affinity group:
- vm_ids = sorted([
- get_id_by_name(vms_service, vm_name)
- for vm_name in module.params['vms']
- ]) if module.params['vms'] is not None else None
- # Fetch host ids which should be assigned to affinity group:
- host_ids = sorted([
- get_id_by_name(hosts_service, host_name)
- for host_name in module.params['hosts']
- ]) if module.params['hosts'] is not None else None
-
- affinity_groups_module = AffinityGroupsModule(
- connection=connection,
- module=module,
- service=affinity_groups_service,
- vm_ids=vm_ids,
- host_ids=host_ids,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = affinity_groups_module.create()
- elif state == 'absent':
- ret = affinity_groups_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py b/lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py
deleted file mode 100644
index 6eae6f1db0..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py
+++ /dev/null
@@ -1,210 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_affinity_label
-short_description: Module to manage affinity labels in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "This module manage affinity labels in oVirt/RHV. It can also manage assignments
- of those labels to hosts and VMs."
-options:
- name:
- description:
- - "Name of the affinity label to manage."
- required: true
- state:
- description:
- - "Should the affinity label be present or absent."
- choices: ['present', 'absent']
- default: present
- cluster:
- description:
- - "Name of the cluster where vms and hosts resides."
- vms:
- description:
- - "List of the VMs names, which should have assigned this affinity label."
- hosts:
- description:
- - "List of the hosts names, which should have assigned this affinity label."
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create(if not exists) and assign affinity label to vms vm1 and vm2 and host host1
-- ovirt_affinity_label:
- name: mylabel
- cluster: mycluster
- vms:
- - vm1
- - vm2
- hosts:
- - host1
-
-# To detach all VMs from label
-- ovirt_affinity_label:
- name: mylabel
- cluster: mycluster
- vms: []
-
-# Remove affinity label
-- ovirt_affinity_label:
- state: absent
- name: mylabel
-'''
-
-RETURN = '''
-id:
- description: ID of the affinity label which is managed
- returned: On success if affinity label is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-affinity_label:
- description: "Dictionary of all the affinity label attributes. Affinity label attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/affinity_label."
- type: dict
- returned: On success if affinity label is found.
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from collections import defaultdict
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- ovirt_full_argument_spec,
-)
-
-
-class AffinityLabelsModule(BaseModule):
-
- def build_entity(self):
- return otypes.AffinityLabel(name=self._module.params['name'])
-
- def post_create(self, entity):
- self.update_check(entity)
-
- def pre_remove(self, entity):
- self._module.params['vms'] = []
- self._module.params['hosts'] = []
- self.update_check(entity)
-
- def _update_label_assignments(self, entity, name, label_obj_type):
- objs_service = getattr(self._connection.system_service(), '%s_service' % name)()
- if self._module.params[name] is not None:
- objs = self._connection.follow_link(getattr(entity, name))
- objs_names = defaultdict(list)
- for obj in objs:
- labeled_entity = objs_service.service(obj.id).get()
- if self._module.params['cluster'] is None:
- objs_names[labeled_entity.name].append(obj.id)
- elif self._connection.follow_link(labeled_entity.cluster).name == self._module.params['cluster']:
- objs_names[labeled_entity.name].append(obj.id)
-
- for obj in self._module.params[name]:
- if obj not in objs_names:
- for obj_id in objs_service.list(
- search='name=%s and cluster=%s' % (obj, self._module.params['cluster'])
- ):
- label_service = getattr(self._service.service(entity.id), '%s_service' % name)()
- if not self._module.check_mode:
- label_service.add(**{
- name[:-1]: label_obj_type(id=obj_id.id)
- })
- self.changed = True
-
- for obj in objs_names:
- if obj not in self._module.params[name]:
- label_service = getattr(self._service.service(entity.id), '%s_service' % name)()
- if not self._module.check_mode:
- for obj_id in objs_names[obj]:
- label_service.service(obj_id).remove()
- self.changed = True
-
- def update_check(self, entity):
- self._update_label_assignments(entity, 'vms', otypes.Vm)
- self._update_label_assignments(entity, 'hosts', otypes.Host)
- return True
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- cluster=dict(default=None),
- name=dict(default=None, required=True),
- vms=dict(default=None, type='list'),
- hosts=dict(default=None, type='list'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ('state', 'present', ['cluster']),
- ],
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- affinity_labels_service = connection.system_service().affinity_labels_service()
- affinity_labels_module = AffinityLabelsModule(
- connection=connection,
- module=module,
- service=affinity_labels_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = affinity_labels_module.create()
- elif state == 'absent':
- ret = affinity_labels_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py
deleted file mode 100644
index 4a9babcfba..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_affinity_label_info
-short_description: Retrieve information about one or more oVirt/RHV affinity labels
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV affinity labels."
- - This module was called C(ovirt_affinity_label_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_affinity_label_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_affinity_labels), which
- contains a list of affinity labels. You need to register the result with
- the I(register) keyword to use it."
-options:
- name:
- description:
- - "Name of the affinity labels which should be listed."
- vm:
- description:
- - "Name of the VM, which affinity labels should be listed."
- host:
- description:
- - "Name of the host, which affinity labels should be listed."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all affinity labels, which names start with C(label):
-- ovirt_affinity_label_info:
- name: label*
- register: result
-- debug:
- msg: "{{ result.ovirt_affinity_labels }}"
-
-# Gather information about all affinity labels, which are assigned to VMs
-# which names start with C(postgres):
-- ovirt_affinity_label_info:
- vm: postgres*
- register: result
-- debug:
- msg: "{{ result.ovirt_affinity_labels }}"
-
-# Gather information about all affinity labels, which are assigned to hosts
-# which names start with C(west):
-- ovirt_affinity_label_info:
- host: west*
- register: result
-- debug:
- msg: "{{ result.ovirt_affinity_labels }}"
-
-# Gather information about all affinity labels, which are assigned to hosts
-# which names start with C(west) or VMs which names start with C(postgres):
-- ovirt_affinity_label_info:
- host: west*
- vm: postgres*
- register: result
-- debug:
- msg: "{{ result.ovirt_affinity_labels }}"
-'''
-
-RETURN = '''
-ovirt_affinity_labels:
- description: "List of dictionaries describing the affinity labels. Affinity labels attributes are mapped to dictionary keys,
- all affinity labels attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/affinity_label."
- returned: On success.
- type: list
-'''
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- search_by_name,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- name=dict(default=None),
- host=dict(default=None),
- vm=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_affinity_label_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_affinity_label_facts' module has been renamed to 'ovirt_affinity_label_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- affinity_labels_service = connection.system_service().affinity_labels_service()
- labels = []
- all_labels = affinity_labels_service.list()
- if module.params['name']:
- labels.extend([
- l for l in all_labels
- if fnmatch.fnmatch(l.name, module.params['name'])
- ])
- if module.params['host']:
- hosts_service = connection.system_service().hosts_service()
- if search_by_name(hosts_service, module.params['host']) is None:
- raise Exception("Host '%s' was not found." % module.params['host'])
- labels.extend([
- label
- for label in all_labels
- for host in connection.follow_link(label.hosts)
- if fnmatch.fnmatch(hosts_service.service(host.id).get().name, module.params['host'])
- ])
- if module.params['vm']:
- vms_service = connection.system_service().vms_service()
- if search_by_name(vms_service, module.params['vm']) is None:
- raise Exception("Vm '%s' was not found." % module.params['vm'])
- labels.extend([
- label
- for label in all_labels
- for vm in connection.follow_link(label.vms)
- if fnmatch.fnmatch(vms_service.service(vm.id).get().name, module.params['vm'])
- ])
-
- if not (module.params['vm'] or module.params['host'] or module.params['name']):
- labels = all_labels
-
- result = dict(
- ovirt_affinity_labels=[
- get_dict_of_struct(
- struct=l,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for l in labels
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_api_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_api_info.py
deleted file mode 100644
index e639ea4982..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_api_info.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017 Ansible Project
-# 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: ovirt_api_info
-short_description: Retrieve information about the oVirt/RHV API
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.5"
-description:
- - "Retrieve information about the oVirt/RHV API."
- - This module was called C(ovirt_api_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_api_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_api),
- which contains a information about oVirt/RHV API. You need to register the result with
- the I(register) keyword to use it."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information oVirt API:
-- ovirt_api_info:
- register: result
-- debug:
- msg: "{{ result.ovirt_api }}"
-'''
-
-RETURN = '''
-ovirt_api:
- description: "Dictionary describing the oVirt API information.
- Api attributes are mapped to dictionary keys,
- all API attributes can be found at following
- url: https://ovirt.example.com/ovirt-engine/api/model#types/api."
- returned: On success.
- type: dict
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec()
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_api_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_api_facts' module has been renamed to 'ovirt_api_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- api = connection.system_service().get()
- result = dict(
- ovirt_api=get_dict_of_struct(
- struct=api,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- )
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_auth.py b/lib/ansible/modules/cloud/ovirt/ovirt_auth.py
deleted file mode 100644
index c8f7407b24..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_auth.py
+++ /dev/null
@@ -1,300 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_auth
-short_description: "Module to manage authentication to oVirt/RHV"
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.2"
-description:
- - "This module authenticates to oVirt/RHV engine and creates SSO token, which should be later used in
- all other oVirt/RHV modules, so all modules don't need to perform login and logout.
- This module returns an Ansible fact called I(ovirt_auth). Every module can use this
- fact as C(auth) parameter, to perform authentication."
-options:
- state:
- default: present
- choices: ['present', 'absent']
- description:
- - "Specifies if a token should be created or revoked."
- username:
- required: False
- description:
- - "The name of the user. For example: I(admin@internal)
- Default value is set by I(OVIRT_USERNAME) environment variable."
- password:
- required: False
- description:
- - "The password of the user. Default value is set by I(OVIRT_PASSWORD) environment variable."
- token:
- required: False
- description:
- - "SSO token to be used instead of login with username/password.
- Default value is set by I(OVIRT_TOKEN) environment variable."
- version_added: 2.5
- url:
- required: False
- description:
- - "A string containing the API URL of the server.
- For example: I(https://server.example.com/ovirt-engine/api).
- Default value is set by I(OVIRT_URL) environment variable."
- - "Either C(url) or C(hostname) is required."
- hostname:
- required: False
- description:
- - "A string containing the hostname of the server.
- For example: I(server.example.com).
- Default value is set by I(OVIRT_HOSTNAME) environment variable."
- - "Either C(url) or C(hostname) is required."
- version_added: "2.6"
- insecure:
- required: False
- description:
- - "A boolean flag that indicates if the server TLS certificate and host name should be checked."
- type: bool
- ca_file:
- required: False
- description:
- - "A PEM file containing the trusted CA certificates. The
- certificate presented by the server will be verified using these CA
- certificates. If C(ca_file) parameter is not set, system wide
- CA certificate store is used.
- Default value is set by I(OVIRT_CAFILE) environment variable."
- timeout:
- required: False
- description:
- - "The maximum total time to wait for the response, in
- seconds. A value of zero (the default) means wait forever. If
- the timeout expires before the response is received an exception
- will be raised."
- compress:
- required: False
- description:
- - "A boolean flag indicating if the SDK should ask
- the server to send compressed responses. The default is I(True).
- Note that this is a hint for the server, and that it may return
- uncompressed data even when this parameter is set to I(True)."
- type: bool
- kerberos:
- required: False
- description:
- - "A boolean flag indicating if Kerberos authentication
- should be used instead of the default basic authentication."
- type: bool
- headers:
- required: False
- description:
- - "A dictionary of HTTP headers to be added to each API call."
- version_added: "2.4"
-
-requirements:
- - python >= 2.7
- - ovirt-engine-sdk-python >= 4.3.0
-notes:
- - "Everytime you use ovirt_auth module to obtain ticket, you need to also revoke the ticket,
- when you no longer need it, otherwise the ticket would be revoked by engine when it expires.
- For an example of how to achieve that, please take a look at I(examples) section."
- - "In order to use this module you have to install oVirt/RHV Python SDK.
- To ensure it's installed with correct version you can create the following task:
- I(pip: name=ovirt-engine-sdk-python version=4.3.0)"
- - "Note that in oVirt/RHV 4.1 if you want to use a user which is not administrator
- you must enable the I(ENGINE_API_FILTER_BY_DEFAULT) variable in engine. In
- oVirt/RHV 4.2 and later it's enabled by default."
-'''
-
-EXAMPLES = '''
- - block:
- # Create a vault with `ovirt_password` variable which store your
- # oVirt/RHV user's password, and include that yaml file with variable:
- - include_vars: ovirt_password.yml
-
- - name: Obtain SSO token with using username/password credentials
- ovirt_auth:
- url: https://ovirt.example.com/ovirt-engine/api
- username: admin@internal
- ca_file: ca.pem
- password: "{{ ovirt_password }}"
-
- # Previous task generated I(ovirt_auth) fact, which you can later use
- # in different modules as follows:
- - ovirt_vm:
- auth: "{{ ovirt_auth }}"
- state: absent
- name: myvm
-
- always:
- - name: Always revoke the SSO token
- ovirt_auth:
- state: absent
- ovirt_auth: "{{ ovirt_auth }}"
-
-# When user will set following environment variables:
-# OVIRT_URL = https://fqdn/ovirt-engine/api
-# OVIRT_USERNAME = admin@internal
-# OVIRT_PASSWORD = the_password
-# User can login the oVirt using environment variable instead of variables
-# in yaml file.
-# This is mainly useful when using Ansible Tower or AWX, as it will work
-# for Red Hat Virtualization credentials type.
- - name: Obtain SSO token
- ovirt_auth:
- state: present
-'''
-
-RETURN = '''
-ovirt_auth:
- description: Authentication facts, needed to perform authentication to oVirt/RHV.
- returned: success
- type: complex
- contains:
- token:
- description: SSO token which is used for connection to oVirt/RHV engine.
- returned: success
- type: str
- sample: "kdfVWp9ZgeewBXV-iq3Js1-xQJZPSEQ334FLb3eksoEPRaab07DhZ8ED8ghz9lJd-MQ2GqtRIeqhvhCkrUWQPw"
- url:
- description: URL of the oVirt/RHV engine API endpoint.
- returned: success
- type: str
- sample: "https://ovirt.example.com/ovirt-engine/api"
- ca_file:
- description: CA file, which is used to verify SSL/TLS connection.
- returned: success
- type: str
- sample: "ca.pem"
- insecure:
- description: Flag indicating if insecure connection is used.
- returned: success
- type: bool
- sample: False
- timeout:
- description: Number of seconds to wait for response.
- returned: success
- type: int
- sample: 0
- compress:
- description: Flag indicating if compression is used for connection.
- returned: success
- type: bool
- sample: True
- kerberos:
- description: Flag indicating if kerberos is used for authentication.
- returned: success
- type: bool
- sample: False
- headers:
- description: Dictionary of HTTP headers to be added to each API call.
- returned: success
- type: dict
-'''
-
-import os
-import traceback
-
-try:
- import ovirtsdk4 as sdk
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import check_sdk
-
-
-def main():
- module = AnsibleModule(
- argument_spec=dict(
- url=dict(default=None),
- hostname=dict(default=None),
- username=dict(default=None),
- password=dict(default=None, no_log=True),
- ca_file=dict(default=None, type='path'),
- insecure=dict(required=False, type='bool', default=None),
- timeout=dict(required=False, type='int', default=0),
- compress=dict(required=False, type='bool', default=True),
- kerberos=dict(required=False, type='bool', default=False),
- headers=dict(required=False, type='dict'),
- state=dict(default='present', choices=['present', 'absent']),
- token=dict(default=None),
- ovirt_auth=dict(required=None, type='dict'),
- ),
- required_if=[
- ('state', 'absent', ['ovirt_auth']),
- ],
- supports_check_mode=True,
- )
- check_sdk(module)
-
- state = module.params.get('state')
- if state == 'present':
- params = module.params
- elif state == 'absent':
- params = module.params['ovirt_auth']
-
- def get_required_parameter(param, env_var, required=False):
- var = params.get(param) or os.environ.get(env_var)
- if not var and required and state == 'present':
- module.fail_json(msg="'%s' is a required parameter." % param)
-
- return var
-
- url = get_required_parameter('url', 'OVIRT_URL', required=False)
- hostname = get_required_parameter('hostname', 'OVIRT_HOSTNAME', required=False)
- if url is None and hostname is None:
- module.fail_json(msg="You must specify either 'url' or 'hostname'.")
-
- if url is None and hostname is not None:
- url = 'https://{0}/ovirt-engine/api'.format(hostname)
-
- username = get_required_parameter('username', 'OVIRT_USERNAME')
- password = get_required_parameter('password', 'OVIRT_PASSWORD')
- token = get_required_parameter('token', 'OVIRT_TOKEN')
- ca_file = get_required_parameter('ca_file', 'OVIRT_CAFILE')
- insecure = params.get('insecure') if params.get('insecure') is not None else not bool(ca_file)
-
- connection = sdk.Connection(
- url=url,
- username=username,
- password=password,
- ca_file=ca_file,
- insecure=insecure,
- timeout=params.get('timeout'),
- compress=params.get('compress'),
- kerberos=params.get('kerberos'),
- headers=params.get('headers'),
- token=token,
- )
- try:
- token = connection.authenticate()
- module.exit_json(
- changed=False,
- ansible_facts=dict(
- ovirt_auth=dict(
- token=token,
- url=url,
- ca_file=ca_file,
- insecure=insecure,
- timeout=params.get('timeout'),
- compress=params.get('compress'),
- kerberos=params.get('kerberos'),
- headers=params.get('headers'),
- ) if state == 'present' else dict()
- )
- )
- except Exception as e:
- module.fail_json(msg=str(e), exception=traceback.format_exc())
- finally:
- # Close the connection, but don't revoke token
- connection.close(logout=state == 'absent')
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_cluster.py b/lib/ansible/modules/cloud/ovirt/ovirt_cluster.py
deleted file mode 100644
index dc15c61604..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_cluster.py
+++ /dev/null
@@ -1,745 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_cluster
-short_description: Module to manage clusters in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage clusters in oVirt/RHV"
-options:
- id:
- description:
- - "ID of the cluster to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the cluster to manage."
- required: true
- state:
- description:
- - "Should the cluster be present or absent."
- choices: ['present', 'absent']
- default: present
- data_center:
- description:
- - "Datacenter name where cluster reside."
- description:
- description:
- - "Description of the cluster."
- comment:
- description:
- - "Comment of the cluster."
- network:
- description:
- - "Management network of cluster to access cluster hosts."
- ballooning:
- description:
- - "If I(True) enable memory balloon optimization. Memory balloon is used to
- re-distribute / reclaim the host memory based on VM needs
- in a dynamic way."
- type: bool
- virt:
- description:
- - "If I(True), hosts in this cluster will be used to run virtual machines."
- type: bool
- gluster:
- description:
- - "If I(True), hosts in this cluster will be used as Gluster Storage
- server nodes, and not for running virtual machines."
- - "By default the cluster is created for virtual machine hosts."
- type: bool
- threads_as_cores:
- description:
- - "If I(True) the exposed host threads would be treated as cores
- which can be utilized by virtual machines."
- type: bool
- ksm:
- description:
- - "I I(True) MoM enables to run Kernel Same-page Merging I(KSM) when
- necessary and when it can yield a memory saving benefit that
- outweighs its CPU cost."
- type: bool
- ksm_numa:
- description:
- - "If I(True) enables KSM C(ksm) for best performance inside NUMA nodes."
- type: bool
- ha_reservation:
- description:
- - "If I(True) enables the oVirt/RHV to monitor cluster capacity for highly
- available virtual machines."
- type: bool
- trusted_service:
- description:
- - "If I(True) enables integration with an OpenAttestation server."
- type: bool
- vm_reason:
- description:
- - "If I(True) enables an optional reason field when a virtual machine
- is shut down from the Manager, allowing the administrator to
- provide an explanation for the maintenance."
- type: bool
- host_reason:
- description:
- - "If I(True) enables an optional reason field when a host is placed
- into maintenance mode from the Manager, allowing the administrator
- to provide an explanation for the maintenance."
- type: bool
- memory_policy:
- description:
- - "I(disabled) - Disables memory page sharing."
- - "I(server) - Sets the memory page sharing threshold to 150% of the system memory on each host."
- - "I(desktop) - Sets the memory page sharing threshold to 200% of the system memory on each host."
- choices: ['disabled', 'server', 'desktop']
- rng_sources:
- description:
- - "List that specify the random number generator devices that all hosts in the cluster will use."
- - "Supported generators are: I(hwrng) and I(random)."
- spice_proxy:
- description:
- - "The proxy by which the SPICE client will connect to virtual machines."
- - "The address must be in the following format: I(protocol://[host]:[port])"
- fence_enabled:
- description:
- - "If I(True) enables fencing on the cluster."
- - "Fencing is enabled by default."
- type: bool
- fence_skip_if_gluster_bricks_up:
- description:
- - "A flag indicating if fencing should be skipped if Gluster bricks are up and running in the host being fenced."
- - "This flag is optional, and the default value is `false`."
- type: bool
- version_added: "2.8"
- fence_skip_if_gluster_quorum_not_met:
- description:
- - "A flag indicating if fencing should be skipped if Gluster bricks are up and running and Gluster quorum will not
- be met without those bricks."
- - "This flag is optional, and the default value is `false`."
- type: bool
- version_added: "2.8"
- fence_skip_if_sd_active:
- description:
- - "If I(True) any hosts in the cluster that are Non Responsive
- and still connected to storage will not be fenced."
- type: bool
- fence_skip_if_connectivity_broken:
- description:
- - "If I(True) fencing will be temporarily disabled if the percentage
- of hosts in the cluster that are experiencing connectivity issues
- is greater than or equal to the defined threshold."
- - "The threshold can be specified by C(fence_connectivity_threshold)."
- type: bool
- fence_connectivity_threshold:
- description:
- - "The threshold used by C(fence_skip_if_connectivity_broken)."
- resilience_policy:
- description:
- - "The resilience policy defines how the virtual machines are prioritized in the migration."
- - "Following values are supported:"
- - "C(do_not_migrate) - Prevents virtual machines from being migrated. "
- - "C(migrate) - Migrates all virtual machines in order of their defined priority."
- - "C(migrate_highly_available) - Migrates only highly available virtual machines to prevent overloading other hosts."
- choices: ['do_not_migrate', 'migrate', 'migrate_highly_available']
- migration_bandwidth:
- description:
- - "The bandwidth settings define the maximum bandwidth of both outgoing and incoming migrations per host."
- - "Following bandwidth options are supported:"
- - "C(auto) - Bandwidth is copied from the I(rate limit) [Mbps] setting in the data center host network QoS."
- - "C(hypervisor_default) - Bandwidth is controlled by local VDSM setting on sending host."
- - "C(custom) - Defined by user (in Mbps)."
- choices: ['auto', 'hypervisor_default', 'custom']
- migration_bandwidth_limit:
- description:
- - "Set the I(custom) migration bandwidth limit."
- - "This parameter is used only when C(migration_bandwidth) is I(custom)."
- migration_auto_converge:
- description:
- - "If I(True) auto-convergence is used during live migration of virtual machines."
- - "Used only when C(migration_policy) is set to I(legacy)."
- - "Following options are supported:"
- - "C(true) - Override the global setting to I(true)."
- - "C(false) - Override the global setting to I(false)."
- - "C(inherit) - Use value which is set globally."
- choices: ['true', 'false', 'inherit']
- migration_compressed:
- description:
- - "If I(True) compression is used during live migration of the virtual machine."
- - "Used only when C(migration_policy) is set to I(legacy)."
- - "Following options are supported:"
- - "C(true) - Override the global setting to I(true)."
- - "C(false) - Override the global setting to I(false)."
- - "C(inherit) - Use value which is set globally."
- choices: ['true', 'false', 'inherit']
- migration_policy:
- description:
- - "A migration policy defines the conditions for live migrating
- virtual machines in the event of host failure."
- - "Following policies are supported:"
- - "C(legacy) - Legacy behavior of 3.6 version."
- - "C(minimal_downtime) - Virtual machines should not experience any significant downtime."
- - "C(suspend_workload) - Virtual machines may experience a more significant downtime."
- - "C(post_copy) - Virtual machines should not experience any significant downtime.
- If the VM migration is not converging for a long time, the migration will be switched to post-copy.
- Added in version I(2.4)."
- choices: ['legacy', 'minimal_downtime', 'suspend_workload', 'post_copy']
- serial_policy:
- description:
- - "Specify a serial number policy for the virtual machines in the cluster."
- - "Following options are supported:"
- - "C(vm) - Sets the virtual machine's UUID as its serial number."
- - "C(host) - Sets the host's UUID as the virtual machine's serial number."
- - "C(custom) - Allows you to specify a custom serial number in C(serial_policy_value)."
- serial_policy_value:
- description:
- - "Allows you to specify a custom serial number."
- - "This parameter is used only when C(serial_policy) is I(custom)."
- scheduling_policy:
- description:
- - "Name of the scheduling policy to be used for cluster."
- scheduling_policy_properties:
- description:
- - "Custom scheduling policy properties of the cluster."
- - "These optional properties override the properties of the
- scheduling policy specified by the C(scheduling_policy) parameter."
- version_added: "2.6"
- cpu_arch:
- description:
- - "CPU architecture of cluster."
- choices: ['x86_64', 'ppc64', 'undefined']
- cpu_type:
- description:
- - "CPU codename. For example I(Intel SandyBridge Family)."
- switch_type:
- description:
- - "Type of switch to be used by all networks in given cluster.
- Either I(legacy) which is using linux bridge or I(ovs) using
- Open vSwitch."
- choices: ['legacy', 'ovs']
- compatibility_version:
- description:
- - "The compatibility version of the cluster. All hosts in this
- cluster must support at least this compatibility version."
- mac_pool:
- description:
- - "MAC pool to be used by this cluster."
- - "C(Note:)"
- - "This is supported since oVirt version 4.1."
- version_added: 2.4
- external_network_providers:
- description:
- - "List of references to the external network providers available
- in the cluster. If the automatic deployment of the external
- network provider is supported, the networks of the referenced
- network provider are available on every host in the cluster."
- - "This is supported since oVirt version 4.2."
- suboptions:
- name:
- description:
- - Name of the external network provider. Either C(name) or C(id) is required.
- id:
- description:
- - ID of the external network provider. Either C(name) or C(id) is required.
- version_added: 2.5
- firewall_type:
- description:
- - "The type of firewall to be used on hosts in this cluster."
- - "Up to version 4.1, it was always I(iptables). Since version 4.2, you can choose between I(iptables) and I(firewalld).
- For clusters with a compatibility version of 4.2 and higher, the default firewall type is I(firewalld)."
- type: str
- version_added: 2.8
- choices: ['firewalld', 'iptables']
- gluster_tuned_profile:
- description:
- - "The name of the U(https://fedorahosted.org/tuned) to set on all the hosts in the cluster. This is not mandatory
- and relevant only for clusters with Gluster service."
- - "Could be for example I(virtual-host), I(rhgs-sequential-io), I(rhgs-random-io)"
- version_added: 2.8
- type: str
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create cluster
-- ovirt_cluster:
- data_center: mydatacenter
- name: mycluster
- cpu_type: Intel SandyBridge Family
- description: mycluster
- compatibility_version: 4.0
-
-# Create virt service cluster:
-- ovirt_cluster:
- data_center: mydatacenter
- name: mycluster
- cpu_type: Intel Nehalem Family
- description: mycluster
- switch_type: legacy
- compatibility_version: 4.0
- ballooning: true
- gluster: false
- threads_as_cores: true
- ha_reservation: true
- trusted_service: false
- host_reason: false
- vm_reason: true
- ksm_numa: true
- memory_policy: server
- rng_sources:
- - hwrng
- - random
-
-# Create cluster with default network provider
-- ovirt_cluster:
- name: mycluster
- data_center: Default
- cpu_type: Intel SandyBridge Family
- external_network_providers:
- - name: ovirt-provider-ovn
-
-# Remove cluster
-- ovirt_cluster:
- state: absent
- name: mycluster
-
-# Change cluster Name
-- ovirt_cluster:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_cluster_name"
-'''
-
-RETURN = '''
-id:
- description: ID of the cluster which is managed
- returned: On success if cluster is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-cluster:
- description: "Dictionary of all the cluster attributes. Cluster attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/cluster."
- type: dict
- returned: On success if cluster is found.
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- ovirt_full_argument_spec,
- search_by_name,
- get_id_by_name,
-)
-
-
-class ClustersModule(BaseModule):
-
- def __get_major(self, full_version):
- if full_version is None:
- return None
- if isinstance(full_version, otypes.Version):
- return full_version.major
- return int(full_version.split('.')[0])
-
- def __get_minor(self, full_version):
- if full_version is None:
- return None
- if isinstance(full_version, otypes.Version):
- return full_version.minor
- return int(full_version.split('.')[1])
-
- def param(self, name, default=None):
- return self._module.params.get(name, default)
-
- def _get_memory_policy(self):
- memory_policy = self.param('memory_policy')
- if memory_policy == 'desktop':
- return 200
- elif memory_policy == 'server':
- return 150
- elif memory_policy == 'disabled':
- return 100
-
- def _get_policy_id(self):
- # These are hardcoded IDs, once there is API, please fix this.
- # legacy - 00000000-0000-0000-0000-000000000000
- # minimal downtime - 80554327-0569-496b-bdeb-fcbbf52b827b
- # suspend workload if needed - 80554327-0569-496b-bdeb-fcbbf52b827c
- # post copy - a7aeedb2-8d66-4e51-bb22-32595027ce71
- migration_policy = self.param('migration_policy')
- if migration_policy == 'legacy':
- return '00000000-0000-0000-0000-000000000000'
- elif migration_policy == 'minimal_downtime':
- return '80554327-0569-496b-bdeb-fcbbf52b827b'
- elif migration_policy == 'suspend_workload':
- return '80554327-0569-496b-bdeb-fcbbf52b827c'
- elif migration_policy == 'post_copy':
- return 'a7aeedb2-8d66-4e51-bb22-32595027ce71'
-
- def _get_sched_policy(self):
- sched_policy = None
- if self.param('scheduling_policy'):
- sched_policies_service = self._connection.system_service().scheduling_policies_service()
- sched_policy = search_by_name(sched_policies_service, self.param('scheduling_policy'))
- if not sched_policy:
- raise Exception("Scheduling policy '%s' was not found" % self.param('scheduling_policy'))
-
- return sched_policy
-
- def _get_mac_pool(self):
- mac_pool = None
- if self._module.params.get('mac_pool'):
- mac_pool = search_by_name(
- self._connection.system_service().mac_pools_service(),
- self._module.params.get('mac_pool'),
- )
-
- return mac_pool
-
- def _get_external_network_providers(self):
- return self.param('external_network_providers') or []
-
- def _get_external_network_provider_id(self, external_provider):
- return external_provider.get('id') or get_id_by_name(
- self._connection.system_service().openstack_network_providers_service(),
- external_provider.get('name')
- )
-
- def _get_external_network_providers_entity(self):
- if self.param('external_network_providers') is not None:
- return [otypes.ExternalProvider(id=self._get_external_network_provider_id(external_provider))
- for external_provider in self.param('external_network_providers')]
-
- def build_entity(self):
- sched_policy = self._get_sched_policy()
- return otypes.Cluster(
- id=self.param('id'),
- name=self.param('name'),
- comment=self.param('comment'),
- description=self.param('description'),
- ballooning_enabled=self.param('ballooning'),
- gluster_service=self.param('gluster'),
- virt_service=self.param('virt'),
- threads_as_cores=self.param('threads_as_cores'),
- ha_reservation=self.param('ha_reservation'),
- trusted_service=self.param('trusted_service'),
- optional_reason=self.param('vm_reason'),
- maintenance_reason_required=self.param('host_reason'),
- scheduling_policy=otypes.SchedulingPolicy(
- id=sched_policy.id,
- ) if sched_policy else None,
- serial_number=otypes.SerialNumber(
- policy=otypes.SerialNumberPolicy(self.param('serial_policy')),
- value=self.param('serial_policy_value'),
- ) if (
- self.param('serial_policy') is not None or
- self.param('serial_policy_value') is not None
- ) else None,
- migration=otypes.MigrationOptions(
- auto_converge=otypes.InheritableBoolean(
- self.param('migration_auto_converge'),
- ) if self.param('migration_auto_converge') else None,
- bandwidth=otypes.MigrationBandwidth(
- assignment_method=otypes.MigrationBandwidthAssignmentMethod(
- self.param('migration_bandwidth'),
- ) if self.param('migration_bandwidth') else None,
- custom_value=self.param('migration_bandwidth_limit'),
- ) if (
- self.param('migration_bandwidth') or
- self.param('migration_bandwidth_limit')
- ) else None,
- compressed=otypes.InheritableBoolean(
- self.param('migration_compressed'),
- ) if self.param('migration_compressed') else None,
- policy=otypes.MigrationPolicy(
- id=self._get_policy_id()
- ) if self.param('migration_policy') else None,
- ) if (
- self.param('migration_bandwidth') is not None or
- self.param('migration_bandwidth_limit') is not None or
- self.param('migration_auto_converge') is not None or
- self.param('migration_compressed') is not None or
- self.param('migration_policy') is not None
- ) else None,
- error_handling=otypes.ErrorHandling(
- on_error=otypes.MigrateOnError(
- self.param('resilience_policy')
- ),
- ) if self.param('resilience_policy') else None,
- fencing_policy=otypes.FencingPolicy(
- enabled=self.param('fence_enabled'),
- skip_if_gluster_bricks_up=self.param('fence_skip_if_gluster_bricks_up'),
- skip_if_gluster_quorum_not_met=self.param('fence_skip_if_gluster_quorum_not_met'),
- skip_if_connectivity_broken=otypes.SkipIfConnectivityBroken(
- enabled=self.param('fence_skip_if_connectivity_broken'),
- threshold=self.param('fence_connectivity_threshold'),
- ) if (
- self.param('fence_skip_if_connectivity_broken') is not None or
- self.param('fence_connectivity_threshold') is not None
- ) else None,
- skip_if_sd_active=otypes.SkipIfSdActive(
- enabled=self.param('fence_skip_if_sd_active'),
- ) if self.param('fence_skip_if_sd_active') is not None else None,
- ) if (
- self.param('fence_enabled') is not None or
- self.param('fence_skip_if_sd_active') is not None or
- self.param('fence_skip_if_connectivity_broken') is not None or
- self.param('fence_skip_if_gluster_bricks_up') is not None or
- self.param('fence_skip_if_gluster_quorum_not_met') is not None or
- self.param('fence_connectivity_threshold') is not None
- ) else None,
- display=otypes.Display(
- proxy=self.param('spice_proxy'),
- ) if self.param('spice_proxy') else None,
- required_rng_sources=[
- otypes.RngSource(rng) for rng in self.param('rng_sources')
- ] if self.param('rng_sources') else None,
- memory_policy=otypes.MemoryPolicy(
- over_commit=otypes.MemoryOverCommit(
- percent=self._get_memory_policy(),
- ),
- ) if self.param('memory_policy') else None,
- ksm=otypes.Ksm(
- enabled=self.param('ksm'),
- merge_across_nodes=not self.param('ksm_numa'),
- ) if (
- self.param('ksm_numa') is not None or
- self.param('ksm') is not None
- ) else None,
- data_center=otypes.DataCenter(
- name=self.param('data_center'),
- ) if self.param('data_center') else None,
- management_network=otypes.Network(
- name=self.param('network'),
- ) if self.param('network') else None,
- cpu=otypes.Cpu(
- architecture=otypes.Architecture(
- self.param('cpu_arch')
- ) if self.param('cpu_arch') else None,
- type=self.param('cpu_type'),
- ) if (
- self.param('cpu_arch') or self.param('cpu_type')
- ) else None,
- version=otypes.Version(
- major=self.__get_major(self.param('compatibility_version')),
- minor=self.__get_minor(self.param('compatibility_version')),
- ) if self.param('compatibility_version') else None,
- switch_type=otypes.SwitchType(
- self.param('switch_type')
- ) if self.param('switch_type') else None,
- mac_pool=otypes.MacPool(
- id=get_id_by_name(self._connection.system_service().mac_pools_service(), self.param('mac_pool'))
- ) if self.param('mac_pool') else None,
- external_network_providers=self._get_external_network_providers_entity(),
- custom_scheduling_policy_properties=[
- otypes.Property(
- name=sp.get('name'),
- value=str(sp.get('value')),
- ) for sp in self.param('scheduling_policy_properties') if sp
- ] if self.param('scheduling_policy_properties') is not None else None,
- firewall_type=otypes.FirewallType(
- self.param('firewall_type')
- ) if self.param('firewall_type') else None,
- gluster_tuned_profile=self.param('gluster_tuned_profile'),
- )
-
- def _matches_entity(self, item, entity):
- return equal(item.get('id'), entity.id) and equal(item.get('name'), entity.name)
-
- def _update_check_external_network_providers(self, entity):
- if self.param('external_network_providers') is None:
- return True
- if entity.external_network_providers is None:
- return not self.param('external_network_providers')
- entity_providers = self._connection.follow_link(entity.external_network_providers)
- entity_provider_ids = [provider.id for provider in entity_providers]
- entity_provider_names = [provider.name for provider in entity_providers]
- for provider in self._get_external_network_providers():
- if provider.get('id'):
- if provider.get('id') not in entity_provider_ids:
- return False
- elif provider.get('name') and provider.get('name') not in entity_provider_names:
- return False
- for entity_provider in entity_providers:
- if not any([self._matches_entity(provider, entity_provider)
- for provider in self._get_external_network_providers()]):
- return False
- return True
-
- def update_check(self, entity):
- sched_policy = self._get_sched_policy()
- migration_policy = getattr(entity.migration, 'policy', None)
- cluster_cpu = getattr(entity, 'cpu', dict())
-
- def check_custom_scheduling_policy_properties():
- if self.param('scheduling_policy_properties'):
- current = []
- if entity.custom_scheduling_policy_properties:
- current = [(sp.name, str(sp.value)) for sp in entity.custom_scheduling_policy_properties]
- passed = [(sp.get('name'), str(sp.get('value'))) for sp in self.param('scheduling_policy_properties') if sp]
- for p in passed:
- if p not in current:
- return False
- return True
-
- return (
- check_custom_scheduling_policy_properties() and
- equal(self.param('name'), entity.name) and
- equal(self.param('comment'), entity.comment) and
- equal(self.param('description'), entity.description) and
- equal(self.param('switch_type'), str(entity.switch_type)) and
- equal(self.param('cpu_arch'), str(getattr(cluster_cpu, 'architecture', None))) and
- equal(self.param('cpu_type'), getattr(cluster_cpu, 'type', None)) and
- equal(self.param('ballooning'), entity.ballooning_enabled) and
- equal(self.param('gluster'), entity.gluster_service) and
- equal(self.param('virt'), entity.virt_service) and
- equal(self.param('threads_as_cores'), entity.threads_as_cores) and
- equal(self.param('ksm_numa'), not entity.ksm.merge_across_nodes) and
- equal(self.param('ksm'), entity.ksm.enabled) and
- equal(self.param('ha_reservation'), entity.ha_reservation) and
- equal(self.param('trusted_service'), entity.trusted_service) and
- equal(self.param('host_reason'), entity.maintenance_reason_required) and
- equal(self.param('vm_reason'), entity.optional_reason) and
- equal(self.param('spice_proxy'), getattr(entity.display, 'proxy', None)) and
- equal(self.param('fence_enabled'), entity.fencing_policy.enabled) and
- equal(self.param('fence_skip_if_gluster_bricks_up'), entity.fencing_policy.skip_if_gluster_bricks_up) and
- equal(self.param('fence_skip_if_gluster_quorum_not_met'), entity.fencing_policy.skip_if_gluster_quorum_not_met) and
- equal(self.param('fence_skip_if_sd_active'), entity.fencing_policy.skip_if_sd_active.enabled) and
- equal(self.param('fence_skip_if_connectivity_broken'), entity.fencing_policy.skip_if_connectivity_broken.enabled) and
- equal(self.param('fence_connectivity_threshold'), entity.fencing_policy.skip_if_connectivity_broken.threshold) and
- equal(self.param('resilience_policy'), str(entity.error_handling.on_error)) and
- equal(self.param('migration_bandwidth'), str(entity.migration.bandwidth.assignment_method)) and
- equal(self.param('migration_auto_converge'), str(entity.migration.auto_converge)) and
- equal(self.param('migration_compressed'), str(entity.migration.compressed)) and
- equal(self.param('serial_policy'), str(getattr(entity.serial_number, 'policy', None))) and
- equal(self.param('serial_policy_value'), getattr(entity.serial_number, 'value', None)) and
- equal(self.param('scheduling_policy'), getattr(self._connection.follow_link(entity.scheduling_policy), 'name', None)) and
- equal(self.param('firewall_type'), str(entity.firewall_type)) and
- equal(self.param('gluster_tuned_profile'), getattr(entity, 'gluster_tuned_profile', None)) and
- equal(self._get_policy_id(), getattr(migration_policy, 'id', None)) and
- equal(self._get_memory_policy(), entity.memory_policy.over_commit.percent) and
- equal(self.__get_minor(self.param('compatibility_version')), self.__get_minor(entity.version)) and
- equal(self.__get_major(self.param('compatibility_version')), self.__get_major(entity.version)) and
- equal(
- self.param('migration_bandwidth_limit') if self.param('migration_bandwidth') == 'custom' else None,
- entity.migration.bandwidth.custom_value
- ) and
- equal(
- sorted(self.param('rng_sources')) if self.param('rng_sources') else None,
- sorted([
- str(source) for source in entity.required_rng_sources
- ])
- ) and
- equal(
- get_id_by_name(self._connection.system_service().mac_pools_service(), self.param('mac_pool'), raise_error=False),
- entity.mac_pool.id
- ) and
- self._update_check_external_network_providers(entity)
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(default=None, required=True),
- id=dict(default=None),
- ballooning=dict(default=None, type='bool', aliases=['balloon']),
- gluster=dict(default=None, type='bool'),
- virt=dict(default=None, type='bool'),
- threads_as_cores=dict(default=None, type='bool'),
- ksm_numa=dict(default=None, type='bool'),
- ksm=dict(default=None, type='bool'),
- ha_reservation=dict(default=None, type='bool'),
- trusted_service=dict(default=None, type='bool'),
- vm_reason=dict(default=None, type='bool'),
- host_reason=dict(default=None, type='bool'),
- memory_policy=dict(default=None, choices=['disabled', 'server', 'desktop'], aliases=['performance_preset']),
- rng_sources=dict(default=None, type='list'),
- spice_proxy=dict(default=None),
- fence_enabled=dict(default=None, type='bool'),
- fence_skip_if_gluster_bricks_up=dict(default=None, type='bool'),
- fence_skip_if_gluster_quorum_not_met=dict(default=None, type='bool'),
- fence_skip_if_sd_active=dict(default=None, type='bool'),
- fence_skip_if_connectivity_broken=dict(default=None, type='bool'),
- fence_connectivity_threshold=dict(default=None, type='int'),
- resilience_policy=dict(default=None, choices=['migrate_highly_available', 'migrate', 'do_not_migrate']),
- migration_bandwidth=dict(default=None, choices=['auto', 'hypervisor_default', 'custom']),
- migration_bandwidth_limit=dict(default=None, type='int'),
- migration_auto_converge=dict(default=None, choices=['true', 'false', 'inherit']),
- migration_compressed=dict(default=None, choices=['true', 'false', 'inherit']),
- migration_policy=dict(
- default=None,
- choices=['legacy', 'minimal_downtime', 'suspend_workload', 'post_copy']
- ),
- serial_policy=dict(default=None, choices=['vm', 'host', 'custom']),
- serial_policy_value=dict(default=None),
- scheduling_policy=dict(default=None),
- data_center=dict(default=None),
- description=dict(default=None),
- comment=dict(default=None),
- network=dict(default=None),
- cpu_arch=dict(default=None, choices=['ppc64', 'undefined', 'x86_64']),
- cpu_type=dict(default=None),
- switch_type=dict(default=None, choices=['legacy', 'ovs']),
- compatibility_version=dict(default=None),
- mac_pool=dict(default=None),
- external_network_providers=dict(default=None, type='list'),
- scheduling_policy_properties=dict(type='list'),
- firewall_type=dict(choices=['iptables', 'firewalld'], default=None),
- gluster_tuned_profile=dict(default=None),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- clusters_service = connection.system_service().clusters_service()
- clusters_module = ClustersModule(
- connection=connection,
- module=module,
- service=clusters_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = clusters_module.create()
- elif state == 'absent':
- ret = clusters_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py
deleted file mode 100644
index 646c05efd9..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_cluster_info
-short_description: Retrieve information about one or more oVirt/RHV clusters
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV clusters."
- - This module was called C(ovirt_cluster_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_cluster_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_clusters), which
- contains a list of clusters. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search cluster X from datacenter Y use following pattern:
- name=X and datacenter=Y"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all clusters which names start with C<production>:
-- ovirt_cluster_info:
- pattern:
- name: 'production*'
- register: result
-- debug:
- msg: "{{ result.ovirt_clusters }}"
-'''
-
-RETURN = '''
-ovirt_clusters:
- description: "List of dictionaries describing the clusters. Cluster attributes are mapped to dictionary keys,
- all clusters attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/cluster."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_cluster_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_cluster_facts' module has been renamed to 'ovirt_cluster_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- clusters_service = connection.system_service().clusters_service()
- clusters = clusters_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_clusters=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in clusters
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py b/lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py
deleted file mode 100644
index d86d5f485a..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_datacenter
-short_description: Module to manage data centers in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage data centers in oVirt/RHV"
-options:
- id:
- description:
- - "ID of the datacenter to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the data center to manage."
- required: true
- state:
- description:
- - "Should the data center be present or absent."
- choices: ['present', 'absent']
- default: present
- description:
- description:
- - "Description of the data center."
- comment:
- description:
- - "Comment of the data center."
- local:
- description:
- - "I(True) if the data center should be local, I(False) if should be shared."
- - "Default value is set by engine."
- type: bool
- compatibility_version:
- description:
- - "Compatibility version of the data center."
- quota_mode:
- description:
- - "Quota mode of the data center. One of I(disabled), I(audit) or I(enabled)"
- choices: ['disabled', 'audit', 'enabled']
- mac_pool:
- description:
- - "MAC pool to be used by this datacenter."
- - "IMPORTANT: This option is deprecated in oVirt/RHV 4.1. You should
- use C(mac_pool) in C(ovirt_clusters) module, as MAC pools are
- set per cluster since 4.1."
- force:
- description:
- - "This parameter can be used only when removing a data center.
- If I(True) data center will be forcibly removed, even though it
- contains some clusters. Default value is I(False), which means
- that only empty data center can be removed."
- version_added: "2.5"
- default: False
- type: bool
-
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create datacenter
-- ovirt_datacenter:
- name: mydatacenter
- local: True
- compatibility_version: 4.0
- quota_mode: enabled
-
-# Remove datacenter
-- ovirt_datacenter:
- state: absent
- name: mydatacenter
-
-# Change Datacenter Name
-- ovirt_datacenter:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_datacenter_name"
-'''
-
-RETURN = '''
-id:
- description: "ID of the managed datacenter"
- returned: "On success if datacenter is found."
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-data_center:
- description: "Dictionary of all the datacenter attributes. Datacenter attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/datacenter."
- returned: "On success if datacenter is found."
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_params,
- create_connection,
- equal,
- ovirt_full_argument_spec,
- search_by_name,
-)
-
-
-class DatacentersModule(BaseModule):
-
- def __get_major(self, full_version):
- if full_version is None:
- return None
- if isinstance(full_version, otypes.Version):
- return full_version.major
- return int(full_version.split('.')[0])
-
- def __get_minor(self, full_version):
- if full_version is None:
- return None
- if isinstance(full_version, otypes.Version):
- return full_version.minor
- return int(full_version.split('.')[1])
-
- def _get_mac_pool(self):
- mac_pool = None
- if self._module.params.get('mac_pool'):
- mac_pool = search_by_name(
- self._connection.system_service().mac_pools_service(),
- self._module.params.get('mac_pool'),
- )
-
- return mac_pool
-
- def build_entity(self):
- return otypes.DataCenter(
- name=self._module.params['name'],
- id=self._module.params['id'],
- comment=self._module.params['comment'],
- description=self._module.params['description'],
- mac_pool=otypes.MacPool(
- id=getattr(self._get_mac_pool(), 'id', None),
- ) if self._module.params.get('mac_pool') else None,
- quota_mode=otypes.QuotaModeType(
- self._module.params['quota_mode']
- ) if self._module.params['quota_mode'] else None,
- local=self._module.params['local'],
- version=otypes.Version(
- major=self.__get_major(self._module.params['compatibility_version']),
- minor=self.__get_minor(self._module.params['compatibility_version']),
- ) if self._module.params['compatibility_version'] else None,
- )
-
- def update_check(self, entity):
- minor = self.__get_minor(self._module.params.get('compatibility_version'))
- major = self.__get_major(self._module.params.get('compatibility_version'))
- return (
- equal(getattr(self._get_mac_pool(), 'id', None), getattr(entity.mac_pool, 'id', None)) and
- equal(self._module.params.get('comment'), entity.comment) and
- equal(self._module.params.get('description'), entity.description) and
- equal(self._module.params.get('name'), entity.name) and
- equal(self._module.params.get('quota_mode'), str(entity.quota_mode)) and
- equal(self._module.params.get('local'), entity.local) and
- equal(minor, self.__get_minor(entity.version)) and
- equal(major, self.__get_major(entity.version))
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(default=None, required=True),
- description=dict(default=None),
- local=dict(type='bool'),
- id=dict(default=None),
- compatibility_version=dict(default=None),
- quota_mode=dict(choices=['disabled', 'audit', 'enabled']),
- comment=dict(default=None),
- mac_pool=dict(default=None),
- force=dict(default=None, type='bool'),
- )
- 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)
- data_centers_service = connection.system_service().data_centers_service()
- data_centers_module = DatacentersModule(
- connection=connection,
- module=module,
- service=data_centers_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = data_centers_module.create()
- elif state == 'absent':
- ret = data_centers_module.remove(force=module.params['force'])
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py
deleted file mode 100644
index 9f17e82ed9..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_datacenter_info
-short_description: Retrieve information about one or more oVirt/RHV datacenters
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV datacenters."
- - This module was called C(ovirt_datacenter_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_datacenter_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_datacenters), which
- contains a list of datacenters. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search datacenter I(X) use following pattern: I(name=X)"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all data centers which names start with C(production):
-- ovirt_datacenter_info:
- pattern: name=production*
- register: result
-- debug:
- msg: "{{ result.ovirt_datacenters }}"
-'''
-
-RETURN = '''
-ovirt_datacenters:
- description: "List of dictionaries describing the datacenters. Datacenter attributes are mapped to dictionary keys,
- all datacenters attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/data_center."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_datacenter_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_datacenter_facts' module has been renamed to 'ovirt_datacenter_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- datacenters_service = connection.system_service().data_centers_service()
- datacenters = datacenters_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_datacenters=[
- get_dict_of_struct(
- struct=d,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for d in datacenters
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_disk.py b/lib/ansible/modules/cloud/ovirt/ovirt_disk.py
deleted file mode 100644
index 6e6b0893be..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_disk.py
+++ /dev/null
@@ -1,838 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_disk
-short_description: "Module to manage Virtual Machine and floating disks in oVirt/RHV"
-version_added: "2.2"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage Virtual Machine and floating disks in oVirt/RHV."
-options:
- id:
- description:
- - "ID of the disk to manage. Either C(id) or C(name) is required."
- name:
- description:
- - "Name of the disk to manage. Either C(id) or C(name)/C(alias) is required."
- aliases: ['alias']
- description:
- description:
- - "Description of the disk image to manage."
- version_added: "2.5"
- vm_name:
- description:
- - "Name of the Virtual Machine to manage. Either C(vm_id) or C(vm_name) is required if C(state) is I(attached) or I(detached)."
- vm_id:
- description:
- - "ID of the Virtual Machine to manage. Either C(vm_id) or C(vm_name) is required if C(state) is I(attached) or I(detached)."
- state:
- description:
- - "Should the Virtual Machine disk be present/absent/attached/detached/exported/imported."
- choices: ['present', 'absent', 'attached', 'detached', 'exported', 'imported']
- default: 'present'
- download_image_path:
- description:
- - "Path on a file system where disk should be downloaded."
- - "Note that you must have an valid oVirt/RHV engine CA in your system trust store
- or you must provide it in C(ca_file) parameter."
- - "Note that the disk is not downloaded when the file already exists,
- but you can forcibly download the disk when using C(force) I (true)."
- version_added: "2.3"
- upload_image_path:
- description:
- - "Path to disk image, which should be uploaded."
- - "Note that currently we support only compatibility version 0.10 of the qcow disk."
- - "Note that you must have an valid oVirt/RHV engine CA in your system trust store
- or you must provide it in C(ca_file) parameter."
- - "Note that there is no reliable way to achieve idempotency, so
- if you want to upload the disk even if the disk with C(id) or C(name) exists,
- then please use C(force) I(true). If you will use C(force) I(false), which
- is default, then the disk image won't be uploaded."
- version_added: "2.3"
- size:
- description:
- - "Size of the disk. Size should be specified using IEC standard units.
- For example 10GiB, 1024MiB, etc."
- - "Size can be only increased, not decreased."
- interface:
- description:
- - "Driver of the storage interface."
- - "It's required parameter when creating the new disk."
- choices: ['virtio', 'ide', 'virtio_scsi']
- format:
- description:
- - Specify format of the disk.
- - Note that this option isn't idempotent as it's not currently possible to change format of the disk via API.
- choices: ['raw', 'cow']
- content_type:
- description:
- - Specify if the disk is a data disk or ISO image or a one of a the Hosted Engine disk types
- - The Hosted Engine disk content types are available with Engine 4.3+ and Ansible 2.8
- choices: ['data', 'iso', 'hosted_engine', 'hosted_engine_sanlock', 'hosted_engine_metadata', 'hosted_engine_configuration']
- default: 'data'
- version_added: "2.8"
- sparse:
- required: False
- type: bool
- version_added: "2.5"
- description:
- - "I(True) if the disk should be sparse (also known as I(thin provision)).
- If the parameter is omitted, cow disks will be created as sparse and raw disks as I(preallocated)"
- - Note that this option isn't idempotent as it's not currently possible to change sparseness of the disk via API.
- storage_domain:
- description:
- - "Storage domain name where disk should be created."
- storage_domains:
- description:
- - "Storage domain names where disk should be copied."
- - "C(**IMPORTANT**)"
- - "There is no reliable way to achieve idempotency, so every time
- you specify this parameter the disks are copied, so please handle
- your playbook accordingly to not copy the disks all the time. This
- is valid only for VM and floating disks, template disks works
- as expected."
- version_added: "2.3"
- force:
- description:
- - "Please take a look at C(image_path) documentation to see the correct
- usage of this parameter."
- version_added: "2.3"
- type: bool
- profile:
- description:
- - "Disk profile name to be attached to disk. By default profile is chosen by oVirt/RHV engine."
- quota_id:
- description:
- - "Disk quota ID to be used for disk. By default quota is chosen by oVirt/RHV engine."
- version_added: "2.5"
- bootable:
- description:
- - "I(True) if the disk should be bootable. By default when disk is created it isn't bootable."
- type: bool
- default: 'no'
- shareable:
- description:
- - "I(True) if the disk should be shareable. By default when disk is created it isn't shareable."
- type: bool
- logical_unit:
- description:
- - "Dictionary which describes LUN to be directly attached to VM:"
- suboptions:
- address:
- description:
- - Address of the storage server. Used by iSCSI.
- port:
- description:
- - Port of the storage server. Used by iSCSI.
- target:
- description:
- - iSCSI target.
- lun_id:
- description:
- - LUN id.
- username:
- description:
- - CHAP Username to be used to access storage server. Used by iSCSI.
- password:
- description:
- - CHAP Password of the user to be used to access storage server. Used by iSCSI.
- storage_type:
- description:
- - Storage type either I(fcp) or I(iscsi).
- sparsify:
- description:
- - "I(True) if the disk should be sparsified."
- - "Sparsification frees space in the disk image that is not used by
- its filesystem. As a result, the image will occupy less space on
- the storage."
- - "Note that this parameter isn't idempotent, as it's not possible
- to check if the disk should be or should not be sparsified."
- version_added: "2.4"
- type: bool
- openstack_volume_type:
- description:
- - "Name of the openstack volume type. This is valid when working
- with cinder."
- version_added: "2.4"
- image_provider:
- description:
- - "When C(state) is I(exported) disk is exported to given Glance image provider."
- - "When C(state) is I(imported) disk is imported from given Glance image provider."
- - "C(**IMPORTANT**)"
- - "There is no reliable way to achieve idempotency, so every time
- you specify this parameter the disk is exported, so please handle
- your playbook accordingly to not export the disk all the time.
- This option is valid only for template disks."
- version_added: "2.4"
- host:
- description:
- - "When the hypervisor name is specified the newly created disk or
- an existing disk will refresh its information about the
- underlying storage( Disk size, Serial, Product ID, Vendor ID ...)
- The specified host will be used for gathering the storage
- related information. This option is only valid for passthrough
- disks. This option requires at least the logical_unit.id to be
- specified"
- version_added: "2.8"
- wipe_after_delete:
- description:
- - "If the disk's Wipe After Delete is enabled, then the disk is first wiped."
- type: bool
- activate:
- description:
- - I(True) if the disk should be activated.
- - When creating disk of virtual machine it is set to I(True).
- version_added: "2.8"
- type: bool
-extends_documentation_fragment: ovirt
-'''
-
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create and attach new disk to VM
-- ovirt_disk:
- name: myvm_disk
- vm_name: rhel7
- size: 10GiB
- format: cow
- interface: virtio
- storage_domain: data
-
-# Attach logical unit to VM rhel7
-- ovirt_disk:
- vm_name: rhel7
- logical_unit:
- target: iqn.2016-08-09.brq.str-01:omachace
- id: 1IET_000d0001
- address: 10.34.63.204
- interface: virtio
-
-# Detach disk from VM
-- ovirt_disk:
- state: detached
- name: myvm_disk
- vm_name: rhel7
- size: 10GiB
- format: cow
- interface: virtio
-
-# Change Disk Name
-- ovirt_disk:
- id: 00000000-0000-0000-0000-000000000000
- storage_domain: data
- name: "new_disk_name"
- vm_name: rhel7
-
-# Upload local image to disk and attach it to vm:
-# Since Ansible 2.3
-- ovirt_disk:
- name: mydisk
- vm_name: myvm
- interface: virtio
- size: 10GiB
- format: cow
- image_path: /path/to/mydisk.qcow2
- storage_domain: data
-
-# Download disk to local file system:
-# Since Ansible 2.3
-- ovirt_disk:
- id: 7de90f31-222c-436c-a1ca-7e655bd5b60c
- download_image_path: /home/user/mydisk.qcow2
-
-# Export disk as image to Glance domain
-# Since Ansible 2.4
-- ovirt_disk:
- id: 7de90f31-222c-436c-a1ca-7e655bd5b60c
- image_provider: myglance
- state: exported
-
-# Defining a specific quota while creating a disk image:
-# Since Ansible 2.5
-- ovirt_quotas_facts:
- data_center: Default
- name: myquota
-- ovirt_disk:
- name: mydisk
- size: 10GiB
- storage_domain: data
- description: somedescriptionhere
- quota_id: "{{ ovirt_quotas[0]['id'] }}"
-
-# Upload an ISO image
-# Since Ansible 2.8
-- ovirt_disk:
- name: myiso
- upload_image_path: /path/to/iso/image
- storage_domain: data
- size: 4 GiB
- wait: true
- bootable: true
- format: raw
- content_type: iso
-
-# Add fiber chanel disk
-- name: Create disk
- ovirt_disk:
- name: fcp_disk
- host: my_host
- logical_unit:
- id: 3600a09803830447a4f244c4657597777
- storage_type: fcp
-'''
-
-
-RETURN = '''
-id:
- description: "ID of the managed disk"
- returned: "On success if disk is found."
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-disk:
- description: "Dictionary of all the disk attributes. Disk attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/disk."
- returned: "On success if disk is found and C(vm_id) or C(vm_name) wasn't passed."
- type: dict
-
-disk_attachment:
- description: "Dictionary of all the disk attachment attributes. Disk attachment attributes can be found
- on your oVirt/RHV instance at following url:
- http://ovirt.github.io/ovirt-engine-api-model/master/#types/disk_attachment."
- returned: "On success if disk is found and C(vm_id) or C(vm_name) was passed and VM was found."
- type: dict
-'''
-
-import os
-import time
-import traceback
-import ssl
-
-from ansible.module_utils.six.moves.http_client import HTTPSConnection, IncompleteRead
-from ansible.module_utils.six.moves.urllib.parse import urlparse
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_params,
- create_connection,
- convert_to_bytes,
- equal,
- follow_link,
- get_id_by_name,
- ovirt_full_argument_spec,
- get_dict_of_struct,
- search_by_name,
- wait,
-)
-
-
-def _search_by_lun(disks_service, lun_id):
- """
- Find disk by LUN ID.
- """
- res = [
- disk for disk in disks_service.list(search='disk_type=lun') if (
- disk.lun_storage.id == lun_id
- )
- ]
- return res[0] if res else None
-
-
-def transfer(connection, module, direction, transfer_func):
- transfers_service = connection.system_service().image_transfers_service()
- transfer = transfers_service.add(
- otypes.ImageTransfer(
- image=otypes.Image(
- id=module.params['id'],
- ),
- direction=direction,
- )
- )
- transfer_service = transfers_service.image_transfer_service(transfer.id)
-
- try:
- # After adding a new transfer for the disk, the transfer's status will be INITIALIZING.
- # Wait until the init phase is over. The actual transfer can start when its status is "Transferring".
- while transfer.phase == otypes.ImageTransferPhase.INITIALIZING:
- time.sleep(module.params['poll_interval'])
- transfer = transfer_service.get()
-
- proxy_url = urlparse(transfer.proxy_url)
- context = ssl.create_default_context()
- auth = module.params['auth']
- if auth.get('insecure'):
- context.check_hostname = False
- context.verify_mode = ssl.CERT_NONE
- elif auth.get('ca_file'):
- context.load_verify_locations(cafile=auth.get('ca_file'))
-
- proxy_connection = HTTPSConnection(
- proxy_url.hostname,
- proxy_url.port,
- context=context,
- )
-
- transfer_func(
- transfer_service,
- proxy_connection,
- proxy_url,
- transfer.signed_ticket
- )
- return True
- finally:
- transfer_service.finalize()
- while transfer.phase in [
- otypes.ImageTransferPhase.TRANSFERRING,
- otypes.ImageTransferPhase.FINALIZING_SUCCESS,
- ]:
- time.sleep(module.params['poll_interval'])
- transfer = transfer_service.get()
- if transfer.phase in [
- otypes.ImageTransferPhase.UNKNOWN,
- otypes.ImageTransferPhase.FINISHED_FAILURE,
- otypes.ImageTransferPhase.FINALIZING_FAILURE,
- otypes.ImageTransferPhase.CANCELLED,
- ]:
- raise Exception(
- "Error occurred while uploading image. The transfer is in %s" % transfer.phase
- )
- if not module.params.get('logical_unit'):
- disks_service = connection.system_service().disks_service()
- wait(
- service=disks_service.service(module.params['id']),
- condition=lambda d: d.status == otypes.DiskStatus.OK,
- wait=module.params['wait'],
- timeout=module.params['timeout'],
- )
-
-
-def download_disk_image(connection, module):
- def _transfer(transfer_service, proxy_connection, proxy_url, transfer_ticket):
- BUF_SIZE = 128 * 1024
- transfer_headers = {
- 'Authorization': transfer_ticket,
- }
- proxy_connection.request(
- 'GET',
- proxy_url.path,
- headers=transfer_headers,
- )
- r = proxy_connection.getresponse()
- path = module.params["download_image_path"]
- image_size = int(r.getheader('Content-Length'))
- with open(path, "wb") as mydisk:
- pos = 0
- while pos < image_size:
- to_read = min(image_size - pos, BUF_SIZE)
- chunk = r.read(to_read)
- if not chunk:
- raise RuntimeError("Socket disconnected")
- mydisk.write(chunk)
- pos += len(chunk)
-
- return transfer(
- connection,
- module,
- otypes.ImageTransferDirection.DOWNLOAD,
- transfer_func=_transfer,
- )
-
-
-def upload_disk_image(connection, module):
- def _transfer(transfer_service, proxy_connection, proxy_url, transfer_ticket):
- BUF_SIZE = 128 * 1024
- path = module.params['upload_image_path']
-
- image_size = os.path.getsize(path)
- proxy_connection.putrequest("PUT", proxy_url.path)
- proxy_connection.putheader('Content-Length', "%d" % (image_size,))
- proxy_connection.endheaders()
- with open(path, "rb") as disk:
- pos = 0
- while pos < image_size:
- to_read = min(image_size - pos, BUF_SIZE)
- chunk = disk.read(to_read)
- if not chunk:
- transfer_service.pause()
- raise RuntimeError("Unexpected end of file at pos=%d" % pos)
- proxy_connection.send(chunk)
- pos += len(chunk)
-
- return transfer(
- connection,
- module,
- otypes.ImageTransferDirection.UPLOAD,
- transfer_func=_transfer,
- )
-
-
-class DisksModule(BaseModule):
-
- def build_entity(self):
- hosts_service = self._connection.system_service().hosts_service()
- logical_unit = self._module.params.get('logical_unit')
- disk = otypes.Disk(
- id=self._module.params.get('id'),
- name=self._module.params.get('name'),
- description=self._module.params.get('description'),
- format=otypes.DiskFormat(
- self._module.params.get('format')
- ) if self._module.params.get('format') else None,
- content_type=otypes.DiskContentType(
- self._module.params.get('content_type')
- ) if self._module.params.get('content_type') else None,
- sparse=self._module.params.get(
- 'sparse'
- ) if self._module.params.get(
- 'sparse'
- ) is not None else self._module.params.get('format') != 'raw',
- openstack_volume_type=otypes.OpenStackVolumeType(
- name=self.param('openstack_volume_type')
- ) if self.param('openstack_volume_type') else None,
- provisioned_size=convert_to_bytes(
- self._module.params.get('size')
- ),
- storage_domains=[
- otypes.StorageDomain(
- name=self._module.params.get('storage_domain'),
- ),
- ],
- quota=otypes.Quota(id=self._module.params.get('quota_id')) if self.param('quota_id') else None,
- shareable=self._module.params.get('shareable'),
- wipe_after_delete=self.param('wipe_after_delete'),
- lun_storage=otypes.HostStorage(
- host=otypes.Host(
- id=get_id_by_name(hosts_service, self._module.params.get('host'))
- ) if self.param('host') else None,
- type=otypes.StorageType(
- logical_unit.get('storage_type', 'iscsi')
- ),
- logical_units=[
- otypes.LogicalUnit(
- address=logical_unit.get('address'),
- port=logical_unit.get('port', 3260),
- target=logical_unit.get('target'),
- id=logical_unit.get('id'),
- username=logical_unit.get('username'),
- password=logical_unit.get('password'),
- )
- ],
- ) if logical_unit else None,
- )
- if hasattr(disk, 'initial_size') and self._module.params['upload_image_path']:
- disk.initial_size = convert_to_bytes(
- self._module.params.get('size')
- )
-
- return disk
-
- def update_storage_domains(self, disk_id):
- changed = False
- disk_service = self._service.service(disk_id)
- disk = disk_service.get()
- sds_service = self._connection.system_service().storage_domains_service()
-
- # We don't support move&copy for non file based storages:
- if disk.storage_type != otypes.DiskStorageType.IMAGE:
- return changed
-
- # Initiate move:
- if self._module.params['storage_domain']:
- new_disk_storage_id = get_id_by_name(sds_service, self._module.params['storage_domain'])
- changed = self.action(
- action='move',
- entity=disk,
- action_condition=lambda d: new_disk_storage_id != d.storage_domains[0].id,
- wait_condition=lambda d: d.status == otypes.DiskStatus.OK,
- storage_domain=otypes.StorageDomain(
- id=new_disk_storage_id,
- ),
- post_action=lambda _: time.sleep(self._module.params['poll_interval']),
- )['changed']
-
- if self._module.params['storage_domains']:
- for sd in self._module.params['storage_domains']:
- new_disk_storage = search_by_name(sds_service, sd)
- changed = changed or self.action(
- action='copy',
- entity=disk,
- action_condition=(
- lambda disk: new_disk_storage.id not in [sd.id for sd in disk.storage_domains]
- ),
- wait_condition=lambda disk: disk.status == otypes.DiskStatus.OK,
- storage_domain=otypes.StorageDomain(
- id=new_disk_storage.id,
- ),
- )['changed']
-
- return changed
-
- def _update_check(self, entity):
- return (
- equal(self._module.params.get('name'), entity.name) and
- equal(self._module.params.get('description'), entity.description) and
- equal(self.param('quota_id'), getattr(entity.quota, 'id', None)) and
- equal(convert_to_bytes(self._module.params.get('size')), entity.provisioned_size) and
- equal(self._module.params.get('shareable'), entity.shareable) and
- equal(self.param('wipe_after_delete'), entity.wipe_after_delete)
- )
-
-
-class DiskAttachmentsModule(DisksModule):
-
- def build_entity(self):
- return otypes.DiskAttachment(
- disk=super(DiskAttachmentsModule, self).build_entity(),
- interface=otypes.DiskInterface(
- self._module.params.get('interface')
- ) if self._module.params.get('interface') else None,
- bootable=self._module.params.get('bootable'),
- active=self.param('activate'),
- )
-
- def update_check(self, entity):
- return (
- super(DiskAttachmentsModule, self)._update_check(follow_link(self._connection, entity.disk)) and
- equal(self._module.params.get('interface'), str(entity.interface)) and
- equal(self._module.params.get('bootable'), entity.bootable) and
- equal(self.param('activate'), entity.active)
- )
-
-
-def searchable_attributes(module):
- """
- Return all searchable disk attributes passed to module.
- """
- attributes = {
- 'name': module.params.get('name'),
- 'Storage.name': module.params.get('storage_domain'),
- 'vm_names': module.params.get('vm_name'),
- }
- return dict((k, v) for k, v in attributes.items() if v is not None)
-
-
-def get_vm_service(connection, module):
- if module.params.get('vm_id') is not None or module.params.get('vm_name') is not None and module.params['state'] != 'absent':
- vms_service = connection.system_service().vms_service()
-
- # If `vm_id` isn't specified, find VM by name:
- vm_id = module.params['vm_id']
- if vm_id is None:
- vm_id = get_id_by_name(vms_service, module.params['vm_name'])
-
- if vm_id is None:
- module.fail_json(
- msg="VM don't exists, please create it first."
- )
-
- return vms_service.vm_service(vm_id)
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent', 'attached', 'detached', 'exported', 'imported'],
- default='present'
- ),
- id=dict(default=None),
- name=dict(default=None, aliases=['alias']),
- description=dict(default=None),
- vm_name=dict(default=None),
- vm_id=dict(default=None),
- size=dict(default=None),
- interface=dict(default=None,),
- storage_domain=dict(default=None),
- storage_domains=dict(default=None, type='list'),
- profile=dict(default=None),
- quota_id=dict(default=None),
- format=dict(default='cow', choices=['raw', 'cow']),
- content_type=dict(
- default='data',
- choices=['data', 'iso', 'hosted_engine', 'hosted_engine_sanlock', 'hosted_engine_metadata', 'hosted_engine_configuration']
- ),
- sparse=dict(default=None, type='bool'),
- bootable=dict(default=None, type='bool'),
- shareable=dict(default=None, type='bool'),
- logical_unit=dict(default=None, type='dict'),
- download_image_path=dict(default=None),
- upload_image_path=dict(default=None, aliases=['image_path']),
- force=dict(default=False, type='bool'),
- sparsify=dict(default=None, type='bool'),
- openstack_volume_type=dict(default=None),
- image_provider=dict(default=None),
- host=dict(default=None),
- wipe_after_delete=dict(type='bool', default=None),
- activate=dict(default=None, type='bool'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- lun = module.params.get('logical_unit')
- host = module.params['host']
- # Fail when host is specified with the LUN id. Lun id is needed to identify
- # an existing disk if already available inthe environment.
- if (host and lun is None) or (host and lun.get("id") is None):
- module.fail_json(
- msg="Can not use parameter host ({0!s}) without "
- "specifying the logical_unit id".format(host)
- )
-
- check_sdk(module)
- check_params(module)
-
- try:
- disk = None
- state = module.params['state']
- auth = module.params.get('auth')
- connection = create_connection(auth)
- disks_service = connection.system_service().disks_service()
- disks_module = DisksModule(
- connection=connection,
- module=module,
- service=disks_service,
- )
-
- force_create = False
- vm_service = get_vm_service(connection, module)
- if lun:
- disk = _search_by_lun(disks_service, lun.get('id'))
- else:
- disk = disks_module.search_entity(search_params=searchable_attributes(module))
- if vm_service and disk:
- # If the VM don't exist in VMs disks, but still it's found it means it was found
- # for template with same name as VM, so we should force create the VM disk.
- force_create = disk.id not in [a.disk.id for a in vm_service.disk_attachments_service().list() if a.disk]
-
- ret = None
- # First take care of creating the VM, if needed:
- if state in ('present', 'detached', 'attached'):
- # Always activate disk when its being created
- if vm_service is not None and disk is None:
- module.params['activate'] = True
- ret = disks_module.create(
- entity=disk if not force_create else None,
- result_state=otypes.DiskStatus.OK if lun is None else None,
- fail_condition=lambda d: d.status == otypes.DiskStatus.ILLEGAL if lun is None else False,
- force_create=force_create,
- )
- is_new_disk = ret['changed']
- ret['changed'] = ret['changed'] or disks_module.update_storage_domains(ret['id'])
- # We need to pass ID to the module, so in case we want detach/attach disk
- # we have this ID specified to attach/detach method:
- module.params['id'] = ret['id']
-
- # Upload disk image in case it's new disk or force parameter is passed:
- if module.params['upload_image_path'] and (is_new_disk or module.params['force']):
- uploaded = upload_disk_image(connection, module)
- ret['changed'] = ret['changed'] or uploaded
- # Download disk image in case it's file don't exist or force parameter is passed:
- if (
- module.params['download_image_path'] and (not os.path.isfile(module.params['download_image_path']) or module.params['force'])
- ):
- downloaded = download_disk_image(connection, module)
- ret['changed'] = ret['changed'] or downloaded
-
- # Disk sparsify, only if disk is of image type:
- if not module.check_mode:
- disk = disks_service.disk_service(module.params['id']).get()
- if disk.storage_type == otypes.DiskStorageType.IMAGE:
- ret = disks_module.action(
- action='sparsify',
- action_condition=lambda d: module.params['sparsify'],
- wait_condition=lambda d: d.status == otypes.DiskStatus.OK,
- )
-
- # Export disk as image to glance domain
- elif state == 'exported':
- disk = disks_module.search_entity()
- if disk is None:
- module.fail_json(
- msg="Can not export given disk '%s', it doesn't exist" %
- module.params.get('name') or module.params.get('id')
- )
- if disk.storage_type == otypes.DiskStorageType.IMAGE:
- ret = disks_module.action(
- action='export',
- action_condition=lambda d: module.params['image_provider'],
- wait_condition=lambda d: d.status == otypes.DiskStatus.OK,
- storage_domain=otypes.StorageDomain(name=module.params['image_provider']),
- )
- elif state == 'imported':
- glance_service = connection.system_service().openstack_image_providers_service()
- image_provider = search_by_name(glance_service, module.params['image_provider'])
- images_service = glance_service.service(image_provider.id).images_service()
- entity_id = get_id_by_name(images_service, module.params['name'])
- images_service.service(entity_id).import_(
- storage_domain=otypes.StorageDomain(
- name=module.params['storage_domain']
- ) if module.params['storage_domain'] else None,
- disk=otypes.Disk(
- name=module.params['name']
- ),
- import_as_template=False,
- )
- # Wait for disk to appear in system:
- disk = disks_module.wait_for_import(
- condition=lambda t: t.status == otypes.DiskStatus.OK
- )
- ret = disks_module.create(result_state=otypes.DiskStatus.OK)
- elif state == 'absent':
- ret = disks_module.remove()
-
- # If VM was passed attach/detach disks to/from the VM:
- if vm_service:
- disk_attachments_service = vm_service.disk_attachments_service()
- disk_attachments_module = DiskAttachmentsModule(
- connection=connection,
- module=module,
- service=disk_attachments_service,
- changed=ret['changed'] if ret else False,
- )
-
- if state == 'present' or state == 'attached':
- ret = disk_attachments_module.create()
- if lun is None:
- wait(
- service=disk_attachments_service.service(ret['id']),
- condition=lambda d: follow_link(connection, d.disk).status == otypes.DiskStatus.OK,
- wait=module.params['wait'],
- timeout=module.params['timeout'],
- )
- elif state == 'detached':
- ret = disk_attachments_module.remove()
-
- # When the host parameter is specified and the disk is not being
- # removed, refresh the information about the LUN.
- if state != 'absent' and host:
- hosts_service = connection.system_service().hosts_service()
- host_id = get_id_by_name(hosts_service, host)
- disks_service.disk_service(disk.id).refresh_lun(otypes.Host(id=host_id))
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py
deleted file mode 100644
index af3d855160..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017 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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_disk_info
-short_description: Retrieve information about one or more oVirt/RHV disks
-author: "Katerina Koukiou (@KKoukiou)"
-version_added: "2.5"
-description:
- - "Retrieve information about one or more oVirt/RHV disks."
- - This module was called C(ovirt_disk_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_disk_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_disks), which
- contains a list of disks. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search Disk X from storage Y use following pattern:
- name=X and storage.name=Y"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all Disks which names start with C(centos)
-- ovirt_disk_info:
- pattern: name=centos*
- register: result
-- debug:
- msg: "{{ result.ovirt_disks }}"
-'''
-
-RETURN = '''
-ovirt_disks:
- description: "List of dictionaries describing the Disks. Disk attributes are mapped to dictionary keys,
- all Disks attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/disk."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_disk_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_disk_facts' module has been renamed to 'ovirt_disk_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- disks_service = connection.system_service().disks_service()
- disks = disks_service.list(
- search=module.params['pattern'],
- )
- result = dict(
- ovirt_disks=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in disks
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_event.py b/lib/ansible/modules/cloud/ovirt/ovirt_event.py
deleted file mode 100644
index ea158e0176..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_event.py
+++ /dev/null
@@ -1,249 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright: (c) 2019, Ansible Project
-# 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: ovirt_event
-short_description: Create or delete an event in oVirt/RHV
-author: "Chris Keller (@nasx)"
-version_added: "2.8"
-description:
- - "This module can be used to create or delete an event in oVirt/RHV."
-options:
- state:
- description:
- - "Should the event be present/absent."
- - "The C(wait) option must be set to false when state is absent."
- choices: ['present', 'absent']
- type: str
- default: present
-
- description:
- description:
- - "Message for the event."
- - "Required when state is present."
- type: str
-
- severity:
- description:
- - "Severity of the event."
- - "Required when state is present."
- choices: ['error', 'normal', 'warning']
- default: normal
- type: str
-
- origin:
- description:
- - "Originator of the event."
- - "Required when state is present."
- type: str
-
- custom_id:
- description:
- - "Custom ID for the event. This ID must be unique for each event."
- - "Required when state is present."
- type: int
-
- id:
- description:
- - "The event ID in the oVirt/RHV audit_log table. This ID is not the same as custom_id and is only used when state is absent."
- - "Required when state is absent."
- type: str
-
- cluster:
- description:
- - "The id of the cluster associated with this event."
- type: str
-
- data_center:
- description:
- - "The id of the data center associated with this event."
- type: str
-
- host:
- description:
- - "The id of the host associated with this event."
- type: str
-
- storage_domain:
- description:
- - "The id of the storage domain associated with this event."
- type: str
-
- template:
- description:
- - "The id of the template associated with this event."
- type: str
-
- user:
- description:
- - "The id of the user associated with this event."
- type: str
-
- vm:
- description:
- - "The id of the VM associated with this event."
- type: str
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain the auth parameter for simplicity,
-# look at the ovirt_auth module to see how to reuse authentication.
-
-- name: Create an event
- ovirt_event:
- state: present
- description: "The file system /home on host xyz is almost full!"
- origin: "mymonitor"
- custom_id: 123456789
- severity: warning
-
-- name: Create an event and link it to a specific object
- ovirt_event:
- state: present
- description: "The file system /home is almost full!"
- origin: "mymonitor"
- custom_id: 123456789
- severity: warning
- vm: "c79db183-46ef-44d1-95f9-1a368c516c19"
-
-- name: Remove an event
- ovirt_event:
- state: absent
- id: 123456789
- wait: false
-'''
-
-RETURN = '''
-id:
- description: "ID of the event that was created."
- returned: "On success."
- type: str
-event:
- description: "Dictionary of all the Event attributes. All event attributes can be found at the following url:
- http://ovirt.github.io/ovirt-engine-api-model/master/#types/event"
- returned: "On success."
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_params,
- create_connection,
- equal,
- get_dict_of_struct,
- ovirt_full_argument_spec,
-)
-
-
-class EventsModule(BaseModule):
-
- def build_entity(self):
- return otypes.Event(
- description=self._module.params['description'],
- severity=otypes.LogSeverity(self._module.params['severity']),
- origin=self._module.params['origin'],
- custom_id=self._module.params['custom_id'],
- id=self._module.params['id'],
- cluster=otypes.Cluster(
- id=self._module.params['cluster']
- ) if self._module.params['cluster'] is not None else None,
- data_center=otypes.DataCenter(
- id=self._module.params['data_center']
- ) if self._module.params['data_center'] is not None else None,
- host=otypes.Host(
- id=self._module.params['host']
- ) if self._module.params['host'] is not None else None,
- storage_domain=otypes.StorageDomain(
- id=self._module.params['storage_domain']
- ) if self._module.params['storage_domain'] is not None else None,
- template=otypes.Template(
- id=self._module.params['template']
- ) if self._module.params['template'] is not None else None,
- user=otypes.User(
- id=self._module.params['user']
- ) if self._module.params['user'] is not None else None,
- vm=otypes.Vm(
- id=self._module.params['vm']
- ) if self._module.params['vm'] is not None else None,
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- description=dict(default=None),
- severity=dict(
- choices=['error', 'normal', 'warning'],
- default='normal',
- ),
- origin=dict(default=None),
- custom_id=dict(default=None, type='int'),
- id=dict(default=None),
- cluster=dict(default=None),
- data_center=dict(default=None),
- host=dict(default=None),
- storage_domain=dict(default=None),
- template=dict(default=None),
- user=dict(default=None),
- vm=dict(default=None),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True
- )
-
- check_sdk(module)
-
- # Wait must be set to false if state == absent
-
- if module.params['state'] == 'absent' and module.params['wait'] is not False:
- module.fail_json(msg='When "state" is absent, "wait" must be set to false.')
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- events_service = connection.system_service().events_service()
- events_module = EventsModule(
- connection=connection,
- module=module,
- service=events_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = events_module.create()
- elif state == 'absent':
- ret = events_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_event_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_event_info.py
deleted file mode 100644
index 6e15fb31d9..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_event_info.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright: (c) 2019, Ansible Project
-# 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: ovirt_event_info
-short_description: This module can be used to retrieve information about one or more oVirt/RHV events
-author: "Chris Keller (@nasx)"
-version_added: "2.8"
-description:
- - "Retrieve information about one or more oVirt/RHV events."
- - This module was called C(ovirt_event_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_event_info) module no longer returns C(ansible_facts)!
-options:
- case_sensitive:
- description:
- - "Indicates if the search performed using the search parameter should be performed taking case
- into account. The default value is true, which means that case is taken into account. If you
- want to search ignoring case set it to false."
- required: false
- default: true
- type: bool
-
- from_:
- description:
- - "Indicates the event index after which events should be returned. The indexes of events are
- strictly increasing, so when this parameter is used only the events with greater indexes
- will be returned."
- required: false
- type: int
-
- max:
- description:
- - "Sets the maximum number of events to return. If not specified all the events are returned."
- required: false
- type: int
-
- search:
- description:
- - "Search term which is accepted by the oVirt/RHV API."
- - "For example to search for events of severity alert use the following pattern: severity=alert"
- required: false
- type: str
-
- headers:
- description:
- - "Additional HTTP headers."
- required: false
- type: str
-
- query:
- description:
- - "Additional URL query parameters."
- required: false
- type: str
-
- wait:
- description:
- - "If True wait for the response."
- required: false
- default: true
- type: bool
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain the auth parameter for simplicity,
-# look at the ovirt_auth module to see how to reuse authentication.
-
-- name: Return all events
- ovirt_event_info:
- register: result
-
-- name: Return the last 10 events
- ovirt_event_info:
- max: 10
- register: result
-
-- name: Return all events of type alert
- ovirt_event_info:
- search: "severity=alert"
- register: result
-- debug:
- msg: "{{ result.ovirt_events }}"
-'''
-
-RETURN = '''
-ovirt_events:
- description: "List of dictionaries describing the events. Event attributes are mapped to dictionary keys.
- All event attributes can be found at the following url:
- http://ovirt.github.io/ovirt-engine-api-model/master/#types/event"
- returned: On success."
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- case_sensitive=dict(default=True, type='bool', required=False),
- from_=dict(default=None, type='int', required=False),
- max=dict(default=None, type='int', required=False),
- search=dict(default='', required=False),
- headers=dict(default='', required=False),
- query=dict(default='', required=False),
- wait=dict(default=True, type='bool', required=False)
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_event_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_event_facts' module has been renamed to 'ovirt_event_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- events_service = connection.system_service().events_service()
- events = events_service.list(
- case_sensitive=module.params['case_sensitive'],
- from_=module.params['from_'],
- max=module.params['max'],
- search=module.params['search'],
- headers=module.params['headers'],
- query=module.params['query'],
- wait=module.params['wait']
- )
-
- result = dict(
- ovirt_events=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in events
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py b/lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py
deleted file mode 100644
index f36d5a4a9f..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py
+++ /dev/null
@@ -1,406 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_external_provider
-short_description: Module to manage external providers in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage external providers in oVirt/RHV"
-options:
- name:
- description:
- - "Name of the external provider to manage."
- state:
- description:
- - "Should the external be present or absent"
- - "When you are using absent for I(os_volume), you need to make
- sure that SD is not attached to the data center!"
- choices: ['present', 'absent']
- default: present
- description:
- description:
- - "Description of the external provider."
- type:
- description:
- - "Type of the external provider."
- choices: ['os_image', 'network', 'os_volume', 'foreman']
- url:
- description:
- - "URL where external provider is hosted."
- - "Applicable for those types: I(os_image), I(os_volume), I(network) and I(foreman)."
- username:
- description:
- - "Username to be used for login to external provider."
- - "Applicable for all types."
- password:
- description:
- - "Password of the user specified in C(username) parameter."
- - "Applicable for all types."
- tenant_name:
- description:
- - "Name of the tenant."
- - "Applicable for those types: I(os_image), I(os_volume) and I(network)."
- aliases: ['tenant']
- authentication_url:
- description:
- - "Keystone authentication URL of the openstack provider."
- - "Applicable for those types: I(os_image), I(os_volume) and I(network)."
- aliases: ['auth_url']
- data_center:
- description:
- - "Name of the data center where provider should be attached."
- - "Applicable for those type: I(os_volume)."
- read_only:
- description:
- - "Specify if the network should be read only."
- - "Applicable if C(type) is I(network)."
- type: bool
- network_type:
- description:
- - "Type of the external network provider either external (for example OVN) or neutron."
- - "Applicable if C(type) is I(network)."
- choices: ['external', 'neutron']
- default: ['external']
- authentication_keys:
- description:
- - "List of authentication keys. Each key is represented by dict
- like {'uuid': 'our-uuid', 'value': 'YourSecretValue=='}"
- - "When you will not pass these keys and there are already some
- of them defined in the system they will be removed."
- - "Applicable for I(os_volume)."
- default: []
- version_added: "2.6"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add image external provider:
-- ovirt_external_provider:
- name: image_provider
- type: os_image
- url: http://1.2.3.4:9292
- username: admin
- password: 123456
- tenant: admin
- auth_url: http://1.2.3.4:35357/v2.0
-
-# Add volume external provider:
-- ovirt_external_provider:
- name: image_provider
- type: os_volume
- url: http://1.2.3.4:9292
- username: admin
- password: 123456
- tenant: admin
- auth_url: http://1.2.3.4:5000/v2.0
- authentication_keys:
- -
- uuid: "1234567-a1234-12a3-a234-123abc45678"
- value: "ABCD00000000111111222333445w=="
-
-# Add foreman provider:
-- ovirt_external_provider:
- name: foreman_provider
- type: foreman
- url: https://foreman.example.com
- username: admin
- password: 123456
-
-# Add external network provider for OVN:
-- ovirt_external_provider:
- name: ovn_provider
- type: network
- network_type: external
- url: http://1.2.3.4:9696
-
-# Remove image external provider:
-- ovirt_external_provider:
- state: absent
- name: image_provider
- type: os_image
-'''
-
-RETURN = '''
-id:
- description: ID of the external provider which is managed
- returned: On success if external provider is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-external_host_provider:
- description: "Dictionary of all the external_host_provider attributes. External provider attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/external_host_provider."
- returned: "On success and if parameter 'type: foreman' is used."
- type: dict
-openstack_image_provider:
- description: "Dictionary of all the openstack_image_provider attributes. External provider attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/openstack_image_provider."
- returned: "On success and if parameter 'type: os_image' is used."
- type: dict
-openstack_volume_provider:
- description: "Dictionary of all the openstack_volume_provider attributes. External provider attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/openstack_volume_provider."
- returned: "On success and if parameter 'type: os_volume' is used."
- type: dict
-openstack_network_provider:
- description: "Dictionary of all the openstack_network_provider attributes. External provider attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/openstack_network_provider."
- returned: "On success and if parameter 'type: network' is used."
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_params,
- check_sdk,
- create_connection,
- equal,
- ovirt_full_argument_spec,
-)
-
-
-OS_VOLUME = 'os_volume'
-OS_IMAGE = 'os_image'
-NETWORK = 'network'
-FOREMAN = 'foreman'
-
-
-class ExternalProviderModule(BaseModule):
-
- non_provider_params = ['type', 'authentication_keys', 'data_center']
-
- def provider_type(self, provider_type):
- self._provider_type = provider_type
-
- def provider_module_params(self):
- provider_params = [
- (key, value) for key, value in self._module.params.items() if key
- not in self.non_provider_params
- ]
- provider_params.append(('data_center', self.get_data_center()))
- return provider_params
-
- def get_data_center(self):
- dc_name = self._module.params.get("data_center", None)
- if dc_name:
- system_service = self._connection.system_service()
- data_centers_service = system_service.data_centers_service()
- return data_centers_service.list(
- search='name=%s' % dc_name,
- )[0]
- return dc_name
-
- def build_entity(self):
- provider_type = self._provider_type(
- requires_authentication=self._module.params.get('username') is not None,
- )
- if self._module.params.pop('type') == NETWORK:
- setattr(
- provider_type,
- 'type',
- otypes.OpenStackNetworkProviderType(self._module.params.pop('network_type'))
- )
-
- for key, value in self.provider_module_params():
- if hasattr(provider_type, key):
- setattr(provider_type, key, value)
-
- return provider_type
-
- def update_check(self, entity):
- return (
- equal(self._module.params.get('description'), entity.description) and
- equal(self._module.params.get('url'), entity.url) and
- equal(self._module.params.get('authentication_url'), entity.authentication_url) and
- equal(self._module.params.get('tenant_name'), getattr(entity, 'tenant_name', None)) and
- equal(self._module.params.get('username'), entity.username)
- )
-
- def update_volume_provider_auth_keys(
- self, provider, providers_service, keys
- ):
- """
- Update auth keys for volume provider, if not exist add them or remove
- if they are not specified and there are already defined in the external
- volume provider.
-
- Args:
- provider (dict): Volume provider details.
- providers_service (openstack_volume_providers_service): Provider
- service.
- keys (list): Keys to be updated/added to volume provider, each key
- is represented as dict with keys: uuid, value.
- """
-
- provider_service = providers_service.provider_service(provider['id'])
- auth_keys_service = provider_service.authentication_keys_service()
- provider_keys = auth_keys_service.list()
- # removing keys which are not defined
- for key in [
- k.id for k in provider_keys if k.uuid not in [
- defined_key['uuid'] for defined_key in keys
- ]
- ]:
- self.changed = True
- if not self._module.check_mode:
- auth_keys_service.key_service(key).remove()
- if not (provider_keys or keys):
- # Nothing need to do when both are empty.
- return
- for key in keys:
- key_id_for_update = None
- for existing_key in provider_keys:
- if key['uuid'] == existing_key.uuid:
- key_id_for_update = existing_key.id
-
- auth_key_usage_type = (
- otypes.OpenstackVolumeAuthenticationKeyUsageType("ceph")
- )
- auth_key = otypes.OpenstackVolumeAuthenticationKey(
- usage_type=auth_key_usage_type,
- uuid=key['uuid'],
- value=key['value'],
- )
-
- if not key_id_for_update:
- self.changed = True
- if not self._module.check_mode:
- auth_keys_service.add(auth_key)
- else:
- # We cannot really distinguish here if it was really updated cause
- # we cannot take key value to check if it was changed or not. So
- # for sure we update here always.
- self.changed = True
- if not self._module.check_mode:
- auth_key_service = (
- auth_keys_service.key_service(key_id_for_update)
- )
- auth_key_service.update(auth_key)
-
-
-def _external_provider_service(provider_type, system_service):
- if provider_type == OS_IMAGE:
- return otypes.OpenStackImageProvider, system_service.openstack_image_providers_service()
- elif provider_type == NETWORK:
- return otypes.OpenStackNetworkProvider, system_service.openstack_network_providers_service()
- elif provider_type == OS_VOLUME:
- return otypes.OpenStackVolumeProvider, system_service.openstack_volume_providers_service()
- elif provider_type == FOREMAN:
- return otypes.ExternalHostProvider, system_service.external_host_providers_service()
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(default=None),
- description=dict(default=None),
- type=dict(
- default=None,
- required=True,
- choices=[
- OS_IMAGE, NETWORK, OS_VOLUME, FOREMAN,
- ],
- aliases=['provider'],
- ),
- url=dict(default=None),
- username=dict(default=None),
- password=dict(default=None, no_log=True),
- tenant_name=dict(default=None, aliases=['tenant']),
- authentication_url=dict(default=None, aliases=['auth_url']),
- data_center=dict(default=None),
- read_only=dict(default=None, type='bool'),
- network_type=dict(
- default='external',
- choices=['external', 'neutron'],
- ),
- authentication_keys=dict(
- default=[], aliases=['auth_keys'], type='list', no_log=True,
- ),
- )
- 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)
- provider_type_param = module.params.get('type')
- provider_type, external_providers_service = _external_provider_service(
- provider_type=provider_type_param,
- system_service=connection.system_service(),
- )
- external_providers_module = ExternalProviderModule(
- connection=connection,
- module=module,
- service=external_providers_service,
- )
- external_providers_module.provider_type(provider_type)
-
- state = module.params.pop('state')
- if state == 'absent':
- ret = external_providers_module.remove()
- elif state == 'present':
- ret = external_providers_module.create()
- openstack_volume_provider_id = ret.get('id')
- if (
- provider_type_param == OS_VOLUME and
- openstack_volume_provider_id
- ):
- external_providers_module.update_volume_provider_auth_keys(
- ret, external_providers_service,
- module.params.get('authentication_keys'),
- )
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py
deleted file mode 100644
index 4a23f17e69..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_external_provider_info
-short_description: Retrieve information about one or more oVirt/RHV external providers
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV external providers."
- - This module was called C(ovirt_external_provider_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_external_provider_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_external_providers), which
- contains a list of external_providers. You need to register the result with
- the I(register) keyword to use it."
-options:
- type:
- description:
- - "Type of the external provider."
- choices: ['os_image', 'os_network', 'os_volume', 'foreman']
- required: true
- name:
- description:
- - "Name of the external provider, can be used as glob expression."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all image external providers named C<glance>:
-- ovirt_external_provider_info:
- type: os_image
- name: glance
- register: result
-- debug:
- msg: "{{ result.ovirt_external_providers }}"
-'''
-
-RETURN = '''
-ovirt_external_providers:
- description:
- - "List of dictionaries. Content depends on I(type)."
- - "For type C(foreman), attributes appearing in the dictionary can be found on your oVirt/RHV instance
- at the following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/external_host_provider."
- - "For type C(os_image), attributes appearing in the dictionary can be found on your oVirt/RHV instance
- at the following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/openstack_image_provider."
- - "For type C(os_volume), attributes appearing in the dictionary can be found on your oVirt/RHV instance
- at the following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/openstack_volume_provider."
- - "For type C(os_network), attributes appearing in the dictionary can be found on your oVirt/RHV instance
- at the following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/openstack_network_provider."
- returned: On success
- type: list
-'''
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def _external_provider_service(provider_type, system_service):
- if provider_type == 'os_image':
- return system_service.openstack_image_providers_service()
- elif provider_type == 'os_network':
- return system_service.openstack_network_providers_service()
- elif provider_type == 'os_volume':
- return system_service.openstack_volume_providers_service()
- elif provider_type == 'foreman':
- return system_service.external_host_providers_service()
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- name=dict(default=None, required=False),
- type=dict(
- default=None,
- required=True,
- choices=[
- 'os_image', 'os_network', 'os_volume', 'foreman',
- ],
- aliases=['provider'],
- ),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_external_provider_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_external_provider_facts' module has been renamed to 'ovirt_external_provider_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- external_providers_service = _external_provider_service(
- provider_type=module.params.pop('type'),
- system_service=connection.system_service(),
- )
- if module.params['name']:
- external_providers = [
- e for e in external_providers_service.list()
- if fnmatch.fnmatch(e.name, module.params['name'])
- ]
- else:
- external_providers = external_providers_service.list()
-
- result = dict(
- ovirt_external_providers=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in external_providers
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_group.py b/lib/ansible/modules/cloud/ovirt/ovirt_group.py
deleted file mode 100644
index 4f6777ed25..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_group.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_group
-short_description: Module to manage groups in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage groups in oVirt/RHV"
-options:
- name:
- description:
- - "Name of the group to manage."
- required: true
- state:
- description:
- - "Should the group be present/absent."
- choices: ['present', 'absent']
- default: present
- authz_name:
- description:
- - "Authorization provider of the group. In previous versions of oVirt/RHV known as domain."
- required: true
- aliases: ['domain']
- namespace:
- description:
- - "Namespace of the authorization provider, where group resides."
- required: false
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add group group1 from authorization provider example.com-authz
-- ovirt_group:
- name: group1
- domain: example.com-authz
-
-# Add group group1 from authorization provider example.com-authz
-# In case of multi-domain Active Directory setup, you should pass
-# also namespace, so it adds correct group:
-- ovirt_group:
- name: group1
- namespace: dc=ad2,dc=example,dc=com
- domain: example.com-authz
-
-# Remove group group1 with authorization provider example.com-authz
-- ovirt_group:
- state: absent
- name: group1
- domain: example.com-authz
-'''
-
-RETURN = '''
-id:
- description: ID of the group which is managed
- returned: On success if group is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-group:
- description: "Dictionary of all the group attributes. Group attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/group."
- returned: On success if group is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_params,
- create_connection,
- equal,
- ovirt_full_argument_spec,
-)
-
-
-def _group(connection, module):
- groups = connection.system_service().groups_service().list(
- search="name={name}".format(
- name=module.params['name'],
- )
- )
-
- # If found more groups, filter them by namespace and authz name:
- # (filtering here, as oVirt/RHV backend doesn't support it)
- if len(groups) > 1:
- groups = [
- g for g in groups if (
- equal(module.params['namespace'], g.namespace) and
- equal(module.params['authz_name'], g.domain.name)
- )
- ]
- return groups[0] if groups else None
-
-
-class GroupsModule(BaseModule):
-
- def build_entity(self):
- return otypes.Group(
- domain=otypes.Domain(
- name=self._module.params['authz_name']
- ),
- name=self._module.params['name'],
- namespace=self._module.params['namespace'],
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(required=True),
- authz_name=dict(required=True, aliases=['domain']),
- namespace=dict(default=None),
- )
- 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)
- groups_service = connection.system_service().groups_service()
- groups_module = GroupsModule(
- connection=connection,
- module=module,
- service=groups_service,
- )
- group = _group(connection, module)
- state = module.params['state']
- if state == 'present':
- ret = groups_module.create(entity=group)
- elif state == 'absent':
- ret = groups_module.remove(entity=group)
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_group_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_group_info.py
deleted file mode 100644
index b1381372d0..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_group_info.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_group_info
-short_description: Retrieve information about one or more oVirt/RHV groups
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV groups."
- - This module was called C(ovirt_group_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_group_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_groups), which
- contains a list of groups. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search group X use following pattern: name=X"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all groups which names start with C(admin):
-- ovirt_group_info:
- pattern: name=admin*
- register: result
-- debug:
- msg: "{{ result.ovirt_groups }}"
-'''
-
-RETURN = '''
-ovirt_groups:
- description: "List of dictionaries describing the groups. Group attributes are mapped to dictionary keys,
- all groups attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/group."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_group_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_group_facts' module has been renamed to 'ovirt_group_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- groups_service = connection.system_service().groups_service()
- groups = groups_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_groups=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in groups
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_host.py b/lib/ansible/modules/cloud/ovirt/ovirt_host.py
deleted file mode 100644
index c5e26625f3..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_host.py
+++ /dev/null
@@ -1,701 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_host
-short_description: Module to manage hosts in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage hosts in oVirt/RHV"
-options:
- id:
- description:
- - "ID of the host to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the host to manage."
- required: true
- state:
- description:
- - "State which should a host to be in after successful completion."
- - "I(iscsilogin) and I(iscsidiscover) are supported since version 2.4."
- choices: [
- 'present', 'absent', 'maintenance', 'upgraded', 'started',
- 'restarted', 'stopped', 'reinstalled', 'iscsidiscover', 'iscsilogin'
- ]
- default: present
- comment:
- description:
- - "Description of the host."
- timeout:
- description:
- - "The amount of time in seconds the module should wait for the host to
- get into desired state."
- default: 600
- cluster:
- description:
- - "Name of the cluster, where host should be created."
- address:
- description:
- - "Host address. It can be either FQDN (preferred) or IP address."
- password:
- description:
- - "Password of the root. It's required in case C(public_key) is set to I(False)."
- public_key:
- description:
- - "I(True) if the public key should be used to authenticate to host."
- - "It's required in case C(password) is not set."
- default: False
- type: bool
- aliases: ['ssh_public_key']
- kdump_integration:
- description:
- - "Specify if host will have enabled Kdump integration."
- choices: ['enabled', 'disabled']
- spm_priority:
- description:
- - "SPM priority of the host. Integer value from 1 to 10, where higher number means higher priority."
- override_iptables:
- description:
- - "If True host iptables will be overridden by host deploy script."
- - "Note that C(override_iptables) is I(false) by default in oVirt/RHV."
- type: bool
- force:
- description:
- - "Indicates that the host should be removed even if it is non-responsive,
- or if it is part of a Gluster Storage cluster and has volume bricks on it."
- - "WARNING: It doesn't forcibly remove the host if another host related operation is being executed on the host at the same time."
- default: False
- type: bool
- override_display:
- description:
- - "Override the display address of all VMs on this host with specified address."
- type: bool
- kernel_params:
- description:
- - "List of kernel boot parameters."
- - "Following are most common kernel parameters used for host:"
- - "Hostdev Passthrough & SR-IOV: intel_iommu=on"
- - "Nested Virtualization: kvm-intel.nested=1"
- - "Unsafe Interrupts: vfio_iommu_type1.allow_unsafe_interrupts=1"
- - "PCI Reallocation: pci=realloc"
- - "C(Note:)"
- - "Modifying kernel boot parameters settings can lead to a host boot failure.
- Please consult the product documentation before doing any changes."
- - "Kernel boot parameters changes require host deploy and restart. The host needs
- to be I(reinstalled) successfully and then to be I(rebooted) for kernel boot parameters
- to be applied."
- hosted_engine:
- description:
- - "If I(deploy) it means this host should deploy also hosted engine
- components."
- - "If I(undeploy) it means this host should un-deploy hosted engine
- components and this host will not function as part of the High
- Availability cluster."
- choices:
- - 'deploy'
- - 'undeploy'
- power_management_enabled:
- description:
- - "Enable or disable power management of the host."
- - "For more comprehensive setup of PM use C(ovirt_host_pm) module."
- version_added: 2.4
- type: bool
- activate:
- description:
- - "If C(state) is I(present) activate the host."
- - "This parameter is good to disable, when you don't want to change
- the state of host when using I(present) C(state)."
- default: True
- type: bool
- version_added: 2.4
- iscsi:
- description:
- - "If C(state) is I(iscsidiscover) it means that the iscsi attribute is being
- used to discover targets"
- - "If C(state) is I(iscsilogin) it means that the iscsi attribute is being
- used to login to the specified targets passed as part of the iscsi attribute"
- suboptions:
- username:
- description:
- - "A CHAP user name for logging into a target."
- password:
- description:
- - "A CHAP password for logging into a target."
- address:
- description:
- - "Address of the iSCSI storage server."
- target:
- description:
- - "The target IQN for the storage device."
- port:
- description:
- - "The port being used to connect with iscsi."
- portal:
- description:
- - "The portal being used to connect with iscsi."
- version_added: 2.10
- version_added: 2.4
- check_upgrade:
- description:
- - "If I(true) and C(state) is I(upgraded) run check for upgrade
- action before executing upgrade action."
- default: True
- type: bool
- version_added: 2.4
- reboot_after_upgrade:
- description:
- - "If I(true) and C(state) is I(upgraded) reboot host after successful upgrade."
- default: True
- type: bool
- version_added: 2.6
- vgpu_placement:
- description:
- - If I(consolidated), each vGPU is placed on the first physical card with
- available space. This is the default placement, utilizing all available
- space on the physical cards.
- - If I(separated), each vGPU is placed on a separate physical card, if
- possible. This can be useful for improving vGPU performance.
- choices: ['consolidated', 'separated']
- version_added: 2.8
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add host with username/password supporting SR-IOV.
-# Note that override_iptables is false by default in oVirt/RHV:
-- ovirt_host:
- cluster: Default
- name: myhost
- address: 10.34.61.145
- password: secret
- override_iptables: true
- kernel_params:
- - intel_iommu=on
-
-# Add host using public key
-- ovirt_host:
- public_key: true
- cluster: Default
- name: myhost2
- address: 10.34.61.145
- override_iptables: true
-
-# Deploy hosted engine host
-- ovirt_host:
- cluster: Default
- name: myhost2
- password: secret
- address: 10.34.61.145
- override_iptables: true
- hosted_engine: deploy
-
-# Maintenance
-- ovirt_host:
- state: maintenance
- name: myhost
-
-# Restart host using power management:
-- ovirt_host:
- state: restarted
- name: myhost
-
-# Upgrade host
-- ovirt_host:
- state: upgraded
- name: myhost
-
-# discover iscsi targets
-- ovirt_host:
- state: iscsidiscover
- name: myhost
- iscsi:
- username: iscsi_user
- password: secret
- address: 10.34.61.145
- port: 3260
-
-
-# login to iscsi targets
-- ovirt_host:
- state: iscsilogin
- name: myhost
- iscsi:
- username: iscsi_user
- password: secret
- address: 10.34.61.145
- target: "iqn.2015-07.com.mlipchuk2.redhat:444"
- port: 3260
-
-
-# Reinstall host using public key
-- ovirt_host:
- state: reinstalled
- name: myhost
- public_key: true
-
-# Remove host
-- ovirt_host:
- state: absent
- name: myhost
- force: True
-
-# Retry removing host when failed (https://bugzilla.redhat.com/show_bug.cgi?id=1719271)
-- ovirt_host:
- state: absent
- name: myhost
- register: result
- until: not result.failed
- retries: 6
- delay: 20
-
-# Change host Name
-- ovirt_host:
- id: 00000000-0000-0000-0000-000000000000
- name: "new host name"
-'''
-
-RETURN = '''
-id:
- description: ID of the host which is managed
- returned: On success if host is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-host:
- description: "Dictionary of all the host attributes. Host attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/host."
- returned: On success if host is found.
- type: dict
-iscsi_targets:
- description: "List of host iscsi targets"
- returned: On success if host is found and state is iscsidiscover.
- type: list
-'''
-
-import time
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-
- from ovirtsdk4.types import HostStatus as hoststate
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_id_by_name,
- ovirt_full_argument_spec,
- wait,
-)
-
-
-class HostsModule(BaseModule):
- def __init__(self, start_event=None, *args, **kwargs):
- super(HostsModule, self).__init__(*args, **kwargs)
- self.start_event = start_event
-
- def build_entity(self):
- return otypes.Host(
- id=self._module.params.get('id'),
- name=self.param('name'),
- cluster=otypes.Cluster(
- name=self.param('cluster')
- ) if self.param('cluster') else None,
- comment=self.param('comment'),
- address=self.param('address'),
- root_password=self.param('password'),
- ssh=otypes.Ssh(
- authentication_method=otypes.SshAuthenticationMethod.PUBLICKEY,
- ) if self.param('public_key') else None,
- spm=otypes.Spm(
- priority=self.param('spm_priority'),
- ) if self.param('spm_priority') else None,
- override_iptables=self.param('override_iptables'),
- display=otypes.Display(
- address=self.param('override_display'),
- ) if self.param('override_display') else None,
- os=otypes.OperatingSystem(
- custom_kernel_cmdline=' '.join(self.param('kernel_params')),
- ) if self.param('kernel_params') else None,
- power_management=otypes.PowerManagement(
- enabled=self.param('power_management_enabled'),
- kdump_detection=self.param('kdump_integration') == 'enabled',
- ) if self.param('power_management_enabled') is not None or self.param('kdump_integration') else None,
- vgpu_placement=otypes.VgpuPlacement(
- self.param('vgpu_placement')
- ) if self.param('vgpu_placement') is not None else None,
- )
-
- def update_check(self, entity):
- kernel_params = self.param('kernel_params')
- return (
- equal(self.param('comment'), entity.comment) and
- equal(self.param('kdump_integration'), 'enabled' if entity.power_management.kdump_detection else 'disabled') and
- equal(self.param('spm_priority'), entity.spm.priority) and
- equal(self.param('name'), entity.name) and
- equal(self.param('power_management_enabled'), entity.power_management.enabled) and
- equal(self.param('override_display'), getattr(entity.display, 'address', None)) and
- equal(self.param('vgpu_placement'), str(entity.vgpu_placement)) and
- equal(
- sorted(kernel_params) if kernel_params else None,
- sorted(entity.os.custom_kernel_cmdline.split(' '))
- )
- )
-
- def pre_remove(self, entity):
- self.action(
- entity=entity,
- action='deactivate',
- action_condition=lambda h: h.status != hoststate.MAINTENANCE,
- wait_condition=lambda h: h.status == hoststate.MAINTENANCE,
- )
-
- def post_reinstall(self, host):
- wait(
- service=self._service.service(host.id),
- condition=lambda h: h.status != hoststate.MAINTENANCE,
- fail_condition=failed_state,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
-
- def raise_host_exception(self):
- events = self._connection.system_service().events_service().list(from_=int(self.start_event.index))
- error_events = [
- event.description for event in events
- if event.host is not None and (event.host.id == self.param('id') or event.host.name == self.param('name')) and
- event.severity in [otypes.LogSeverity.WARNING, otypes.LogSeverity.ERROR]
- ]
- if error_events:
- raise Exception("Error message: %s" % error_events)
- return True
-
- def failed_state_after_reinstall(self, host, count=0):
- if host.status in [
- hoststate.ERROR,
- hoststate.INSTALL_FAILED,
- hoststate.NON_OPERATIONAL,
- ]:
- return self.raise_host_exception()
-
- # If host is in non-responsive state after upgrade/install
- # let's wait for few seconds and re-check again the state:
- if host.status == hoststate.NON_RESPONSIVE:
- if count <= 3:
- time.sleep(20)
- return self.failed_state_after_reinstall(
- self._service.service(host.id).get(),
- count + 1,
- )
- else:
- return self.raise_host_exception()
-
- return False
-
-
-def failed_state(host):
- return host.status in [
- hoststate.ERROR,
- hoststate.INSTALL_FAILED,
- hoststate.NON_RESPONSIVE,
- hoststate.NON_OPERATIONAL,
- ]
-
-
-def control_state(host_module):
- host = host_module.search_entity()
- if host is None:
- return
-
- state = host_module._module.params['state']
- host_service = host_module._service.service(host.id)
- if failed_state(host):
- # In case host is in INSTALL_FAILED status, we can reinstall it:
- if hoststate.INSTALL_FAILED == host.status and state != 'reinstalled':
- raise Exception(
- "Not possible to manage host '%s' in state '%s'." % (
- host.name,
- host.status
- )
- )
- elif host.status in [
- hoststate.REBOOT,
- hoststate.CONNECTING,
- hoststate.INITIALIZING,
- hoststate.INSTALLING,
- hoststate.INSTALLING_OS,
- ]:
- wait(
- service=host_service,
- condition=lambda host: host.status == hoststate.UP,
- fail_condition=failed_state,
- )
- elif host.status == hoststate.PREPARING_FOR_MAINTENANCE:
- wait(
- service=host_service,
- condition=lambda host: host.status == hoststate.MAINTENANCE,
- fail_condition=failed_state,
- )
-
- return host
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=[
- 'present', 'absent', 'maintenance', 'upgraded', 'started',
- 'restarted', 'stopped', 'reinstalled', 'iscsidiscover', 'iscsilogin'
- ],
- default='present',
- ),
- name=dict(required=True),
- id=dict(default=None),
- comment=dict(default=None),
- cluster=dict(default=None),
- address=dict(default=None),
- password=dict(default=None, no_log=True),
- public_key=dict(default=False, type='bool', aliases=['ssh_public_key']),
- kdump_integration=dict(default=None, choices=['enabled', 'disabled']),
- spm_priority=dict(default=None, type='int'),
- override_iptables=dict(default=None, type='bool'),
- force=dict(default=False, type='bool'),
- timeout=dict(default=600, type='int'),
- override_display=dict(default=None),
- kernel_params=dict(default=None, type='list'),
- hosted_engine=dict(default=None, choices=['deploy', 'undeploy']),
- power_management_enabled=dict(default=None, type='bool'),
- activate=dict(default=True, type='bool'),
- iscsi=dict(default=None, type='dict'),
- check_upgrade=dict(default=True, type='bool'),
- reboot_after_upgrade=dict(default=True, type='bool'),
- vgpu_placement=dict(default=None, choices=['consolidated', 'separated']),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'iscsidiscover', ['iscsi']],
- ['state', 'iscsilogin', ['iscsi']]
- ]
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- hosts_service = connection.system_service().hosts_service()
- start_event = connection.system_service().events_service().list(max=1)[0]
- hosts_module = HostsModule(
- connection=connection,
- module=module,
- service=hosts_service,
- start_event=start_event,
- )
-
- state = module.params['state']
- host = control_state(hosts_module)
- if state == 'present':
- ret = hosts_module.create(
- deploy_hosted_engine=(
- module.params.get('hosted_engine') == 'deploy'
- ) if module.params.get('hosted_engine') is not None else None,
- activate=module.params['activate'],
- result_state=(hoststate.MAINTENANCE if module.params['activate'] is False else hoststate.UP) if host is None else None,
- fail_condition=hosts_module.failed_state_after_reinstall if host is None else lambda h: False,
- )
- if module.params['activate'] and host is not None:
- ret = hosts_module.action(
- action='activate',
- action_condition=lambda h: h.status != hoststate.UP,
- wait_condition=lambda h: h.status == hoststate.UP,
- fail_condition=failed_state,
- )
- elif state == 'absent':
- ret = hosts_module.remove()
- elif state == 'maintenance':
- hosts_module.action(
- action='deactivate',
- action_condition=lambda h: h.status != hoststate.MAINTENANCE,
- wait_condition=lambda h: h.status == hoststate.MAINTENANCE,
- fail_condition=failed_state,
- )
- ret = hosts_module.create()
- elif state == 'upgraded':
- result_state = hoststate.MAINTENANCE if host.status == hoststate.MAINTENANCE else hoststate.UP
- events_service = connection.system_service().events_service()
- last_event = events_service.list(max=1)[0]
-
- if module.params['check_upgrade']:
- hosts_module.action(
- action='upgrade_check',
- action_condition=lambda host: not host.update_available,
- wait_condition=lambda host: host.update_available or (
- len([
- event
- for event in events_service.list(
- from_=int(last_event.id),
- search='type=885',
- # Uncomment when 4.1 is EOL, and remove the cond:
- # if host.name in event.description
- # search='type=885 and host.name=%s' % host.name,
- ) if host.name in event.description
- ]) > 0
- ),
- fail_condition=lambda host: len([
- event
- for event in events_service.list(
- from_=int(last_event.id),
- search='type=839 or type=887 and host.name=%s' % host.name,
- )
- ]) > 0,
- )
- # Set to False, because upgrade_check isn't 'changing' action:
- hosts_module._changed = False
- ret = hosts_module.action(
- action='upgrade',
- action_condition=lambda h: h.update_available,
- wait_condition=lambda h: h.status == result_state,
- post_action=lambda h: time.sleep(module.params['poll_interval']),
- fail_condition=lambda h: hosts_module.failed_state_after_reinstall(h) or (
- len([
- event
- for event in events_service.list(
- from_=int(last_event.id),
- # Fail upgrade if migration fails:
- # 17: Failed to switch Host to Maintenance mode
- # 65, 140: Migration failed
- # 166: No available host was found to migrate VM
- search='type=65 or type=140 or type=166 or type=17',
- ) if host.name in event.description
- ]) > 0
- ),
- reboot=module.params['reboot_after_upgrade'],
- )
- elif state == 'iscsidiscover':
- host_id = get_id_by_name(hosts_service, module.params['name'])
- iscsi_param = module.params['iscsi']
- iscsi_targets = hosts_service.service(host_id).iscsi_discover(
- iscsi=otypes.IscsiDetails(
- port=int(iscsi_param.get('port', 3260)),
- username=iscsi_param.get('username'),
- password=iscsi_param.get('password'),
- address=iscsi_param.get('address'),
- portal=iscsi_param.get('portal'),
- ),
- )
- ret = {
- 'changed': False,
- 'id': host_id,
- 'iscsi_targets': iscsi_targets,
- }
- elif state == 'iscsilogin':
- host_id = get_id_by_name(hosts_service, module.params['name'])
- iscsi_param = module.params['iscsi']
- ret = hosts_module.action(
- action='iscsi_login',
- iscsi=otypes.IscsiDetails(
- port=int(iscsi_param.get('port', 3260)),
- username=iscsi_param.get('username'),
- password=iscsi_param.get('password'),
- address=iscsi_param.get('address'),
- target=iscsi_param.get('target'),
- portal=iscsi_param.get('portal'),
- ),
- )
- elif state == 'started':
- ret = hosts_module.action(
- action='fence',
- action_condition=lambda h: h.status == hoststate.DOWN,
- wait_condition=lambda h: h.status in [hoststate.UP, hoststate.MAINTENANCE],
- fail_condition=hosts_module.failed_state_after_reinstall,
- fence_type='start',
- )
- elif state == 'stopped':
- hosts_module.action(
- action='deactivate',
- action_condition=lambda h: h.status not in [hoststate.MAINTENANCE, hoststate.DOWN],
- wait_condition=lambda h: h.status in [hoststate.MAINTENANCE, hoststate.DOWN],
- fail_condition=failed_state,
- )
- ret = hosts_module.action(
- action='fence',
- action_condition=lambda h: h.status != hoststate.DOWN,
- wait_condition=lambda h: h.status == hoststate.DOWN if module.params['wait'] else True,
- fail_condition=failed_state,
- fence_type='stop',
- )
- elif state == 'restarted':
- ret = hosts_module.action(
- action='fence',
- wait_condition=lambda h: h.status == hoststate.UP,
- fail_condition=hosts_module.failed_state_after_reinstall,
- fence_type='restart',
- )
- elif state == 'reinstalled':
- # Deactivate host if not in maintanence:
- hosts_module.action(
- action='deactivate',
- action_condition=lambda h: h.status not in [hoststate.MAINTENANCE, hoststate.DOWN],
- wait_condition=lambda h: h.status in [hoststate.MAINTENANCE, hoststate.DOWN],
- fail_condition=failed_state,
- )
-
- # Reinstall host:
- hosts_module.action(
- action='install',
- action_condition=lambda h: h.status == hoststate.MAINTENANCE,
- post_action=hosts_module.post_reinstall,
- wait_condition=lambda h: h.status == hoststate.MAINTENANCE,
- fail_condition=hosts_module.failed_state_after_reinstall,
- host=otypes.Host(
- override_iptables=module.params['override_iptables'],
- ) if module.params['override_iptables'] else None,
- root_password=module.params['password'],
- ssh=otypes.Ssh(
- authentication_method=otypes.SshAuthenticationMethod.PUBLICKEY,
- ) if module.params['public_key'] else None,
- deploy_hosted_engine=(
- module.params.get('hosted_engine') == 'deploy'
- ) if module.params.get('hosted_engine') is not None else None,
- undeploy_hosted_engine=(
- module.params.get('hosted_engine') == 'undeploy'
- ) if module.params.get('hosted_engine') is not None else None,
- )
-
- # Activate host after reinstall:
- ret = hosts_module.action(
- action='activate',
- action_condition=lambda h: h.status == hoststate.MAINTENANCE,
- wait_condition=lambda h: h.status == hoststate.UP,
- fail_condition=failed_state,
- )
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_host_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_host_info.py
deleted file mode 100644
index 807baa20dc..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_host_info.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_host_info
-short_description: Retrieve information about one or more oVirt/RHV hosts
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV hosts."
- - This module was called C(ovirt_host_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_host_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_hosts), which
- contains a list of hosts. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search host X from datacenter Y use following pattern:
- name=X and datacenter=Y"
- all_content:
- description:
- - "If I(true) all the attributes of the hosts should be
- included in the response."
- default: False
- version_added: "2.7"
- type: bool
- cluster_version:
- description:
- - "Filter the hosts based on the cluster version."
- type: str
- version_added: "2.8"
-
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all hosts which names start with C(host) and
-# belong to data center C(west):
-- ovirt_host_info:
- pattern: name=host* and datacenter=west
- register: result
-- debug:
- msg: "{{ result.ovirt_hosts }}"
-# All hosts with cluster version 4.2:
-- ovirt_host_info:
- pattern: name=host*
- cluster_version: "4.2"
- register: result
-- debug:
- msg: "{{ result.ovirt_hosts }}"
-'''
-
-RETURN = '''
-ovirt_hosts:
- description: "List of dictionaries describing the hosts. Host attributes are mapped to dictionary keys,
- all hosts attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/host."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def get_filtered_hosts(cluster_version, hosts, connection):
- # Filtering by cluster version returns only those which have same cluster version as input
- filtered_hosts = []
- for host in hosts:
- cluster = connection.follow_link(host.cluster)
- cluster_version_host = str(cluster.version.major) + '.' + str(cluster.version.minor)
- if cluster_version_host == cluster_version:
- filtered_hosts.append(host)
- return filtered_hosts
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- all_content=dict(default=False, type='bool'),
- cluster_version=dict(default=None, type='str'),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_host_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_host_facts' module has been renamed to 'ovirt_host_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- hosts_service = connection.system_service().hosts_service()
- hosts = hosts_service.list(
- search=module.params['pattern'],
- all_content=module.params['all_content']
- )
- cluster_version = module.params.get('cluster_version')
- if cluster_version is not None:
- hosts = get_filtered_hosts(cluster_version, hosts, connection)
- result = dict(
- ovirt_hosts=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in hosts
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_host_network.py b/lib/ansible/modules/cloud/ovirt/ovirt_host_network.py
deleted file mode 100644
index 8c4ac44d70..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_host_network.py
+++ /dev/null
@@ -1,601 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016, 2018 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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_host_network
-short_description: Module to manage host networks in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage host networks in oVirt/RHV."
-options:
- name:
- description:
- - "Name of the host to manage networks for."
- required: true
- aliases:
- - 'host'
- state:
- description:
- - "Should the host be present/absent."
- choices: ['present', 'absent']
- default: present
- bond:
- description:
- - "Dictionary describing network bond:"
- suboptions:
- name:
- description:
- - Bond name.
- mode:
- description:
- - Bonding mode.
- options:
- description:
- - Bonding options.
- interfaces:
- description:
- - List of interfaces to create a bond.
- interface:
- description:
- - "Name of the network interface where logical network should be attached."
- networks:
- description:
- - "List of dictionary describing networks to be attached to interface or bond:"
- suboptions:
- name:
- description:
- - Name of the logical network to be assigned to bond or interface.
- boot_protocol:
- description:
- - Boot protocol.
- choices: ['none', 'static', 'dhcp']
- address:
- description:
- - IP address in case of I(static) boot protocol is used.
- netmask:
- description:
- - Subnet mask in case of I(static) boot protocol is used.
- gateway:
- description:
- - Gateway in case of I(static) boot protocol is used.
- version:
- description:
- - IP version. Either v4 or v6. Default is v4.
- custom_properties:
- description:
- - "Custom properties applied to the host network."
- - "Custom properties is a list of dictionary which can have following values."
- suboptions:
- name:
- description:
- - Name of custom property.
- value:
- description:
- - Value of custom property.
- version_added: 2.10
- labels:
- description:
- - "List of names of the network label to be assigned to bond or interface."
- check:
- description:
- - "If I(true) verify connectivity between host and engine."
- - "Network configuration changes will be rolled back if connectivity between
- engine and the host is lost after changing network configuration."
- type: bool
- save:
- description:
- - "If I(true) network configuration will be persistent, otherwise it is temporary. Default I(true) since Ansible 2.8."
- type: bool
- default: True
- sync_networks:
- description:
- - "If I(true) all networks will be synchronized before modification"
- type: bool
- default: false
- version_added: 2.8
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# In all examples the durability of the configuration created is dependent on the 'save' option value:
-
-# Create bond on eth0 and eth1 interface, and put 'myvlan' network on top of it and persist the new configuration:
-- name: Bonds
- ovirt_host_network:
- name: myhost
- save: yes
- bond:
- name: bond0
- mode: 2
- interfaces:
- - eth1
- - eth2
- networks:
- - name: myvlan
- boot_protocol: static
- address: 1.2.3.4
- netmask: 255.255.255.0
- gateway: 1.2.3.4
- version: v4
-
-# Create bond on eth1 and eth2 interface, specifying both mode and miimon:
-- name: Bonds
- ovirt_host_network:
- name: myhost
- bond:
- name: bond0
- mode: 1
- options:
- miimon: 200
- interfaces:
- - eth1
- - eth2
-
-# Remove bond0 bond from host interfaces:
-- ovirt_host_network:
- state: absent
- name: myhost
- bond:
- name: bond0
-
-# Assign myvlan1 and myvlan2 vlans to host eth0 interface:
-- ovirt_host_network:
- name: myhost
- interface: eth0
- networks:
- - name: myvlan1
- - name: myvlan2
-
-# Remove myvlan2 vlan from host eth0 interface:
-- ovirt_host_network:
- state: absent
- name: myhost
- interface: eth0
- networks:
- - name: myvlan2
-
-# Remove all networks/vlans from host eth0 interface:
-- ovirt_host_network:
- state: absent
- name: myhost
- interface: eth0
-
-# Add custom_properties to network:
-- ovirt_host_network:
- name: myhost
- interface: eth0
- networks:
- - name: myvlan1
- custom_properties:
- - name: bridge_opts
- value: gc_timer=10
-'''
-
-RETURN = '''
-id:
- description: ID of the host NIC which is managed
- returned: On success if host NIC is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-host_nic:
- description: "Dictionary of all the host NIC attributes. Host NIC attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/host_nic."
- returned: On success if host NIC is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils import six
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_dict_of_struct,
- get_entity,
- get_link_name,
- ovirt_full_argument_spec,
- search_by_name,
- engine_supported
-)
-
-
-def get_bond_options(mode, usr_opts):
- MIIMON_100 = dict(miimon='100')
- DEFAULT_MODE_OPTS = {
- '1': MIIMON_100,
- '2': MIIMON_100,
- '3': MIIMON_100,
- '4': dict(xmit_hash_policy='2', **MIIMON_100)
- }
-
- options = []
- if mode is None:
- return options
-
- def get_type_name(mode_number):
- """
- We need to maintain this type strings, for the __compare_options method,
- for easier comparision.
- """
- modes = [
- 'Active-Backup',
- 'Load balance (balance-xor)',
- None,
- 'Dynamic link aggregation (802.3ad)',
- ]
- if (not 0 < mode_number <= len(modes)):
- return None
- return modes[mode_number - 1]
-
- try:
- mode_number = int(mode)
- except ValueError:
- raise Exception('Bond mode must be a number.')
-
- options.append(
- otypes.Option(
- name='mode',
- type=get_type_name(mode_number),
- value=str(mode_number)
- )
- )
-
- opts_dict = DEFAULT_MODE_OPTS.get(str(mode), {})
- if usr_opts is not None:
- opts_dict.update(**usr_opts)
-
- options.extend(
- [otypes.Option(name=opt, value=str(value))
- for opt, value in six.iteritems(opts_dict)]
- )
- return options
-
-
-class HostNetworksModule(BaseModule):
-
- def __compare_options(self, new_options, old_options):
- return sorted((get_dict_of_struct(opt) for opt in new_options),
- key=lambda x: x["name"]) != sorted((get_dict_of_struct(opt) for opt in old_options),
- key=lambda x: x["name"])
-
- def build_entity(self):
- return otypes.Host()
-
- def update_custom_properties(self, attachments_service, attachment, network):
- if network.get('custom_properties'):
- current = []
- if attachment.properties:
- current = [(cp.name, str(cp.value)) for cp in attachment.properties]
- passed = [(cp.get('name'), str(cp.get('value'))) for cp in network.get('custom_properties') if cp]
- if sorted(current) != sorted(passed):
- attachment.properties = [
- otypes.Property(
- name=prop.get('name'),
- value=prop.get('value')
- ) for prop in network.get('custom_properties')
- ]
- if not self._module.check_mode:
- attachments_service.service(attachment.id).update(attachment)
- self.changed = True
-
- def update_address(self, attachments_service, attachment, network):
- # Check if there is any change in address assignments and
- # update it if needed:
- for ip in attachment.ip_address_assignments:
- if str(ip.ip.version) == network.get('version', 'v4'):
- changed = False
- if not equal(network.get('boot_protocol'), str(ip.assignment_method)):
- ip.assignment_method = otypes.BootProtocol(network.get('boot_protocol'))
- changed = True
- if not equal(network.get('address'), ip.ip.address):
- ip.ip.address = network.get('address')
- changed = True
- if not equal(network.get('gateway'), ip.ip.gateway):
- ip.ip.gateway = network.get('gateway')
- changed = True
- if not equal(network.get('netmask'), ip.ip.netmask):
- ip.ip.netmask = network.get('netmask')
- changed = True
-
- if changed:
- if not self._module.check_mode:
- attachments_service.service(attachment.id).update(attachment)
- self.changed = True
- break
-
- def has_update(self, nic_service):
- update = False
- bond = self._module.params['bond']
- networks = self._module.params['networks']
- labels = self._module.params['labels']
- nic = get_entity(nic_service)
-
- if nic is None:
- return update
-
- # Check if bond configuration should be updated:
- if bond:
- update = self.__compare_options(get_bond_options(bond.get('mode'), bond.get('options')), getattr(nic.bonding, 'options', []))
- update = update or not equal(
- sorted(bond.get('interfaces')) if bond.get('interfaces') else None,
- sorted(get_link_name(self._connection, s) for s in nic.bonding.slaves)
- )
-
- # Check if labels need to be updated on interface/bond:
- if labels:
- net_labels = nic_service.network_labels_service().list()
- # If any labels which user passed aren't assigned, relabel the interface:
- if sorted(labels) != sorted([lbl.id for lbl in net_labels]):
- return True
-
- if not networks:
- return update
-
- # Check if networks attachments configuration should be updated:
- attachments_service = nic_service.network_attachments_service()
- network_names = [network.get('name') for network in networks]
-
- attachments = {}
- for attachment in attachments_service.list():
- name = get_link_name(self._connection, attachment.network)
- if name in network_names:
- attachments[name] = attachment
-
- for network in networks:
- attachment = attachments.get(network.get('name'))
- # If attachment don't exists, we need to create it:
- if attachment is None:
- return True
- self.update_custom_properties(attachments_service, attachment, network)
- self.update_address(attachments_service, attachment, network)
-
- return update
-
- def _action_save_configuration(self, entity):
- if not self._module.check_mode:
- self._service.service(entity.id).commit_net_config()
- self.changed = True
-
-
-def needs_sync(nics_service):
- nics = nics_service.list()
- for nic in nics:
- nic_service = nics_service.nic_service(nic.id)
- for network_attachment_service in nic_service.network_attachments_service().list():
- if not network_attachment_service.in_sync:
- return True
- return False
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(aliases=['host'], required=True),
- bond=dict(default=None, type='dict'),
- interface=dict(default=None),
- networks=dict(default=None, type='list'),
- labels=dict(default=None, type='list'),
- check=dict(default=None, type='bool'),
- save=dict(default=True, type='bool'),
- sync_networks=dict(default=False, type='bool'),
- )
- module = AnsibleModule(argument_spec=argument_spec)
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- hosts_service = connection.system_service().hosts_service()
- host_networks_module = HostNetworksModule(
- connection=connection,
- module=module,
- service=hosts_service,
- )
-
- host = host_networks_module.search_entity()
- if host is None:
- raise Exception("Host '%s' was not found." % module.params['name'])
-
- bond = module.params['bond']
- interface = module.params['interface']
- networks = module.params['networks']
- labels = module.params['labels']
- nic_name = bond.get('name') if bond else module.params['interface']
-
- host_service = hosts_service.host_service(host.id)
- nics_service = host_service.nics_service()
- nic = search_by_name(nics_service, nic_name)
-
- if module.params["sync_networks"]:
- if needs_sync(nics_service):
- if not module.check_mode:
- host_service.sync_all_networks()
- host_networks_module.changed = True
-
- network_names = [network['name'] for network in networks or []]
- state = module.params['state']
-
- if (
- state == 'present' and
- (nic is None or host_networks_module.has_update(nics_service.service(nic.id)))
- ):
- # Remove networks which are attached to different interface then user want:
- attachments_service = host_service.network_attachments_service()
-
- # Append attachment ID to network if needs update:
- for a in attachments_service.list():
- current_network_name = get_link_name(connection, a.network)
- if current_network_name in network_names:
- for n in networks:
- if n['name'] == current_network_name:
- n['id'] = a.id
-
- # Check if we have to break some bonds:
- removed_bonds = []
- if nic is not None:
- for host_nic in nics_service.list():
- if host_nic.bonding and nic.id in [slave.id for slave in host_nic.bonding.slaves]:
- removed_bonds.append(otypes.HostNic(id=host_nic.id))
-
- # Assign the networks:
- setup_params = dict(
- entity=host,
- action='setup_networks',
- check_connectivity=module.params['check'],
- removed_bonds=removed_bonds if removed_bonds else None,
- modified_bonds=[
- otypes.HostNic(
- name=bond.get('name'),
- bonding=otypes.Bonding(
- options=get_bond_options(bond.get('mode'), bond.get('options')),
- slaves=[
- otypes.HostNic(name=i) for i in bond.get('interfaces', [])
- ],
- ),
- ),
- ] if bond else None,
- modified_labels=[
- otypes.NetworkLabel(
- id=str(name),
- host_nic=otypes.HostNic(
- name=bond.get('name') if bond else interface
- ),
- ) for name in labels
- ] if labels else None,
- modified_network_attachments=[
- otypes.NetworkAttachment(
- id=network.get('id'),
- network=otypes.Network(
- name=network['name']
- ) if network['name'] else None,
- host_nic=otypes.HostNic(
- name=bond.get('name') if bond else interface
- ),
- ip_address_assignments=[
- otypes.IpAddressAssignment(
- assignment_method=otypes.BootProtocol(
- network.get('boot_protocol', 'none')
- ),
- ip=otypes.Ip(
- address=network.get('address'),
- gateway=network.get('gateway'),
- netmask=network.get('netmask'),
- version=otypes.IpVersion(
- network.get('version')
- ) if network.get('version') else None,
- ),
- ),
- ],
- properties=[
- otypes.Property(
- name=prop.get('name'),
- value=prop.get('value')
- ) for prop in network.get('custom_properties')
- ]
- ) for network in networks
- ] if networks else None,
- )
- if engine_supported(connection, '4.3'):
- setup_params['commit_on_success'] = module.params['save']
- elif module.params['save']:
- setup_params['post_action'] = host_networks_module._action_save_configuration
- host_networks_module.action(**setup_params)
- elif state == 'absent' and nic:
- attachments = []
- nic_service = nics_service.nic_service(nic.id)
-
- attached_labels = set([str(lbl.id) for lbl in nic_service.network_labels_service().list()])
- if networks:
- attachments_service = nic_service.network_attachments_service()
- attachments = attachments_service.list()
- attachments = [
- attachment for attachment in attachments
- if get_link_name(connection, attachment.network) in network_names
- ]
-
- # Remove unmanaged networks:
- unmanaged_networks_service = host_service.unmanaged_networks_service()
- unmanaged_networks = [(u.id, u.name) for u in unmanaged_networks_service.list()]
- for net_id, net_name in unmanaged_networks:
- if net_name in network_names:
- if not module.check_mode:
- unmanaged_networks_service.unmanaged_network_service(net_id).remove()
- host_networks_module.changed = True
-
- # Need to check if there are any labels to be removed, as backend fail
- # if we try to send remove non existing label, for bond and attachments it's OK:
- if (labels and set(labels).intersection(attached_labels)) or bond or attachments:
- setup_params = dict(
- entity=host,
- action='setup_networks',
- check_connectivity=module.params['check'],
- removed_bonds=[
- otypes.HostNic(
- name=bond.get('name'),
- ),
- ] if bond else None,
- removed_labels=[
- otypes.NetworkLabel(id=str(name)) for name in labels
- ] if labels else None,
- removed_network_attachments=attachments if attachments else None,
- )
- if engine_supported(connection, '4.3'):
- setup_params['commit_on_success'] = module.params['save']
- elif module.params['save']:
- setup_params['post_action'] = host_networks_module._action_save_configuration
- host_networks_module.action(**setup_params)
-
- nic = search_by_name(nics_service, nic_name)
- module.exit_json(**{
- 'changed': host_networks_module.changed,
- 'id': nic.id if nic else None,
- 'host_nic': get_dict_of_struct(nic),
- })
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py b/lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py
deleted file mode 100644
index aab2c9f922..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py
+++ /dev/null
@@ -1,261 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_host_pm
-short_description: Module to manage power management of hosts in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage power management of hosts in oVirt/RHV."
-options:
- name:
- description:
- - "Name of the host to manage."
- required: true
- aliases: ['host']
- state:
- description:
- - "Should the host be present/absent."
- choices: ['present', 'absent']
- default: present
- address:
- description:
- - "Address of the power management interface."
- username:
- description:
- - "Username to be used to connect to power management interface."
- password:
- description:
- - "Password of the user specified in C(username) parameter."
- type:
- description:
- - "Type of the power management. oVirt/RHV predefined values are I(drac5), I(ipmilan), I(rsa),
- I(bladecenter), I(alom), I(apc), I(apc_snmp), I(eps), I(wti), I(rsb), I(cisco_ucs),
- I(drac7), I(hpblade), I(ilo), I(ilo2), I(ilo3), I(ilo4), I(ilo_ssh),
- but user can have defined custom type."
- port:
- description:
- - "Power management interface port."
- options:
- description:
- - "Dictionary of additional fence agent options (including Power Management slot)."
- - "Additional information about options can be found at U(https://github.com/ClusterLabs/fence-agents/blob/master/doc/FenceAgentAPI.md)."
- encrypt_options:
- description:
- - "If I(true) options will be encrypted when send to agent."
- aliases: ['encrypt']
- type: bool
- order:
- description:
- - "Integer value specifying, by default it's added at the end."
- version_added: "2.5"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add fence agent to host 'myhost'
-- ovirt_host_pm:
- name: myhost
- address: 1.2.3.4
- options:
- myoption1: x
- myoption2: y
- username: admin
- password: admin
- port: 3333
- type: ipmilan
-
-# Add fence agent to host 'myhost' using 'slot' option
-- ovirt_host_pm:
- name: myhost
- address: 1.2.3.4
- options:
- myoption1: x
- myoption2: y
- slot: myslot
- username: admin
- password: admin
- port: 3333
- type: ipmilan
-
-
-# Remove ipmilan fence agent with address 1.2.3.4 on host 'myhost'
-- ovirt_host_pm:
- state: absent
- name: myhost
- address: 1.2.3.4
- type: ipmilan
-'''
-
-RETURN = '''
-id:
- description: ID of the agent which is managed
- returned: On success if agent is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-agent:
- description: "Dictionary of all the agent attributes. Agent attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/agent."
- returned: On success if agent is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- ovirt_full_argument_spec,
- search_by_name,
-)
-
-
-class HostModule(BaseModule):
- def build_entity(self):
- return otypes.Host(
- power_management=otypes.PowerManagement(
- enabled=True,
- ),
- )
-
- def update_check(self, entity):
- return equal(True, entity.power_management.enabled)
-
-
-class HostPmModule(BaseModule):
-
- def pre_create(self, entity):
- # Save the entity, so we know if Agent already existed
- self.entity = entity
-
- def build_entity(self):
- last = next((s for s in sorted([a.order for a in self._service.list()])), 0)
- order = self.param('order') if self.param('order') is not None else self.entity.order if self.entity else last + 1
- return otypes.Agent(
- address=self._module.params['address'],
- encrypt_options=self._module.params['encrypt_options'],
- options=[
- otypes.Option(
- name=name,
- value=value,
- ) for name, value in self._module.params['options'].items()
- ] if self._module.params['options'] else None,
- password=self._module.params['password'],
- port=self._module.params['port'],
- type=self._module.params['type'],
- username=self._module.params['username'],
- order=order,
- )
-
- def update_check(self, entity):
- def check_options():
- if self.param('options'):
- current = []
- if entity.options:
- current = [(opt.name, str(opt.value)) for opt in entity.options]
- passed = [(k, str(v)) for k, v in self.param('options').items()]
- return sorted(current) == sorted(passed)
- return True
-
- return (
- check_options() and
- equal(self._module.params.get('address'), entity.address) and
- equal(self._module.params.get('encrypt_options'), entity.encrypt_options) and
- equal(self._module.params.get('username'), entity.username) and
- equal(self._module.params.get('port'), entity.port) and
- equal(self._module.params.get('type'), entity.type) and
- equal(self._module.params.get('order'), entity.order)
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(default=None, required=True, aliases=['host']),
- address=dict(default=None),
- username=dict(default=None),
- password=dict(default=None, no_log=True),
- type=dict(default=None),
- port=dict(default=None, type='int'),
- order=dict(default=None, type='int'),
- options=dict(default=None, type='dict'),
- encrypt_options=dict(default=None, type='bool', aliases=['encrypt']),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- hosts_service = connection.system_service().hosts_service()
- host = search_by_name(hosts_service, module.params['name'])
- fence_agents_service = hosts_service.host_service(host.id).fence_agents_service()
-
- host_pm_module = HostPmModule(
- connection=connection,
- module=module,
- service=fence_agents_service,
- )
- host_module = HostModule(
- connection=connection,
- module=module,
- service=hosts_service,
- )
-
- state = module.params['state']
- if state == 'present':
- agent = host_pm_module.search_entity(
- search_params={
- 'address': module.params['address'],
- 'type': module.params['type'],
- }
- )
- ret = host_pm_module.create(entity=agent)
-
- # Enable Power Management, if it's not enabled:
- host_module.create(entity=host)
- elif state == 'absent':
- agent = host_pm_module.search_entity(
- search_params={
- 'address': module.params['address'],
- 'type': module.params['type'],
- }
- )
- ret = host_pm_module.remove(entity=agent)
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py
deleted file mode 100644
index 7eecafb4b1..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_host_storage_info
-short_description: Retrieve information about one or more oVirt/RHV HostStorages (applicable only for block storage)
-author: "Daniel Erez (@derez)"
-version_added: "2.4"
-description:
- - "Retrieve information about one or more oVirt/RHV HostStorages (applicable only for block storage)."
- - This module was called C(ovirt_host_storage_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_host_storage_info) module no longer returns C(ansible_facts)!
-options:
- host:
- description:
- - "Host to get device list from."
- required: true
- iscsi:
- description:
- - "Dictionary with values for iSCSI storage type:"
- suboptions:
- address:
- description:
- - "Address of the iSCSI storage server."
- target:
- description:
- - "The target IQN for the storage device."
- username:
- description:
- - "A CHAP user name for logging into a target."
- password:
- description:
- - "A CHAP password for logging into a target."
- portal:
- description:
- - "The portal being used to connect with iscsi."
- version_added: 2.10
- fcp:
- description:
- - "Dictionary with values for fibre channel storage type:"
- suboptions:
- address:
- description:
- - "Address of the fibre channel storage server."
- port:
- description:
- - "Port of the fibre channel storage server."
- lun_id:
- description:
- - "LUN id."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about HostStorages with specified target and address:
-- ovirt_host_storage_info:
- host: myhost
- iscsi:
- target: iqn.2016-08-09.domain-01:nickname
- address: 10.34.63.204
- register: result
-- debug:
- msg: "{{ result.ovirt_host_storages }}"
-'''
-
-RETURN = '''
-ovirt_host_storages:
- description: "List of dictionaries describing the HostStorage. HostStorage attributes are mapped to dictionary keys,
- all HostStorage attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/host_storage."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- get_id_by_name,
-)
-
-
-def _login(host_service, iscsi):
- host_service.iscsi_login(
- iscsi=otypes.IscsiDetails(
- username=iscsi.get('username'),
- password=iscsi.get('password'),
- address=iscsi.get('address'),
- target=iscsi.get('target'),
- portal=iscsi.get('portal')
- ),
- )
-
-
-def _get_storage_type(params):
- for sd_type in ['iscsi', 'fcp']:
- if params.get(sd_type) is not None:
- return sd_type
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- host=dict(required=True),
- iscsi=dict(default=None, type='dict'),
- fcp=dict(default=None, type='dict'),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_host_storage_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_host_storage_facts' module has been renamed to 'ovirt_host_storage_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
-
- # Get Host
- hosts_service = connection.system_service().hosts_service()
- host_id = get_id_by_name(hosts_service, module.params['host'])
- storage_type = _get_storage_type(module.params)
- host_service = hosts_service.host_service(host_id)
-
- if storage_type == 'iscsi':
- # Login
- iscsi = module.params.get('iscsi')
- _login(host_service, iscsi)
-
- # Get LUNs exposed from the specified target
- host_storages = host_service.storage_service().list()
-
- if storage_type == 'iscsi':
- filterred_host_storages = [host_storage for host_storage in host_storages
- if host_storage.type == otypes.StorageType.ISCSI]
- if 'target' in iscsi:
- filterred_host_storages = [host_storage for host_storage in filterred_host_storages
- if iscsi.get('target') == host_storage.logical_units[0].target]
- elif storage_type == 'fcp':
- filterred_host_storages = [host_storage for host_storage in host_storages
- if host_storage.type == otypes.StorageType.FCP]
-
- result = dict(
- ovirt_host_storages=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in filterred_host_storages
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py b/lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py
deleted file mode 100644
index 63e0471c17..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py
+++ /dev/null
@@ -1,592 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2017, Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_instance_type
-short_description: Module to manage Instance Types in oVirt/RHV
-version_added: "2.8"
-author:
-- Martin Necas (@mnecas)
-- Ondra Machacek (@machacekondra)
-description:
- - This module manages whole lifecycle of the Instance Type in oVirt/RHV.
-options:
- name:
- description:
- - Name of the Instance Type to manage.
- - If instance type don't exists C(name) is required. Otherwise C(id) or C(name) can be used.
- id:
- description:
- - ID of the Instance Type to manage.
- state:
- description:
- - Should the Instance Type be present/absent.
- - I(present) state will create/update instance type and don't change its state if it already exists.
- choices: [ absent, present ]
- default: present
- memory:
- description:
- - Amount of memory of the Instance Type. 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 Instance Type.
- 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.
- 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 instance type in more depth please use M(ovirt_nic) module instead.
- memory_max:
- description:
- - Upper bound of instance type 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.
- cpu_cores:
- description:
- - Number of virtual CPUs cores of the Instance Type.
- - Default value is set by oVirt/RHV engine.
- cpu_sockets:
- description:
- - Number of virtual CPUs sockets of the Instance Type.
- - Default value is set by oVirt/RHV engine.
- cpu_threads:
- description:
- - Number of virtual CPUs sockets of the Instance Type.
- - Default value is set by oVirt/RHV engine.
- operating_system:
- description:
- - Operating system of the Instance Type.
- - Default value is set by oVirt/RHV engine.
- - "Possible values: debian_7, freebsd, freebsdx64, other, other_linux,
- other_linux_ppc64, other_ppc64, rhel_3, rhel_4, rhel_4x64, rhel_5, rhel_5x64,
- rhel_6, rhel_6x64, rhel_6_ppc64, rhel_7x64, rhel_7_ppc64, sles_11, sles_11_ppc64,
- ubuntu_12_04, ubuntu_12_10, ubuntu_13_04, ubuntu_13_10, ubuntu_14_04, ubuntu_14_04_ppc64,
- windows_10, windows_10x64, windows_2003, windows_2003x64, windows_2008, windows_2008x64,
- windows_2008r2x64, windows_2008R2x64, windows_2012x64, windows_2012R2x64, windows_7,
- windows_7x64, windows_8, windows_8x64, windows_xp"
- boot_devices:
- description:
- - List of boot devices which should be used to boot. For example C([ cdrom, hd ]).
- - Default value is set by oVirt/RHV engine.
- choices: [ cdrom, hd, network ]
- serial_console:
- description:
- - "I(True) enable VirtIO serial console, I(False) to disable it. By default is chosen by oVirt/RHV engine."
- type: bool
- usb_support:
- description:
- - "I(True) enable USB support, I(False) to disable it. By default is chosen by oVirt/RHV engine."
- type: bool
- high_availability:
- description:
- - If I(yes) Instance Type will be set as highly available.
- - If I(no) Instance Type won't be set as highly available.
- - If no value is passed, default value is set by oVirt/RHV engine.
- type: bool
- high_availability_priority:
- description:
- - Indicates the priority of the instance type inside the run and migration queues.
- Instance Type with higher priorities will be started and migrated before instance types with lower
- priorities. The value is an integer between 0 and 100. The higher the value, the higher the priority.
- - If no value is passed, default value is set by oVirt/RHV engine.
- watchdog:
- description:
- - "Assign watchdog device for the instance type."
- - "Watchdogs is a dictionary which can have following values:"
- - "C(model) - Model of the watchdog device. For example: I(i6300esb), I(diag288) or I(null)."
- - "C(action) - Watchdog action to be performed when watchdog is triggered. For example: I(none), I(reset), I(poweroff), I(pause) or I(dump)."
- host:
- description:
- - Specify host where Instance Type should be running. By default the host is chosen by engine scheduler.
- - This parameter is used only when C(state) is I(running) or I(present).
- graphical_console:
- description:
- - "Assign graphical console to the instance type."
- - "Graphical console is a dictionary which can have following values:"
- - "C(headless_mode) - If I(true) disable the graphics console for this instance type."
- - "C(protocol) - Graphical protocol, a list of I(spice), I(vnc), or both."
- description:
- description:
- - "Description of the instance type."
- cpu_mode:
- description:
- - "CPU mode of the instance type. It can be some of the following: I(host_passthrough), I(host_model) or I(custom)."
- - "For I(host_passthrough) CPU type you need to set C(placement_policy) to I(pinned)."
- - "If no value is passed, default value is set by oVirt/RHV engine."
- rng_device:
- description:
- - "Random number generator (RNG). You can choose of one the following devices I(urandom), I(random) or I(hwrng)."
- - "In order to select I(hwrng), you must have it enabled on cluster first."
- - "/dev/urandom is used for cluster version >= 4.1, and /dev/random for cluster version <= 4.0"
- rng_bytes:
- description:
- - "Number of bytes allowed to consume per period."
- rng_period:
- description:
- - "Duration of one period in milliseconds."
- placement_policy:
- description:
- - "The configuration of the instance type's placement policy."
- - "Placement policy can be one of the following values:"
- - "C(migratable) - Allow manual and automatic migration."
- - "C(pinned) - Do not allow migration."
- - "C(user_migratable) - Allow manual migration only."
- - "If no value is passed, default value is set by oVirt/RHV engine."
- cpu_pinning:
- description:
- - "CPU Pinning topology to map instance type CPU to host CPU."
- - "CPU Pinning topology is a list of dictionary which can have following values:"
- - "C(cpu) - Number of the host CPU."
- - "C(vcpu) - Number of the instance type CPU."
- soundcard_enabled:
- description:
- - "If I(true), the sound card is added to the instance type."
- type: bool
- smartcard_enabled:
- description:
- - "If I(true), use smart card authentication."
- type: bool
- virtio_scsi:
- description:
- - "If I(true), virtio scsi will be enabled."
- type: bool
- io_threads:
- description:
- - "Number of IO threads used by instance type. I(0) means IO threading disabled."
- ballooning_enabled:
- description:
- - "If I(true), use memory ballooning."
- - "Memory balloon is a guest device, which may be used to re-distribute / reclaim the host memory
- based on instance type needs in a dynamic way. In this way it's possible to create memory over commitment states."
- type: bool
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create instance type
-- name: Create instance type
- ovirt_instance_type:
- state: present
- name: myit
- rng_device: hwrng
- rng_bytes: 200
- rng_period: 200
- soundcard_enabled: true
- virtio_scsi: true
- boot_devices:
- - network
-
-# Remove instance type
-- ovirt_instance_type:
- state: absent
- name: myit
-
-
-# Create instance type with predefined memory and cpu limits.
-- ovirt_instance_type:
- state: present
- name: myit
- memory: 2GiB
- cpu_cores: 2
- cpu_sockets: 2
- nics:
- - name: nic1
-
-# Enable usb support and serial console
-- ovirt_instance_type:
- name: myit
- usb_support: True
- serial_console: True
-
-# Use graphical console with spice and vnc
-- name: Create a instance type that has the console configured for both Spice and VNC
- ovirt_instance_type:
- name: myit
- graphical_console:
- protocol:
- - spice
- - vnc
-'''
-
-
-RETURN = '''
-
-id:
- description: ID of the instance type which is managed
- returned: On success if instance type is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-instancetype:
- description: "Dictionary of all the instance type attributes. instance type attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/instance_type."
- returned: On success if instance type is found.
- type: dict
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-import traceback
-
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_params,
- check_sdk,
- convert_to_bytes,
- create_connection,
- equal,
- get_dict_of_struct,
- get_entity,
- get_link_name,
- get_id_by_name,
- ovirt_full_argument_spec,
- search_by_attributes,
- search_by_name,
- wait,
-)
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-
-class InstanceTypeModule(BaseModule):
- def build_entity(self):
- return otypes.InstanceType(
- id=self.param('id'),
- name=self.param('name'),
- console=(
- otypes.Console(enabled=self.param('serial_console'))
- ) if self.param('serial_console') is not None else None,
- usb=(
- otypes.Usb(enabled=self.param('usb_support'))
- ) if self.param('usb_support') is not None else None,
- high_availability=otypes.HighAvailability(
- enabled=self.param('high_availability'),
- priority=self.param('high_availability_priority'),
- ) if self.param('high_availability') is not None or self.param('high_availability_priority') else None,
- cpu=otypes.Cpu(
- topology=otypes.CpuTopology(
- cores=self.param('cpu_cores'),
- sockets=self.param('cpu_sockets'),
- threads=self.param('cpu_threads'),
- ) if any((
- self.param('cpu_cores'),
- self.param('cpu_sockets'),
- self.param('cpu_threads')
- )) else None,
- cpu_tune=otypes.CpuTune(
- vcpu_pins=[
- otypes.VcpuPin(vcpu=int(pin['vcpu']), cpu_set=str(pin['cpu'])) for pin in self.param('cpu_pinning')
- ],
- ) if self.param('cpu_pinning') else None,
- mode=otypes.CpuMode(self.param('cpu_mode')) if self.param(
- 'cpu_mode') else None,
- ) if any((
- self.param('cpu_cores'),
- self.param('cpu_sockets'),
- self.param('cpu_threads'),
- self.param('cpu_mode'),
- self.param('cpu_pinning')
- )) else None,
- os=otypes.OperatingSystem(
- type=self.param('operating_system'),
- boot=otypes.Boot(
- devices=[
- otypes.BootDevice(dev) for dev in self.param('boot_devices')
- ],
- ) if self.param('boot_devices') else None
- ),
- rng_device=otypes.RngDevice(
- source=otypes.RngSource(self.param('rng_device')),
- rate=otypes.Rate(
- bytes=self.param('rng_bytes'),
- period=self.param('rng_period')
- )
- ) if self.param('rng_device') else None,
- memory=convert_to_bytes(
- self.param('memory')
- ) if self.param('memory') else None,
- virtio_scsi=otypes.VirtioScsi(
- enabled=self.param('virtio_scsi')
- ) if self.param('virtio_scsi') else None,
- memory_policy=otypes.MemoryPolicy(
- guaranteed=convert_to_bytes(self.param('memory_guaranteed')),
- ballooning=self.param('ballooning_enabled'),
- max=convert_to_bytes(self.param('memory_max')),
- ) if any((
- self.param('memory_guaranteed'),
- self.param('ballooning_enabled') is not None,
- self.param('memory_max')
- )) else None,
- description=self.param('description'),
- placement_policy=otypes.VmPlacementPolicy(
- affinity=otypes.VmAffinity(self.param('placement_policy')),
- hosts=[
- otypes.Host(name=self.param('host')),
- ] if self.param('host') else None,
- ) if self.param('placement_policy') else None,
- soundcard_enabled=self.param('soundcard_enabled'),
- display=otypes.Display(
- smartcard_enabled=self.param('smartcard_enabled')
- ) if self.param('smartcard_enabled') is not None else None,
- io=otypes.Io(
- threads=self.param('io_threads'),
- ) if self.param('io_threads') is not None else None,
- )
-
- def __attach_watchdog(self, entity):
- watchdogs_service = self._service.service(entity.id).watchdogs_service()
- watchdog = self.param('watchdog')
- if watchdog is not None:
- current_watchdog = next(iter(watchdogs_service.list()), None)
- if watchdog.get('model') is None and current_watchdog:
- watchdogs_service.watchdog_service(current_watchdog.id).remove()
- return True
- elif watchdog.get('model') is not None and current_watchdog is None:
- watchdogs_service.add(
- otypes.Watchdog(
- model=otypes.WatchdogModel(watchdog.get('model').lower()),
- action=otypes.WatchdogAction(watchdog.get('action')),
- )
- )
- return True
- elif current_watchdog is not None:
- if (
- str(current_watchdog.model).lower() != watchdog.get('model').lower() or
- str(current_watchdog.action).lower() != watchdog.get('action').lower()
- ):
- watchdogs_service.watchdog_service(current_watchdog.id).update(
- otypes.Watchdog(
- model=otypes.WatchdogModel(watchdog.get('model')),
- action=otypes.WatchdogAction(watchdog.get('action')),
- )
- )
- return True
- return False
-
- 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 __attach_nics(self, entity):
- # Attach NICs to instance type, if specified:
- nics_service = self._service.service(entity.id).nics_service()
- for nic in self.param('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 __attach_graphical_console(self, entity):
- graphical_console = self.param('graphical_console')
- if not graphical_console:
- return False
-
- it_service = self._service.instance_type_service(entity.id)
- gcs_service = it_service.graphics_consoles_service()
- graphical_consoles = gcs_service.list()
- # Remove all graphical consoles if there are any:
- if bool(graphical_console.get('headless_mode')):
- if not self._module.check_mode:
- for gc in graphical_consoles:
- gcs_service.console_service(gc.id).remove()
- return len(graphical_consoles) > 0
-
- # If there are not gc add any gc to be added:
- protocol = graphical_console.get('protocol')
- if isinstance(protocol, str):
- protocol = [protocol]
-
- current_protocols = [str(gc.protocol) for gc in graphical_consoles]
- if not current_protocols:
- if not self._module.check_mode:
- for p in protocol:
- gcs_service.add(
- otypes.GraphicsConsole(
- protocol=otypes.GraphicsType(p),
- )
- )
- return True
-
- # Update consoles:
- if sorted(protocol) != sorted(current_protocols):
- if not self._module.check_mode:
- for gc in graphical_consoles:
- gcs_service.console_service(gc.id).remove()
- for p in protocol:
- gcs_service.add(
- otypes.GraphicsConsole(
- protocol=otypes.GraphicsType(p),
- )
- )
- return True
-
- def post_update(self, entity):
- self.post_present(entity.id)
-
- def post_present(self, entity_id):
- entity = self._service.service(entity_id).get()
- self.changed = self.__attach_nics(entity)
- self.changed = self.__attach_watchdog(entity)
- self.changed = self.__attach_graphical_console(entity)
-
- def update_check(self, entity):
- cpu_mode = getattr(entity.cpu, 'mode')
- it_display = entity.display
- return (
- not self.param('kernel_params_persist') and
- equal(convert_to_bytes(self.param('memory_guaranteed')), entity.memory_policy.guaranteed) and
- equal(convert_to_bytes(self.param('memory_max')), entity.memory_policy.max) and
- equal(self.param('cpu_cores'), entity.cpu.topology.cores) and
- equal(self.param('cpu_sockets'), entity.cpu.topology.sockets) and
- equal(self.param('cpu_threads'), entity.cpu.topology.threads) and
- equal(self.param('cpu_mode'), str(cpu_mode) if cpu_mode else None) and
- equal(self.param('type'), str(entity.type)) and
- equal(self.param('name'), str(entity.name)) and
- equal(self.param('operating_system'), str(entity.os.type)) and
- equal(self.param('soundcard_enabled'), entity.soundcard_enabled) and
- equal(self.param('smartcard_enabled'), getattr(it_display, 'smartcard_enabled', False)) and
- equal(self.param('io_threads'), entity.io.threads) and
- equal(self.param('ballooning_enabled'), entity.memory_policy.ballooning) and
- equal(self.param('serial_console'), getattr(entity.console, 'enabled', None)) and
- equal(self.param('usb_support'), entity.usb.enabled) and
- equal(self.param('virtio_scsi'), getattr(entity, 'smartcard_enabled', False)) and
- equal(self.param('high_availability'), entity.high_availability.enabled) and
- equal(self.param('high_availability_priority'), entity.high_availability.priority) and
- equal(self.param('boot_devices'), [str(dev) for dev in getattr(entity.os.boot, 'devices', [])]) and
- equal(self.param('description'), entity.description) and
- equal(self.param('rng_device'), str(entity.rng_device.source) if entity.rng_device else None) and
- equal(self.param('rng_bytes'), entity.rng_device.rate.bytes if entity.rng_device else None) and
- equal(self.param('rng_period'), entity.rng_device.rate.period if entity.rng_device else None) and
- equal(self.param('placement_policy'), str(entity.placement_policy.affinity) if entity.placement_policy else None)
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(type='str', default='present',
- choices=['absent', 'present']),
- name=dict(type='str'),
- id=dict(type='str'),
- memory=dict(type='str'),
- memory_guaranteed=dict(type='str'),
- memory_max=dict(type='str'),
- cpu_sockets=dict(type='int'),
- cpu_cores=dict(type='int'),
- cpu_threads=dict(type='int'),
- operating_system=dict(type='str'),
- boot_devices=dict(type='list', choices=['cdrom', 'hd', 'network']),
- serial_console=dict(type='bool'),
- usb_support=dict(type='bool'),
- high_availability=dict(type='bool'),
- high_availability_priority=dict(type='int'),
- watchdog=dict(type='dict'),
- host=dict(type='str'),
- graphical_console=dict(type='dict'),
- description=dict(type='str'),
- cpu_mode=dict(type='str'),
- rng_device=dict(type='str'),
- rng_bytes=dict(type='int', default=None),
- rng_period=dict(type='int', default=None),
- placement_policy=dict(type='str'),
- cpu_pinning=dict(type='list'),
- soundcard_enabled=dict(type='bool', default=None),
- virtio_scsi=dict(type='bool', default=None),
- smartcard_enabled=dict(type='bool', default=None),
- io_threads=dict(type='int', default=None),
- nics=dict(type='list', default=[]),
- ballooning_enabled=dict(type='bool', default=None),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_one_of=[['id', 'name']],
- )
-
- check_sdk(module)
- check_params(module)
-
- try:
- state = module.params['state']
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- its_service = connection.system_service().instance_types_service()
- its_module = InstanceTypeModule(
- connection=connection,
- module=module,
- service=its_service,
- )
- it = its_module.search_entity()
-
- if state == 'present':
- ret = its_module.create(
- entity=it
- )
- its_module.post_present(ret['id'])
- ret['changed'] = its_module.changed
- elif state == 'absent':
- ret = its_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_job.py b/lib/ansible/modules/cloud/ovirt/ovirt_job.py
deleted file mode 100644
index 7b6c595ee3..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_job.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_job
-short_description: Module to manage jobs in oVirt/RHV
-version_added: "2.9"
-author: "Martin Necas (@mnecas)"
-description:
- - "This module manage jobs in oVirt/RHV. It can also manage steps of the job."
-options:
- description:
- description:
- - "Description of the job."
- - "When task with same description has already finished and you rerun taks it will create new job."
- required: true
- state:
- description:
- - "Should the job be C(present)/C(absent)/C(failed)."
- - "C(started) is alias for C(present). C(finished) is alias for C(absent). Same in the steps."
- - "Note when C(finished)/C(failed) it will finish/fail all steps."
- choices: ['present', 'absent', 'started', 'finished', 'failed']
- default: present
- steps:
- description:
- - "The steps of the job."
- suboptions:
- description:
- description:
- - "Description of the step."
- required: true
- state:
- description:
- - "Should the step be present/absent/failed."
- - "Note when one step fail whole job will fail"
- - "Note when all steps are finished it will finish job."
- choices: ['present', 'absent', 'started', 'finished', 'failed']
- default: present
- type: list
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-- name: Create job with two steps
- ovirt_job:
- description: job_name
- steps:
- - description: step_name_A
- - description: step_name_B
-
-- name: Finish one step
- ovirt_job:
- description: job_name
- steps:
- - description: step_name_A
- state: finished
-
-- name: When you fail one step whole job will stop
- ovirt_job:
- description: job_name
- steps:
- - description: step_name_B
- state: failed
-
-- name: Finish all steps
- ovirt_job:
- description: job_name
- state: finished
-'''
-
-RETURN = '''
-id:
- description: ID of the job which is managed
- returned: On success if job is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-job:
- description: "Dictionary of all the job attributes. Job attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/job."
- returned: On success if job is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- equal,
- get_id_by_name,
- ovirt_full_argument_spec,
- get_dict_of_struct,
-)
-
-
-def build_job(description):
- return otypes.Job(
- description=description,
- status=otypes.JobStatus.STARTED,
- external=True,
- auto_cleared=True
- )
-
-
-def build_step(description, job_id):
- return otypes.Step(
- description=description,
- type=otypes.StepEnum.UNKNOWN,
- job=otypes.Job(
- id=job_id
- ),
- status=otypes.StepStatus.STARTED,
- external=True,
- )
-
-
-def attach_steps(module, job_id, jobs_service):
- changed = False
- steps_service = jobs_service.job_service(job_id).steps_service()
- if module.params.get('steps'):
- for step in module.params.get('steps'):
- step_entity = get_entity(steps_service, step.get('description'))
- step_state = step.get('state', 'present')
- if step_state in ['present', 'started']:
- if step_entity is None:
- steps_service.add(build_step(step.get('description'), job_id))
- changed = True
- if step_entity is not None and step_entity.status not in [otypes.StepStatus.FINISHED, otypes.StepStatus.FAILED]:
- if step_state in ['absent', 'finished']:
- steps_service.step_service(step_entity.id).end(succeeded=True)
- changed = True
- elif step_state == 'failed':
- steps_service.step_service(step_entity.id).end(succeeded=False)
- changed = True
- return changed
-
-
-def get_entity(service, description):
- all_entities = service.list()
- for entity in all_entities:
- if entity.description == description and entity.status not in [otypes.StepStatus.FINISHED, otypes.JobStatus.FINISHED]:
- return entity
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent', 'started', 'finished', 'failed'],
- default='present',
- ),
- description=dict(default=None),
- steps=dict(default=None, type='list'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=False,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- jobs_service = connection.system_service().jobs_service()
-
- state = module.params['state']
- job = get_entity(jobs_service, module.params['description'])
- changed = False
- if state in ['present', 'started']:
- if job is None or job.status in [otypes.JobStatus.FINISHED, otypes.JobStatus.FAILED]:
- job = jobs_service.add(build_job(module.params['description']))
- changed = True
- changed = attach_steps(module, job.id, jobs_service) or changed
-
- if job is not None and job.status not in [otypes.JobStatus.FINISHED, otypes.JobStatus.FAILED]:
- if state in ['absent', 'finished']:
- jobs_service.job_service(job.id).end(succeeded=True)
- changed = True
-
- elif state == 'failed':
- jobs_service.job_service(job.id).end(succeeded=False)
- changed = True
-
- ret = {
- 'changed': changed,
- 'id': getattr(job, 'id', None),
- 'job': get_dict_of_struct(
- struct=job,
- connection=connection,
- fetch_nested=True,
- attributes=module.params.get('nested_attributes'),
- ),
- }
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py b/lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py
deleted file mode 100644
index 7d9d2dbc09..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py
+++ /dev/null
@@ -1,181 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_mac_pool
-short_description: Module to manage MAC pools in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "This module manage MAC pools in oVirt/RHV."
-options:
- id:
- description:
- - "ID of the mac pool to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the MAC pool to manage."
- required: true
- description:
- description:
- - "Description of the MAC pool."
- state:
- description:
- - "Should the mac pool be present or absent."
- choices: ['present', 'absent']
- default: present
- allow_duplicates:
- description:
- - "If I(true) allow a MAC address to be used multiple times in a pool."
- - "Default value is set by oVirt/RHV engine to I(false)."
- type: bool
- ranges:
- description:
- - "List of MAC ranges. The from and to should be split by comma."
- - "For example: 00:1a:4a:16:01:51,00:1a:4a:16:01:61"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create MAC pool:
-- ovirt_mac_pool:
- name: mymacpool
- allow_duplicates: false
- ranges:
- - 00:1a:4a:16:01:51,00:1a:4a:16:01:61
- - 00:1a:4a:16:02:51,00:1a:4a:16:02:61
-
-# Remove MAC pool:
-- ovirt_mac_pool:
- state: absent
- name: mymacpool
-
-# Change MAC pool Name
-- ovirt_nic:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_mac_pool_name"
-'''
-
-RETURN = '''
-id:
- description: ID of the MAC pool which is managed
- returned: On success if MAC pool is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-template:
- description: "Dictionary of all the MAC pool attributes. MAC pool attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/mac_pool."
- returned: On success if MAC pool is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- equal,
- create_connection,
- ovirt_full_argument_spec,
-)
-
-
-class MACPoolModule(BaseModule):
-
- def build_entity(self):
- return otypes.MacPool(
- name=self._module.params['name'],
- id=self._module.params['id'],
- allow_duplicates=self._module.params['allow_duplicates'],
- description=self._module.params['description'],
- ranges=[
- otypes.Range(
- from_=mac_range.split(',')[0],
- to=mac_range.split(',')[1],
- )
- for mac_range in self._module.params['ranges']
- ] if self._module.params['ranges'] else None,
- )
-
- def _compare_ranges(self, entity):
- if self._module.params['ranges'] is not None:
- ranges = sorted([
- '%s,%s' % (mac_range.from_, mac_range.to)
- for mac_range in entity.ranges
- ])
- return equal(sorted(self._module.params['ranges']), ranges)
-
- return True
-
- def update_check(self, entity):
- return (
- self._compare_ranges(entity) and
- equal(self._module.params['allow_duplicates'], entity.allow_duplicates) and
- equal(self._module.params['description'], entity.description) and
- equal(self._module.params['name'], entity.name)
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(required=True),
- id=dict(default=None),
- allow_duplicates=dict(default=None, type='bool'),
- description=dict(default=None),
- ranges=dict(default=None, type='list'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- mac_pools_service = connection.system_service().mac_pools_service()
- mac_pools_module = MACPoolModule(
- connection=connection,
- module=module,
- service=mac_pools_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = mac_pools_module.create()
- elif state == 'absent':
- ret = mac_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_network.py b/lib/ansible/modules/cloud/ovirt/ovirt_network.py
deleted file mode 100644
index ba88c5a798..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_network.py
+++ /dev/null
@@ -1,360 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_network
-short_description: Module to manage logical networks in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage logical networks in oVirt/RHV"
-options:
- id:
- description:
- - "ID of the network to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the network to manage."
- required: true
- state:
- description:
- - "Should the network be present or absent"
- choices: ['present', 'absent']
- default: present
- data_center:
- description:
- - "Datacenter name where network reside."
- description:
- description:
- - "Description of the network."
- comment:
- description:
- - "Comment of the network."
- vlan_tag:
- description:
- - "Specify VLAN tag."
- external_provider:
- description:
- - "Name of external network provider."
- - "At first it tries to import the network when not found it will create network in external provider."
- version_added: 2.8
- vm_network:
- description:
- - "If I(True) network will be marked as network for VM."
- - "VM network carries traffic relevant to the virtual machine."
- type: bool
- mtu:
- description:
- - "Maximum transmission unit (MTU) of the network."
- clusters:
- description:
- - "List of dictionaries describing how the network is managed in specific cluster."
- suboptions:
- name:
- description:
- - Cluster name.
- assigned:
- description:
- - I(true) if the network should be assigned to cluster. Default is I(true).
- type: bool
- required:
- description:
- - I(true) if the network must remain operational for all hosts associated with this network.
- type: bool
- display:
- description:
- - I(true) if the network should marked as display network.
- type: bool
- migration:
- description:
- - I(true) if the network should marked as migration network.
- type: bool
- gluster:
- description:
- - I(true) if the network should marked as gluster network.
- type: bool
- label:
- description:
- - "Name of the label to assign to the network."
- version_added: "2.5"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create network
-- ovirt_network:
- data_center: mydatacenter
- name: mynetwork
- vlan_tag: 1
- vm_network: true
-
-# Remove network
-- ovirt_network:
- state: absent
- name: mynetwork
-
-# Change Network Name
-- ovirt_network:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_network_name"
- data_center: mydatacenter
-
-# Add network from external provider
-- ovirt_network:
- data_center: mydatacenter
- name: mynetwork
- external_provider: ovirt-provider-ovn
-'''
-
-RETURN = '''
-id:
- description: "ID of the managed network"
- returned: "On success if network is found."
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-network:
- description: "Dictionary of all the network attributes. Network attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/network."
- returned: "On success if network is found."
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_params,
- create_connection,
- equal,
- ovirt_full_argument_spec,
- search_by_name,
- get_id_by_name,
- get_dict_of_struct,
- get_entity
-)
-
-
-class NetworksModule(BaseModule):
- def build_entity(self):
- if self.param('external_provider'):
- ons_service = self._connection.system_service().openstack_network_providers_service()
- on_service = ons_service.provider_service(get_id_by_name(ons_service, self.param('external_provider')))
- return otypes.Network(
- name=self._module.params['name'],
- comment=self._module.params['comment'],
- description=self._module.params['description'],
- id=self._module.params['id'],
- data_center=otypes.DataCenter(
- name=self._module.params['data_center'],
- ) if self._module.params['data_center'] else None,
- vlan=otypes.Vlan(
- self._module.params['vlan_tag'],
- ) if self._module.params['vlan_tag'] else None,
- usages=[
- otypes.NetworkUsage.VM if self._module.params['vm_network'] else None
- ] if self._module.params['vm_network'] is not None else None,
- mtu=self._module.params['mtu'],
- external_provider=otypes.OpenStackNetworkProvider(id=on_service.get().id)
- if self.param('external_provider') else None,
- )
-
- def post_create(self, entity):
- self._update_label_assignments(entity)
-
- def _update_label_assignments(self, entity):
- if self.param('label') is None:
- return
-
- labels_service = self._service.service(entity.id).network_labels_service()
- labels = [lbl.id for lbl in labels_service.list()]
- if not self.param('label') in labels:
- if not self._module.check_mode:
- if labels:
- labels_service.label_service(labels[0]).remove()
- labels_service.add(
- label=otypes.NetworkLabel(id=self.param('label'))
- )
- self.changed = True
-
- def update_check(self, entity):
- self._update_label_assignments(entity)
- return (
- equal(self._module.params.get('comment'), entity.comment) and
- equal(self._module.params.get('name'), entity.name) and
- equal(self._module.params.get('description'), entity.description) and
- equal(self._module.params.get('vlan_tag'), getattr(entity.vlan, 'id', None)) and
- equal(self._module.params.get('vm_network'), True if entity.usages else False) and
- equal(self._module.params.get('mtu'), entity.mtu)
- )
-
-
-class ClusterNetworksModule(BaseModule):
-
- def __init__(self, network_id, cluster_network, *args, **kwargs):
- super(ClusterNetworksModule, self).__init__(*args, **kwargs)
- self._network_id = network_id
- self._cluster_network = cluster_network
- self._old_usages = []
- self._cluster_network_entity = get_entity(self._service.network_service(network_id))
- if self._cluster_network_entity is not None:
- self._old_usages = self._cluster_network_entity.usages
-
- def build_entity(self):
- return otypes.Network(
- id=self._network_id,
- name=self._module.params['name'],
- required=self._cluster_network.get('required'),
- display=self._cluster_network.get('display'),
- usages=list(set([
- otypes.NetworkUsage(usage)
- for usage in ['display', 'gluster', 'migration']
- if self._cluster_network.get(usage, False)
- ] + self._old_usages))
- if (
- self._cluster_network.get('display') is not None or
- self._cluster_network.get('gluster') is not None or
- self._cluster_network.get('migration') is not None
- ) else None,
- )
-
- def update_check(self, entity):
- return (
- equal(self._cluster_network.get('required'), entity.required) and
- equal(self._cluster_network.get('display'), entity.display) and
- all(
- x in [
- str(usage)
- for usage in getattr(entity, 'usages', [])
- # VM + MANAGEMENT is part of root network
- if usage != otypes.NetworkUsage.VM and usage != otypes.NetworkUsage.MANAGEMENT
- ]
- for x in [
- usage
- for usage in ['display', 'gluster', 'migration']
- if self._cluster_network.get(usage, False)
- ]
- )
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- data_center=dict(required=True),
- id=dict(default=None),
- name=dict(required=True),
- description=dict(default=None),
- comment=dict(default=None),
- external_provider=dict(default=None),
- vlan_tag=dict(default=None, type='int'),
- vm_network=dict(default=None, type='bool'),
- mtu=dict(default=None, type='int'),
- clusters=dict(default=None, type='list'),
- label=dict(default=None),
- )
- 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)
- clusters_service = connection.system_service().clusters_service()
- networks_service = connection.system_service().networks_service()
- networks_module = NetworksModule(
- connection=connection,
- module=module,
- service=networks_service,
- )
- state = module.params['state']
- search_params = {
- 'name': module.params['name'],
- 'datacenter': module.params['data_center'],
- }
- if state == 'present':
- imported = False
- if module.params.get('external_provider') and module.params.get('name') not in [net.name for net in networks_service.list()]:
- # Try to import network
- ons_service = connection.system_service().openstack_network_providers_service()
- on_service = ons_service.provider_service(get_id_by_name(ons_service, module.params.get('external_provider')))
- on_networks_service = on_service.networks_service()
- if module.params.get('name') in [net.name for net in on_networks_service.list()]:
- network_service = on_networks_service.network_service(get_id_by_name(on_networks_service, module.params.get('name')))
- network_service.import_(data_center=otypes.DataCenter(name=module.params.get('data_center')))
- imported = True
-
- ret = networks_module.create(search_params=search_params)
- ret['changed'] = ret['changed'] or imported
- # Update clusters networks:
- if module.params.get('clusters') is not None:
- for param_cluster in module.params.get('clusters'):
- cluster = search_by_name(clusters_service, param_cluster.get('name'))
- if cluster is None:
- raise Exception("Cluster '%s' was not found." % param_cluster.get('name'))
- cluster_networks_service = clusters_service.service(cluster.id).networks_service()
- cluster_networks_module = ClusterNetworksModule(
- network_id=ret['id'],
- cluster_network=param_cluster,
- connection=connection,
- module=module,
- service=cluster_networks_service,
- )
- if param_cluster.get('assigned', True):
- ret = cluster_networks_module.create()
- else:
- ret = cluster_networks_module.remove()
-
- elif state == 'absent':
- ret = networks_module.remove(search_params=search_params)
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_network_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_network_info.py
deleted file mode 100644
index cb65aa26e1..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_network_info.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_network_info
-short_description: Retrieve information about one or more oVirt/RHV networks
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV networks."
- - This module was called C(ovirt_network_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_network_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_networks), which
- contains a list of networks. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search network starting with string vlan1 use: name=vlan1*"
-extends_documentation_fragment: ovirt_info
-'''
-
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all networks which names start with C(vlan1):
-- ovirt_network_info:
- pattern: name=vlan1*
- register: result
-- debug:
- msg: "{{ result.ovirt_networks }}"
-'''
-
-
-RETURN = '''
-ovirt_networks:
- description: "List of dictionaries describing the networks. Network attributes are mapped to dictionary keys,
- all networks attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/network."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_network_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_network_facts' module has been renamed to 'ovirt_network_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- networks_service = connection.system_service().networks_service()
- networks = networks_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_networks=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in networks
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_nic.py b/lib/ansible/modules/cloud/ovirt/ovirt_nic.py
deleted file mode 100644
index 827009948e..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_nic.py
+++ /dev/null
@@ -1,318 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2017, Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_nic
-short_description: Module to manage network interfaces of Virtual Machines in oVirt/RHV
-version_added: "2.3"
-author:
-- Ondra Machacek (@machacekondra)
-description:
- - Module to manage network interfaces of Virtual Machines in oVirt/RHV.
-options:
- id:
- description:
- - "ID of the nic to manage."
- version_added: "2.8"
- name:
- description:
- - Name of the network interface to manage.
- required: true
- vm:
- description:
- - Name of the Virtual Machine to manage.
- - You must provide either C(vm) parameter or C(template) parameter.
- template:
- description:
- - Name of the template to manage.
- - You must provide either C(vm) parameter or C(template) parameter.
- version_added: "2.4"
- state:
- description:
- - Should the Virtual Machine NIC be present/absent/plugged/unplugged.
- choices: [ absent, plugged, present, unplugged ]
- default: present
- network:
- description:
- - Logical network to which the VM network interface should use,
- by default Empty network is used if network is not specified.
- profile:
- description:
- - Virtual network interface profile to be attached to VM network interface.
- - When not specified and network has only single profile it will be auto-selected, otherwise you must specify profile.
- interface:
- description:
- - "Type of the network interface. For example e1000, pci_passthrough, rtl8139, rtl8139_virtio, spapr_vlan or virtio."
- - "It's required parameter when creating the new NIC."
- mac_address:
- description:
- - Custom MAC address of the network interface, by default it's obtained from MAC pool.
- linked:
- description:
- - Defines if the NIC is linked to the virtual machine.
- type: bool
- version_added: "2.9"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-- name: Add NIC to VM
- ovirt_nic:
- state: present
- vm: myvm
- name: mynic
- interface: e1000
- mac_address: 00:1a:4a:16:01:56
- profile: ovirtmgmt
- network: ovirtmgmt
-
-- name: Plug NIC to VM
- ovirt_nic:
- state: plugged
- vm: myvm
- name: mynic
-
-- name: Unplug NIC from VM
- ovirt_nic:
- state: unplugged
- linked: false
- vm: myvm
- name: mynic
-
-- name: Add NIC to template
- ovirt_nic:
- auth: "{{ ovirt_auth }}"
- state: present
- template: my_template
- name: nic1
- interface: virtio
- profile: ovirtmgmt
- network: ovirtmgmt
-
-- name: Remove NIC from VM
- ovirt_nic:
- state: absent
- vm: myvm
- name: mynic
-
-# Change NIC Name
-- ovirt_nic:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_nic_name"
- vm: myvm
-'''
-
-RETURN = '''
-id:
- description: ID of the network interface which is managed
- returned: On success if network interface is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-nic:
- description: "Dictionary of all the network interface attributes. Network interface attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/nic."
- returned: On success if network interface is found.
- type: dict
-'''
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_link_name,
- ovirt_full_argument_spec,
- search_by_name,
-)
-
-
-class EntityNicsModule(BaseModule):
-
- def __init__(self, *args, **kwargs):
- super(EntityNicsModule, self).__init__(*args, **kwargs)
- self.vnic_id = None
-
- @property
- def vnic_id(self):
- return self._vnic_id
-
- @vnic_id.setter
- def vnic_id(self, vnic_id):
- self._vnic_id = vnic_id
-
- def build_entity(self):
- return otypes.Nic(
- id=self._module.params.get('id'),
- name=self._module.params.get('name'),
- interface=otypes.NicInterface(
- self._module.params.get('interface')
- ) if self._module.params.get('interface') else None,
- vnic_profile=otypes.VnicProfile(
- id=self.vnic_id,
- ) if self.vnic_id else None,
- mac=otypes.Mac(
- address=self._module.params.get('mac_address')
- ) if self._module.params.get('mac_address') else None,
- linked=self.param('linked') if self.param('linked') is not None else None,
- )
-
- def update_check(self, entity):
- if self._module.params.get('vm'):
- return (
- equal(self._module.params.get('interface'), str(entity.interface)) and
- equal(self._module.params.get('linked'), entity.linked) and
- equal(self._module.params.get('name'), str(entity.name)) and
- equal(self._module.params.get('profile'), get_link_name(self._connection, entity.vnic_profile)) and
- equal(self._module.params.get('mac_address'), entity.mac.address)
- )
- elif self._module.params.get('template'):
- return (
- equal(self._module.params.get('interface'), str(entity.interface)) and
- equal(self._module.params.get('linked'), entity.linked) and
- equal(self._module.params.get('name'), str(entity.name)) and
- equal(self._module.params.get('profile'), get_link_name(self._connection, entity.vnic_profile))
- )
-
-
-def get_vnics(networks_service, network, connection):
- resp = []
- vnic_services = connection.system_service().vnic_profiles_service()
- for vnic in vnic_services.list():
- if vnic.network.id == network.id:
- resp.append(vnic)
- return resp
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(type='str', default='present', choices=['absent', 'plugged', 'present', 'unplugged']),
- vm=dict(type='str'),
- id=dict(default=None),
- template=dict(type='str'),
- name=dict(type='str', required=True),
- interface=dict(type='str'),
- profile=dict(type='str'),
- network=dict(type='str'),
- mac_address=dict(type='str'),
- linked=dict(type='bool'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_one_of=[['vm', 'template']],
- )
-
- check_sdk(module)
-
- try:
- # Locate the service that manages the virtual machines and use it to
- # search for the NIC:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- entity_name = None
-
- if module.params.get('vm'):
- # Locate the VM, where we will manage NICs:
- entity_name = module.params.get('vm')
- collection_service = connection.system_service().vms_service()
- elif module.params.get('template'):
- entity_name = module.params.get('template')
- collection_service = connection.system_service().templates_service()
-
- # TODO: We have to modify the search_by_name function to accept raise_error=True/False,
- entity = search_by_name(collection_service, entity_name)
- if entity is None:
- raise Exception("Vm/Template '%s' was not found." % entity_name)
-
- service = collection_service.service(entity.id)
- cluster_id = entity.cluster
-
- nics_service = service.nics_service()
- entitynics_module = EntityNicsModule(
- connection=connection,
- module=module,
- service=nics_service,
- )
-
- # Find vNIC id of the network interface (if any):
- if module.params['network']:
- profile = module.params.get('profile')
- cluster_name = get_link_name(connection, cluster_id)
- dcs_service = connection.system_service().data_centers_service()
- dc = dcs_service.list(search='Clusters.name=%s' % cluster_name)[0]
- networks_service = dcs_service.service(dc.id).networks_service()
- network = next(
- (n for n in networks_service.list()
- if n.name == module.params['network']),
- None
- )
- if network is None:
- raise Exception(
- "Network '%s' was not found in datacenter '%s'." % (
- module.params['network'],
- dc.name
- )
- )
- if profile:
- for vnic in connection.system_service().vnic_profiles_service().list():
- if vnic.name == profile and vnic.network.id == network.id:
- entitynics_module.vnic_id = vnic.id
- else:
- # When not specified which vnic use ovirtmgmt/ovirtmgmt
- vnics = get_vnics(networks_service, network, connection)
- if len(vnics) == 1:
- entitynics_module.vnic_id = vnics[0].id
- else:
- raise Exception(
- "You didn't specify any vnic profile. "
- "Following vnic profiles are in system: '%s', please specify one of them" % ([vnic.name for vnic in vnics])
- )
- # Handle appropriate action:
- state = module.params['state']
- if state == 'present':
- ret = entitynics_module.create()
- elif state == 'absent':
- ret = entitynics_module.remove()
- elif state == 'plugged':
- entitynics_module.create()
- ret = entitynics_module.action(
- action='activate',
- action_condition=lambda nic: not nic.plugged,
- wait_condition=lambda nic: nic.plugged,
- )
- elif state == 'unplugged':
- entitynics_module.create()
- ret = entitynics_module.action(
- action='deactivate',
- action_condition=lambda nic: nic.plugged,
- wait_condition=lambda nic: not nic.plugged,
- )
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py
deleted file mode 100644
index 0b80020697..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_nic_info
-short_description: Retrieve information about one or more oVirt/RHV virtual machine network interfaces
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV virtual machine network interfaces."
- - This module was called C(ovirt_nic_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_nic_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_nics), which
- contains a list of NICs. You need to register the result with
- the I(register) keyword to use it."
-options:
- vm:
- description:
- - "Name of the VM where NIC is attached."
- required: true
- name:
- description:
- - "Name of the NIC, can be used as glob expression."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all NICs which names start with C(eth) for VM named C(centos7):
-- ovirt_nic_info:
- vm: centos7
- name: eth*
- register: result
-- debug:
- msg: "{{ result.ovirt_nics }}"
-'''
-
-RETURN = '''
-ovirt_nics:
- description: "List of dictionaries describing the network interfaces. NIC attributes are mapped to dictionary keys,
- all NICs attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/nic."
- returned: On success.
- type: list
-'''
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- search_by_name,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- vm=dict(required=True),
- name=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_nic_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_nic_facts' module has been renamed to 'ovirt_nic_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- vms_service = connection.system_service().vms_service()
- vm_name = module.params['vm']
- vm = search_by_name(vms_service, vm_name)
- if vm is None:
- raise Exception("VM '%s' was not found." % vm_name)
-
- nics_service = vms_service.service(vm.id).nics_service()
- if module.params['name']:
- nics = [
- e for e in nics_service.list()
- if fnmatch.fnmatch(e.name, module.params['name'])
- ]
- else:
- nics = nics_service.list()
-
- result = dict(
- ovirt_nics=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in nics
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_permission.py b/lib/ansible/modules/cloud/ovirt/ovirt_permission.py
deleted file mode 100644
index f494bdbb4f..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_permission.py
+++ /dev/null
@@ -1,320 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2017, Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_permission
-short_description: Module to manage permissions of users/groups in oVirt/RHV
-version_added: "2.3"
-author:
-- Ondra Machacek (@machacekondra)
-description:
- - Module to manage permissions of users/groups in oVirt/RHV.
-options:
- role:
- description:
- - Name of the role to be assigned to user/group on specific object.
- default: UserRole
- state:
- description:
- - Should the permission be present/absent.
- choices: [ absent, present ]
- default: present
- object_id:
- description:
- - ID of the object where the permissions should be managed.
- object_name:
- description:
- - Name of the object where the permissions should be managed.
- object_type:
- description:
- - The object where the permissions should be managed.
- choices:
- - cluster
- - cpu_profile
- - data_center
- - disk
- - disk_profile
- - host
- - network
- - storage_domain
- - system
- - template
- - vm
- - vm_pool
- - vnic_profile
- default: vm
- user_name:
- description:
- - Username of the user to manage. In most LDAPs it's I(uid) of the user,
- but in Active Directory you must specify I(UPN) of the user.
- - Note that if user does not exist in the system this module will fail,
- you should ensure the user exists by using M(ovirt_users) module.
- group_name:
- description:
- - Name of the group to manage.
- - Note that if group does not exist in the system this module will fail,
- you should ensure the group exists by using M(ovirt_groups) module.
- authz_name:
- description:
- - Authorization provider of the user/group.
- required: true
- aliases: [ domain ]
- namespace:
- description:
- - Namespace of the authorization provider, where user/group resides.
- quota_name:
- description:
- - Name of the quota to assign permission. Works only with C(object_type) I(data_center).
- version_added: "2.7"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-- name: Add user user1 from authorization provider example.com-authz
- ovirt_permission:
- user_name: user1
- authz_name: example.com-authz
- object_type: vm
- object_name: myvm
- role: UserVmManager
-
-- name: Remove permission from user
- ovirt_permission:
- state: absent
- user_name: user1
- authz_name: example.com-authz
- object_type: cluster
- object_name: mycluster
- role: ClusterAdmin
-
-- name: Assign QuotaConsumer role to user
- ovirt_permissions:
- state: present
- user_name: user1
- authz_name: example.com-authz
- object_type: data_center
- object_name: mydatacenter
- quota_name: myquota
- role: QuotaConsumer
-
-- name: Assign QuotaConsumer role to group
- ovirt_permissions:
- state: present
- group_name: group1
- authz_name: example.com-authz
- object_type: data_center
- object_name: mydatacenter
- quota_name: myquota
- role: QuotaConsumer
-'''
-
-RETURN = '''
-id:
- description: ID of the permission which is managed
- returned: On success if permission is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-permission:
- description: "Dictionary of all the permission attributes. Permission attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/permission."
- returned: On success if permission is found.
- type: dict
-'''
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- follow_link,
- get_link_name,
- ovirt_full_argument_spec,
- search_by_attributes,
- search_by_name,
- get_id_by_name
-)
-
-
-def _objects_service(connection, object_type):
- if object_type == 'system':
- return connection.system_service()
-
- return getattr(
- connection.system_service(),
- '%ss_service' % object_type,
- None,
- )()
-
-
-def _object_service(connection, module):
- object_type = module.params['object_type']
- objects_service = _objects_service(connection, object_type)
- if object_type == 'system':
- return objects_service
-
- object_id = module.params['object_id']
- if object_id is None:
- sdk_object = search_by_name(objects_service, module.params['object_name'])
- if sdk_object is None:
- raise Exception(
- "'%s' object '%s' was not found." % (
- module.params['object_type'],
- module.params['object_name']
- )
- )
- object_id = sdk_object.id
-
- object_service = objects_service.service(object_id)
- if module.params['quota_name'] and object_type == 'data_center':
- quotas_service = object_service.quotas_service()
- return quotas_service.quota_service(get_id_by_name(quotas_service, module.params['quota_name']))
- return object_service
-
-
-def _permission(module, permissions_service, connection):
- for permission in permissions_service.list():
- user = follow_link(connection, permission.user)
- if (
- equal(module.params['user_name'], user.principal if user else None) and
- equal(module.params['group_name'], get_link_name(connection, permission.group)) and
- equal(module.params['role'], get_link_name(connection, permission.role))
- ):
- return permission
-
-
-class PermissionsModule(BaseModule):
-
- def _user(self):
- user = search_by_attributes(
- self._connection.system_service().users_service(),
- usrname="{name}@{authz_name}".format(
- name=self._module.params['user_name'],
- authz_name=self._module.params['authz_name'],
- ),
- )
- if user is None:
- raise Exception("User '%s' was not found." % self._module.params['user_name'])
- return user
-
- def _group(self):
- groups = self._connection.system_service().groups_service().list(
- search="name={name}".format(
- name=self._module.params['group_name'],
- )
- )
-
- # If found more groups, filter them by namespace and authz name:
- # (filtering here, as oVirt/RHV backend doesn't support it)
- if len(groups) > 1:
- groups = [
- g for g in groups if (
- equal(self._module.params['namespace'], g.namespace) and
- equal(self._module.params['authz_name'], g.domain.name)
- )
- ]
- if not groups:
- raise Exception("Group '%s' was not found." % self._module.params['group_name'])
- return groups[0]
-
- def build_entity(self):
- entity = self._group() if self._module.params['group_name'] else self._user()
-
- return otypes.Permission(
- user=otypes.User(
- id=entity.id
- ) if self._module.params['user_name'] else None,
- group=otypes.Group(
- id=entity.id
- ) if self._module.params['group_name'] else None,
- role=otypes.Role(
- name=self._module.params['role']
- ),
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(type='str', default='present', choices=['absent', 'present']),
- role=dict(type='str', default='UserRole'),
- object_type=dict(type='str', default='vm',
- choices=[
- 'cluster',
- 'cpu_profile',
- 'data_center',
- 'disk',
- 'disk_profile',
- 'host',
- 'network',
- 'storage_domain',
- 'system',
- 'template',
- 'vm',
- 'vm_pool',
- 'vnic_profile',
- ]),
- authz_name=dict(type='str', required=True, aliases=['domain']),
- object_id=dict(type='str'),
- object_name=dict(type='str'),
- user_name=dict(type='str'),
- group_name=dict(type='str'),
- namespace=dict(type='str'),
- quota_name=dict(type='str'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- if (module.params['object_name'] is None and module.params['object_id'] is None) and module.params['object_type'] != 'system':
- module.fail_json(msg='"object_name" or "object_id" is required')
-
- if module.params['user_name'] is None and module.params['group_name'] is None:
- module.fail_json(msg='"user_name" or "group_name" is required')
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- permissions_service = _object_service(connection, module).permissions_service()
- permissions_module = PermissionsModule(
- connection=connection,
- module=module,
- service=permissions_service,
- )
-
- permission = _permission(module, permissions_service, connection)
- state = module.params['state']
- if state == 'present':
- ret = permissions_module.create(entity=permission)
- elif state == 'absent':
- ret = permissions_module.remove(entity=permission)
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py
deleted file mode 100644
index bec4621374..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_permission_info
-short_description: Retrieve information about one or more oVirt/RHV permissions
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV permissions."
- - This module was called C(ovirt_permission_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_permission_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_permissions), which
- contains a list of permissions. You need to register the result with
- the I(register) keyword to use it."
-options:
- user_name:
- description:
- - "Username of the user to manage. In most LDAPs it's I(uid) of the user, but in Active Directory you must specify I(UPN) of the user."
- group_name:
- description:
- - "Name of the group to manage."
- authz_name:
- description:
- - "Authorization provider of the user/group. In previous versions of oVirt/RHV known as domain."
- required: true
- aliases: ['domain']
- namespace:
- description:
- - "Namespace of the authorization provider, where user/group resides."
- required: false
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all permissions of user with username C(john):
-- ovirt_permission_info:
- user_name: john
- authz_name: example.com-authz
- register: result
-- debug:
- msg: "{{ result.ovirt_permissions }}"
-'''
-
-RETURN = '''
-ovirt_permissions:
- description: "List of dictionaries describing the permissions. Permission attributes are mapped to dictionary keys,
- all permissions attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/permission."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-try:
- import ovirtsdk4 as sdk
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_link_name,
- ovirt_info_full_argument_spec,
- search_by_name,
-)
-
-
-def _permissions_service(connection, module):
- if module.params['user_name']:
- service = connection.system_service().users_service()
- entity = next(
- iter(
- service.list(
- search='usrname={0}'.format(
- '{0}@{1}'.format(module.params['user_name'], module.params['authz_name'])
- )
- )
- ),
- None
- )
- else:
- service = connection.system_service().groups_service()
- entity = search_by_name(service, module.params['group_name'])
-
- if entity is None:
- raise Exception("User/Group wasn't found.")
-
- return service.service(entity.id).permissions_service()
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- authz_name=dict(required=True, aliases=['domain']),
- user_name=dict(default=None),
- group_name=dict(default=None),
- namespace=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_permission_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_permission_facts' module has been renamed to 'ovirt_permission_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- permissions_service = _permissions_service(connection, module)
- permissions = []
- for p in permissions_service.list():
- newperm = dict()
- for key, value in p.__dict__.items():
- if value and isinstance(value, sdk.Struct):
- newperm[key[1:]] = get_link_name(connection, value)
- newperm['%s_id' % key[1:]] = value.id
- permissions.append(newperm)
-
- result = dict(ovirt_permissions=permissions)
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_quota.py b/lib/ansible/modules/cloud/ovirt/ovirt_quota.py
deleted file mode 100644
index 8e61473789..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_quota.py
+++ /dev/null
@@ -1,319 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_quota
-short_description: Module to manage datacenter quotas in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage datacenter quotas in oVirt/RHV"
-options:
- id:
- description:
- - "ID of the quota to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the quota to manage."
- required: true
- state:
- description:
- - "Should the quota be present/absent."
- choices: ['present', 'absent']
- default: present
- data_center:
- description:
- - "Name of the datacenter where quota should be managed."
- required: true
- description:
- description:
- - "Description of the quota to manage."
- cluster_threshold:
- description:
- - "Cluster threshold(soft limit) defined in percentage (0-100)."
- aliases:
- - "cluster_soft_limit"
- cluster_grace:
- description:
- - "Cluster grace(hard limit) defined in percentage (1-100)."
- aliases:
- - "cluster_hard_limit"
- storage_threshold:
- description:
- - "Storage threshold(soft limit) defined in percentage (0-100)."
- aliases:
- - "storage_soft_limit"
- storage_grace:
- description:
- - "Storage grace(hard limit) defined in percentage (1-100)."
- aliases:
- - "storage_hard_limit"
- clusters:
- description:
- - "List of dictionary of cluster limits, which is valid to specific cluster."
- - "If cluster isn't specified it's valid to all clusters in system:"
- suboptions:
- cluster:
- description:
- - Name of the cluster.
- memory:
- description:
- - Memory limit (in GiB).
- cpu:
- description:
- - CPU limit.
- storages:
- description:
- - "List of dictionary of storage limits, which is valid to specific storage."
- - "If storage isn't specified it's valid to all storages in system:"
- suboptions:
- storage:
- description:
- - Name of the storage.
- size:
- description:
- - Size limit (in GiB).
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add cluster quota to cluster cluster1 with memory limit 20GiB and CPU limit to 10:
-- ovirt_quota:
- name: quota1
- data_center: dcX
- clusters:
- - name: cluster1
- memory: 20
- cpu: 10
-
-# Add cluster quota to all clusters with memory limit 30GiB and CPU limit to 15:
-- ovirt_quota:
- name: quota2
- data_center: dcX
- clusters:
- - memory: 30
- cpu: 15
-
-# Add storage quota to storage data1 with size limit to 100GiB
-- ovirt_quota:
- name: quota3
- data_center: dcX
- storage_grace: 40
- storage_threshold: 60
- storages:
- - name: data1
- size: 100
-
-# Remove quota quota1 (Note the quota must not be assigned to any VM/disk):
-- ovirt_quota:
- state: absent
- data_center: dcX
- name: quota1
-
-# Change Quota Name
-- ovirt_quota:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_quota_name"
- data_center: dcX
-'''
-
-RETURN = '''
-id:
- description: ID of the quota which is managed
- returned: On success if quota is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-quota:
- description: "Dictionary of all the quota attributes. Quota attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/quota."
- returned: On success if quota is found.
- type: dict
-'''
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_link_name,
- ovirt_full_argument_spec,
- search_by_name,
-)
-
-
-class QuotasModule(BaseModule):
-
- def build_entity(self):
- return otypes.Quota(
- description=self._module.params['description'],
- name=self._module.params['name'],
- id=self._module.params['id'],
- storage_hard_limit_pct=self._module.params.get('storage_grace'),
- storage_soft_limit_pct=self._module.params.get('storage_threshold'),
- cluster_hard_limit_pct=self._module.params.get('cluster_grace'),
- cluster_soft_limit_pct=self._module.params.get('cluster_threshold'),
- )
-
- def update_storage_limits(self, entity):
- new_limits = {}
- for storage in self._module.params.get('storages'):
- new_limits[storage.get('name', '')] = {
- 'size': storage.get('size'),
- }
-
- old_limits = {}
- sd_limit_service = self._service.service(entity.id).quota_storage_limits_service()
- for limit in sd_limit_service.list():
- storage = get_link_name(self._connection, limit.storage_domain) if limit.storage_domain else ''
- old_limits[storage] = {
- 'size': limit.limit,
- }
- sd_limit_service.service(limit.id).remove()
-
- return new_limits == old_limits
-
- def update_cluster_limits(self, entity):
- new_limits = {}
- for cluster in self._module.params.get('clusters'):
- new_limits[cluster.get('name', '')] = {
- 'cpu': cluster.get('cpu'),
- 'memory': float(cluster.get('memory')),
- }
-
- old_limits = {}
- cl_limit_service = self._service.service(entity.id).quota_cluster_limits_service()
- for limit in cl_limit_service.list():
- cluster = get_link_name(self._connection, limit.cluster) if limit.cluster else ''
- old_limits[cluster] = {
- 'cpu': limit.vcpu_limit,
- 'memory': limit.memory_limit,
- }
- cl_limit_service.service(limit.id).remove()
-
- return new_limits == old_limits
-
- def update_check(self, entity):
- # -- FIXME --
- # Note that we here always remove all cluster/storage limits, because
- # it's not currently possible to update them and then re-create the limits
- # appropriately, this shouldn't have any side-effects, but it's not considered
- # as a correct approach.
- # This feature is tracked here: https://bugzilla.redhat.com/show_bug.cgi?id=1398576
- #
-
- return (
- self.update_storage_limits(entity) and
- self.update_cluster_limits(entity) and
- equal(self._module.params.get('name'), entity.name) and
- equal(self._module.params.get('description'), entity.description) and
- equal(self._module.params.get('storage_grace'), entity.storage_hard_limit_pct) and
- equal(self._module.params.get('storage_threshold'), entity.storage_soft_limit_pct) and
- equal(self._module.params.get('cluster_grace'), entity.cluster_hard_limit_pct) and
- equal(self._module.params.get('cluster_threshold'), entity.cluster_soft_limit_pct)
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- id=dict(default=None),
- name=dict(required=True),
- data_center=dict(required=True),
- description=dict(default=None),
- cluster_threshold=dict(default=None, type='int', aliases=['cluster_soft_limit']),
- cluster_grace=dict(default=None, type='int', aliases=['cluster_hard_limit']),
- storage_threshold=dict(default=None, type='int', aliases=['storage_soft_limit']),
- storage_grace=dict(default=None, type='int', aliases=['storage_hard_limit']),
- clusters=dict(default=[], type='list'),
- storages=dict(default=[], type='list'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- datacenters_service = connection.system_service().data_centers_service()
- dc_name = module.params['data_center']
- dc_id = getattr(search_by_name(datacenters_service, dc_name), 'id', None)
- if dc_id is None:
- raise Exception("Datacenter '%s' was not found." % dc_name)
-
- quotas_service = datacenters_service.service(dc_id).quotas_service()
- quotas_module = QuotasModule(
- connection=connection,
- module=module,
- service=quotas_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = quotas_module.create()
-
- # Manage cluster limits:
- cl_limit_service = quotas_service.service(ret['id']).quota_cluster_limits_service()
- for cluster in module.params.get('clusters'):
- cl_limit_service.add(
- limit=otypes.QuotaClusterLimit(
- memory_limit=float(cluster.get('memory')),
- vcpu_limit=cluster.get('cpu'),
- cluster=search_by_name(
- connection.system_service().clusters_service(),
- cluster.get('name')
- ),
- ),
- )
-
- # Manage storage limits:
- sd_limit_service = quotas_service.service(ret['id']).quota_storage_limits_service()
- for storage in module.params.get('storages'):
- sd_limit_service.add(
- limit=otypes.QuotaStorageLimit(
- limit=storage.get('size'),
- storage_domain=search_by_name(
- connection.system_service().storage_domains_service(),
- storage.get('name')
- ),
- )
- )
-
- elif state == 'absent':
- ret = quotas_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py
deleted file mode 100644
index a1013ec67f..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_quota_info
-short_description: Retrieve information about one or more oVirt/RHV quotas
-version_added: "2.3"
-author: "Maor Lipchuk (@machacekondra)"
-description:
- - "Retrieve information about one or more oVirt/RHV quotas."
- - This module was called C(ovirt_quota_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_quota_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_quotas), which
- contains a list of quotas. You need to register the result with
- the I(register) keyword to use it."
-options:
- data_center:
- description:
- - "Name of the datacenter where quota resides."
- required: true
- name:
- description:
- - "Name of the quota, can be used as glob expression."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about quota named C<myquota> in Default datacenter:
-- ovirt_quota_info:
- data_center: Default
- name: myquota
- register: result
-- debug:
- msg: "{{ result.ovirt_quotas }}"
-'''
-
-RETURN = '''
-ovirt_quotas:
- description: "List of dictionaries describing the quotas. Quota attributes are mapped to dictionary keys,
- all quotas attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/quota."
- returned: On success.
- type: list
-'''
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- search_by_name,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- data_center=dict(required=True),
- name=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_quota_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_quota_facts' module has been renamed to 'ovirt_quota_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- datacenters_service = connection.system_service().data_centers_service()
- dc_name = module.params['data_center']
- dc = search_by_name(datacenters_service, dc_name)
- if dc is None:
- raise Exception("Datacenter '%s' was not found." % dc_name)
-
- quotas_service = datacenters_service.service(dc.id).quotas_service()
- if module.params['name']:
- quotas = [
- e for e in quotas_service.list()
- if fnmatch.fnmatch(e.name, module.params['name'])
- ]
- else:
- quotas = quotas_service.list()
-
- result = dict(
- ovirt_quotas=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in quotas
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_role.py b/lib/ansible/modules/cloud/ovirt/ovirt_role.py
deleted file mode 100644
index 9f1d94e79a..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_role.py
+++ /dev/null
@@ -1,190 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_role
-short_description: Module to manage roles in oVirt/RHV
-version_added: "2.8"
-author: "Martin Necas (@mnecas)"
-description:
- - "Module to manage roles in oVirt/RHV."
-options:
- name:
- description:
- - "Name of the role to manage."
- id:
- description:
- - "ID of the role to manage."
- description:
- description:
- - "Description of the role."
- state:
- description:
- - "Should the role be present/absent."
- choices: ['present', 'absent']
- default: present
- administrative:
- description:
- - "Defines the role as administrative-only or not."
- type: bool
- permits:
- description:
- - "List of permits which role will have"
- - "Permit 'login' is default and all roles will have it."
- - "List can contain name of permit."
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create administrative role with two permits
-- ovirt_role:
- name: role
- administrative: true
- permits:
- - manipulate_permissions
- - create_instance
-
-# Remove role
-- ovirt_role:
- name: role
- state: absent
-
-# Remove all permit
-- ovirt_role:
- name: role
- administrative: ture
- permits:
- - login
-'''
-
-RETURN = '''
-ovirt_role:
- description: "List of dictionaries describing the Roles. Role attributes are mapped to dictionary keys,
- all Roles attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/role."
- returned: On success.
- type: list
-'''
-
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- convert_to_bytes,
- create_connection,
- equal,
- get_dict_of_struct,
- get_link_name,
- get_id_by_name,
- ovirt_full_argument_spec,
- search_by_attributes,
- search_by_name,
-)
-from ansible.module_utils.basic import AnsibleModule
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-
-class RoleModule(BaseModule):
- def build_entity(self):
- if 'login' not in self.param('permits'):
- self.param('permits').append('login')
- all_permits = self.get_all_permits()
- return otypes.Role(
- id=self.param('id'),
- name=self.param('name'),
- administrative=self.param('administrative') if self.param(
- 'administrative') else None,
- permits=[
- otypes.Permit(id=all_permits.get(new_permit)) for new_permit in self.param('permits')
- ] if self.param('permits') else None,
- description=self.param('description') if self.param('administrative') else None,
- )
-
- def get_all_permits(self):
- return dict((permit.name, permit.id) for permit in self._connection.system_service().cluster_levels_service().level_service('4.3').get().permits)
-
- def update_check(self, entity):
- def check_permits():
- if self.param('permits'):
- if 'login' not in self.param('permits'):
- self.param('permits').append('login')
- permits_service = self._service.service(entity.id).permits_service()
- current = [er.name for er in permits_service.list()]
- passed = [pr for pr in self.param('permits')]
- if not sorted(current) == sorted(passed):
- if self._module.check_mode:
- return False
- # remove all
- for permit in permits_service.list():
- permits_service.permit_service(permit.id).remove()
- # add passed permits
- all_permits = self.get_all_permits()
- for new_permit in passed:
- permits_service.add(otypes.Permit(id=all_permits.get(new_permit)))
- return False
- return True
-
- return (
- check_permits() and
- equal(self.param('administrative'), entity.administrative) and
- equal(self.param('description'), entity.description)
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- id=dict(default=None),
- name=dict(default=None),
- description=dict(default=None),
- administrative=dict(type='bool', default=False),
- permits=dict(type='list', default=[]),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_one_of=[['id', 'name']],
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- roles_service = connection.system_service().roles_service()
- roles_module = RoleModule(
- connection=connection,
- module=module,
- service=roles_service,
- )
- state = module.params['state']
- if state == 'present':
- ret = roles_module.create()
- elif state == 'absent':
- ret = roles_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py
deleted file mode 100644
index f238a44be1..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017 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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_scheduling_policy_info
-short_description: Retrieve information about one or more oVirt scheduling policies
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.4"
-description:
- - "Retrieve information about one or more oVirt scheduling policies."
- - This module was called C(ovirt_scheduling_policy_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_scheduling_policy_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_scheduling_policies),
- which contains a list of scheduling policies. You need to register the result with
- the I(register) keyword to use it."
-options:
- id:
- description:
- - "ID of the scheduling policy."
- required: true
- name:
- description:
- - "Name of the scheduling policy, can be used as glob expression."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all scheduling policies with name InClusterUpgrade:
-- ovirt_scheduling_policy_info:
- name: InClusterUpgrade
- register: result
-- debug:
- msg: "{{ result.ovirt_scheduling_policies }}"
-'''
-
-RETURN = '''
-ovirt_scheduling_policies:
- description: "List of dictionaries describing the scheduling policies.
- Scheduling policies attributes are mapped to dictionary keys,
- all scheduling policies attributes can be found at following
- url: https://ovirt.example.com/ovirt-engine/api/model#types/scheduling_policy."
- returned: On success.
- type: list
-'''
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- id=dict(default=None),
- name=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_scheduling_policy_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_scheduling_policy_facts' module has been renamed to 'ovirt_scheduling_policy_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- system_service = connection.system_service()
- sched_policies_service = system_service.scheduling_policies_service()
- if module.params['name']:
- sched_policies = [
- e for e in sched_policies_service.list()
- if fnmatch.fnmatch(e.name, module.params['name'])
- ]
- elif module.params['id']:
- sched_policies = [
- sched_policies_service.service(module.params['id']).get()
- ]
- else:
- sched_policies = sched_policies_service.list()
-
- result = dict(
- ovirt_scheduling_policies=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in sched_policies
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py b/lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py
deleted file mode 100644
index 869fd84f45..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py
+++ /dev/null
@@ -1,551 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_snapshot
-short_description: "Module to manage Virtual Machine Snapshots in oVirt/RHV"
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage Virtual Machine Snapshots in oVirt/RHV"
-options:
- snapshot_id:
- description:
- - "ID of the snapshot to manage."
- vm_name:
- description:
- - "Name of the Virtual Machine to manage."
- required: true
- state:
- description:
- - "Should the Virtual Machine snapshot be restore/present/absent."
- choices: ['restore', 'present', 'absent']
- default: present
- description:
- description:
- - "Description of the snapshot."
- disk_id:
- description:
- - "Disk id which you want to upload or download"
- - "To get disk, you need to define disk_id or disk_name"
- version_added: "2.8"
- disk_name:
- description:
- - "Disk name which you want to upload or download"
- version_added: "2.8"
- download_image_path:
- description:
- - "Path on a file system where snapshot should be downloaded."
- - "Note that you must have an valid oVirt/RHV engine CA in your system trust store
- or you must provide it in C(ca_file) parameter."
- - "Note that the snapshot is not downloaded when the file already exists,
- but you can forcibly download the snapshot when using C(force) I (true)."
- version_added: "2.8"
- upload_image_path:
- description:
- - "Path to disk image, which should be uploaded."
- version_added: "2.8"
- use_memory:
- description:
- - "If I(true) and C(state) is I(present) save memory of the Virtual
- Machine if it's running."
- - "If I(true) and C(state) is I(restore) restore memory of the
- Virtual Machine."
- - "Note that Virtual Machine will be paused while saving the memory."
- aliases:
- - "restore_memory"
- - "save_memory"
- type: bool
- keep_days_old:
- description:
- - "Number of days after which should snapshot be deleted."
- - "It will check all snapshots of virtual machine and delete them, if they are older."
- version_added: "2.8"
- disks:
- description:
- - "List of disks which should be created with snapshot."
- suboptions:
- id:
- description:
- - "Id of the disk which should will be created."
- type: str
- name:
- description:
- - "Name of the disk which should will be created."
- type: str
- type: list
- version_added: "2.10"
-notes:
- - "Note that without a guest agent the data on the created snapshot may be
- inconsistent."
- - "Deleting a snapshot does not remove any information from the virtual
- machine - it simply removes a return-point. However, restoring a virtual
- machine from a snapshot deletes any content that was written to the
- virtual machine after the time the snapshot was taken."
-extends_documentation_fragment: ovirt
-'''
-
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create snapshot:
-- ovirt_snapshot:
- vm_name: rhel7
- description: MySnapshot
- register: snapshot
-
-# Create snapshot and save memory:
-- ovirt_snapshot:
- vm_name: rhel7
- description: SnapWithMem
- use_memory: true
- register: snapshot
-
-# Restore snapshot:
-- ovirt_snapshot:
- state: restore
- vm_name: rhel7
- snapshot_id: "{{ snapshot.id }}"
-
-# Remove snapshot:
-- ovirt_snapshot:
- state: absent
- vm_name: rhel7
- snapshot_id: "{{ snapshot.id }}"
-
-# Upload local image to disk and attach it to vm:
-# Since Ansible 2.8
-- ovirt_snapshot:
- name: mydisk
- vm_name: myvm
- upload_image_path: /path/to/mydisk.qcow2
-
-# Download snapshot to local file system:
-# Since Ansible 2.8
-- ovirt_snapshot:
- snapshot_id: 7de90f31-222c-436c-a1ca-7e655bd5b60c
- disk_name: DiskName
- vm_name: myvm
- download_image_path: /home/user/mysnaphost.qcow2
-
-# Delete all snapshots older than 2 days
-- ovirt_snapshot:
- vm_name: test
- keep_days_old: 2
-
-- name: Select which disks should be add to snapshot
- ovirt_snapshot:
- vm_name: test
- disks:
- - id: 7de90f31-222c-436c-a1ca-7e655bd5b60c
- - name: my_disk_name
-'''
-
-
-RETURN = '''
-id:
- description: ID of the snapshot which is managed
- returned: On success if snapshot is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-snapshot:
- description: "Dictionary of all the snapshot attributes. Snapshot attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/snapshot."
- returned: On success if snapshot is found.
- type: dict
-snapshots:
- description: List of deleted snapshots when keep_days_old is defined and snapshot is older than the input days
- returned: On success returns deleted snapshots
- type: list
-'''
-
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-
-import os
-import ssl
-import time
-
-from ansible.module_utils.six.moves.http_client import HTTPSConnection, IncompleteRead
-from ansible.module_utils.six.moves.urllib.parse import urlparse
-
-from datetime import datetime
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- get_entity,
- ovirt_full_argument_spec,
- search_by_name,
- wait,
- get_id_by_name,
- get_link_name
-)
-
-
-def transfer(connection, module, direction, transfer_func):
- transfers_service = connection.system_service().image_transfers_service()
- transfer = transfers_service.add(
- otypes.ImageTransfer(
- image=otypes.Image(
- id=module.params['disk_id'],
- ),
- direction=direction,
- )
- )
- transfer_service = transfers_service.image_transfer_service(transfer.id)
-
- try:
- # After adding a new transfer for the disk, the transfer's status will be INITIALIZING.
- # Wait until the init phase is over. The actual transfer can start when its status is "Transferring".
- while transfer.phase == otypes.ImageTransferPhase.INITIALIZING:
- time.sleep(module.params['poll_interval'])
- transfer = transfer_service.get()
-
- proxy_url = urlparse(transfer.proxy_url)
- context = ssl.create_default_context()
- auth = module.params['auth']
- if auth.get('insecure'):
- context.check_hostname = False
- context.verify_mode = ssl.CERT_NONE
- elif auth.get('ca_file'):
- context.load_verify_locations(cafile=auth.get('ca_file'))
-
- proxy_connection = HTTPSConnection(
- proxy_url.hostname,
- proxy_url.port,
- context=context,
- )
-
- transfer_func(
- transfer_service,
- proxy_connection,
- proxy_url,
- transfer.signed_ticket
- )
- return True
- finally:
- transfer_service.finalize()
- while transfer.phase in [
- otypes.ImageTransferPhase.TRANSFERRING,
- otypes.ImageTransferPhase.FINALIZING_SUCCESS,
- ]:
- time.sleep(module.params['poll_interval'])
- transfer = transfer_service.get()
- if transfer.phase in [
- otypes.ImageTransferPhase.UNKNOWN,
- otypes.ImageTransferPhase.FINISHED_FAILURE,
- otypes.ImageTransferPhase.FINALIZING_FAILURE,
- otypes.ImageTransferPhase.CANCELLED,
- ]:
- raise Exception(
- "Error occurred while uploading image. The transfer is in %s" % transfer.phase
- )
- if module.params.get('logical_unit'):
- disks_service = connection.system_service().disks_service()
- wait(
- service=disks_service.service(module.params['id']),
- condition=lambda d: d.status == otypes.DiskStatus.OK,
- wait=module.params['wait'],
- timeout=module.params['timeout'],
- )
-
-
-def upload_disk_image(connection, module):
- def _transfer(transfer_service, proxy_connection, proxy_url, transfer_ticket):
- BUF_SIZE = 128 * 1024
- path = module.params['upload_image_path']
-
- image_size = os.path.getsize(path)
- proxy_connection.putrequest("PUT", proxy_url.path)
- proxy_connection.putheader('Content-Length', "%d" % (image_size,))
- proxy_connection.endheaders()
- with open(path, "rb") as disk:
- pos = 0
- while pos < image_size:
- to_read = min(image_size - pos, BUF_SIZE)
- chunk = disk.read(to_read)
- if not chunk:
- transfer_service.pause()
- raise RuntimeError("Unexpected end of file at pos=%d" % pos)
- proxy_connection.send(chunk)
- pos += len(chunk)
-
- return transfer(
- connection,
- module,
- otypes.ImageTransferDirection.UPLOAD,
- transfer_func=_transfer,
- )
-
-
-def download_disk_image(connection, module):
- def _transfer(transfer_service, proxy_connection, proxy_url, transfer_ticket):
- BUF_SIZE = 128 * 1024
- transfer_headers = {
- 'Authorization': transfer_ticket,
- }
- proxy_connection.request(
- 'GET',
- proxy_url.path,
- headers=transfer_headers,
- )
- r = proxy_connection.getresponse()
- path = module.params["download_image_path"]
- image_size = int(r.getheader('Content-Length'))
- with open(path, "wb") as mydisk:
- pos = 0
- while pos < image_size:
- to_read = min(image_size - pos, BUF_SIZE)
- chunk = r.read(to_read)
- if not chunk:
- raise RuntimeError("Socket disconnected")
- mydisk.write(chunk)
- pos += len(chunk)
-
- return transfer(
- connection,
- module,
- otypes.ImageTransferDirection.DOWNLOAD,
- transfer_func=_transfer,
- )
-
-
-def get_disk_attachment(disk, disk_attachments, connection):
- for disk_attachment in disk_attachments:
- if get_link_name(connection, disk_attachment.disk) == disk.get('name') or\
- disk_attachment.disk.id == disk.get('id'):
- return disk_attachment
-
-
-def create_snapshot(module, vm_service, snapshots_service, connection):
- changed = False
- snapshot = get_entity(
- snapshots_service.snapshot_service(module.params['snapshot_id'])
- )
- if snapshot is None:
- if not module.check_mode:
- disk_attachments_id = set(
- get_disk_attachment(disk, vm_service.disk_attachments_service().list(), connection).id
- for disk in module.params.get('disks')
- ) if module.params.get('disks') else None
-
- snapshot = snapshots_service.add(
- otypes.Snapshot(
- description=module.params.get('description'),
- persist_memorystate=module.params.get('use_memory'),
- disk_attachments=[otypes.DiskAttachment(disk=otypes.Disk(id=da_id)) for da_id in disk_attachments_id] if disk_attachments_id else None
- )
- )
- changed = True
- wait(
- service=snapshots_service.snapshot_service(snapshot.id),
- condition=lambda snap: snap.snapshot_status == otypes.SnapshotStatus.OK,
- wait=module.params['wait'],
- timeout=module.params['timeout'],
- )
- return {
- 'changed': changed,
- 'id': snapshot.id,
- 'snapshot': get_dict_of_struct(snapshot),
- }
-
-
-def remove_snapshot(module, vm_service, snapshots_service, snapshot_id=None):
- changed = False
- if not snapshot_id:
- snapshot_id = module.params['snapshot_id']
- snapshot = get_entity(
- snapshots_service.snapshot_service(snapshot_id)
- )
-
- if snapshot:
- snapshot_service = snapshots_service.snapshot_service(snapshot.id)
- if not module.check_mode:
- snapshot_service.remove()
- changed = True
- wait(
- service=snapshot_service,
- condition=lambda snapshot: snapshot is None,
- wait=module.params['wait'],
- timeout=module.params['timeout'],
- )
-
- return {
- 'changed': changed,
- 'id': snapshot.id if snapshot else None,
- 'snapshot': get_dict_of_struct(snapshot),
- }
-
-
-def restore_snapshot(module, vm_service, snapshots_service):
- changed = False
- snapshot_service = snapshots_service.snapshot_service(
- module.params['snapshot_id']
- )
- snapshot = get_entity(snapshot_service)
- if snapshot is None:
- raise Exception(
- "Snapshot with id '%s' doesn't exist" % module.params['snapshot_id']
- )
-
- if snapshot.snapshot_status != otypes.SnapshotStatus.IN_PREVIEW:
- if not module.check_mode:
- snapshot_service.restore(
- restore_memory=module.params.get('use_memory'),
- )
- changed = True
- else:
- if not module.check_mode:
- vm_service.commit_snapshot()
- changed = True
-
- if changed:
- wait(
- service=snapshot_service,
- condition=lambda snap: snap.snapshot_status == otypes.SnapshotStatus.OK,
- wait=module.params['wait'],
- timeout=module.params['timeout'],
- )
- return {
- 'changed': changed,
- 'id': snapshot.id if snapshot else None,
- 'snapshot': get_dict_of_struct(snapshot),
- }
-
-
-def get_snapshot_disk_id(module, snapshots_service):
- snapshot_service = snapshots_service.snapshot_service(module.params.get('snapshot_id'))
- snapshot_disks_service = snapshot_service.disks_service()
-
- disk_id = ''
- if module.params.get('disk_id'):
- disk_id = module.params.get('disk_id')
- elif module.params.get('disk_name'):
- disk_id = get_id_by_name(snapshot_disks_service, module.params.get('disk_name'))
- return disk_id
-
-
-def remove_old_snapshosts(module, vm_service, snapshots_service):
- deleted_snapshots = []
- changed = False
- date_now = datetime.now()
- for snapshot in snapshots_service.list():
- if snapshot.vm is not None and snapshot.vm.name == module.params.get('vm_name'):
- diff = date_now - snapshot.date.replace(tzinfo=None)
- if diff.days >= module.params.get('keep_days_old'):
- snapshot = remove_snapshot(module, vm_service, snapshots_service, snapshot.id).get('snapshot')
- deleted_snapshots.append(snapshot)
- changed = True
- return dict(snapshots=deleted_snapshots, changed=changed)
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['restore', 'present', 'absent'],
- default='present',
- ),
- vm_name=dict(required=True),
- snapshot_id=dict(default=None),
- disks=dict(
- type='list',
- options=dict(
- name=dict(default=None, type='str'),
- id=dict(default=None, type='str'),
- )
- ),
- disk_id=dict(default=None),
- disk_name=dict(default=None),
- description=dict(default=None),
- download_image_path=dict(default=None),
- upload_image_path=dict(default=None),
- keep_days_old=dict(default=None, type='int'),
- use_memory=dict(
- default=None,
- type='bool',
- aliases=['restore_memory', 'save_memory'],
- ),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ('state', 'absent', ['snapshot_id']),
- ('state', 'restore', ['snapshot_id']),
- ]
- )
-
- check_sdk(module)
- ret = {}
- vm_name = module.params.get('vm_name')
- auth = module.params['auth']
- connection = create_connection(auth)
- vms_service = connection.system_service().vms_service()
- vm = search_by_name(vms_service, vm_name)
- if not vm:
- module.fail_json(
- msg="Vm '{name}' doesn't exist.".format(name=vm_name),
- )
-
- vm_service = vms_service.vm_service(vm.id)
- snapshots_service = vms_service.vm_service(vm.id).snapshots_service()
- try:
- state = module.params['state']
- if state == 'present':
- if module.params.get('disk_id') or module.params.get('disk_name'):
- module.params['disk_id'] = get_snapshot_disk_id(module, snapshots_service)
- if module.params['upload_image_path']:
- ret['changed'] = upload_disk_image(connection, module)
- if module.params['download_image_path']:
- ret['changed'] = download_disk_image(connection, module)
- if module.params.get('keep_days_old') is not None:
- ret = remove_old_snapshosts(module, vm_service, snapshots_service)
- else:
- ret = create_snapshot(module, vm_service, snapshots_service, connection)
- elif state == 'restore':
- ret = restore_snapshot(module, vm_service, snapshots_service)
- elif state == 'absent':
- ret = remove_snapshot(module, vm_service, snapshots_service)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py
deleted file mode 100644
index 0d21e2fe7c..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_snapshot_info
-short_description: Retrieve information about one or more oVirt/RHV virtual machine snapshots
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV virtual machine snapshots."
- - This module was called C(ovirt_snapshot_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_snapshot_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_snapshots), which
- contains a list of snapshots. You need to register the result with
- the I(register) keyword to use it."
-options:
- vm:
- description:
- - "Name of the VM with snapshot."
- required: true
- description:
- description:
- - "Description of the snapshot, can be used as glob expression."
- snapshot_id:
- description:
- - "Id of the snapshot we want to retrieve information about."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all snapshots which description start with C(update) for VM named C(centos7):
-- ovirt_snapshot_info:
- vm: centos7
- description: update*
- register: result
-- debug:
- msg: "{{ result.ovirt_snapshots }}"
-'''
-
-RETURN = '''
-ovirt_snapshots:
- description: "List of dictionaries describing the snapshot. Snapshot attributes are mapped to dictionary keys,
- all snapshot attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/snapshot."
- returned: On success.
- type: list
-'''
-
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- search_by_name,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- vm=dict(required=True),
- description=dict(default=None),
- snapshot_id=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_snapshot_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_snapshot_facts' module has been renamed to 'ovirt_snapshot_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- vms_service = connection.system_service().vms_service()
- vm_name = module.params['vm']
- vm = search_by_name(vms_service, vm_name)
- if vm is None:
- raise Exception("VM '%s' was not found." % vm_name)
-
- snapshots_service = vms_service.service(vm.id).snapshots_service()
- if module.params['description']:
- snapshots = [
- e for e in snapshots_service.list()
- if fnmatch.fnmatch(e.description, module.params['description'])
- ]
- elif module.params['snapshot_id']:
- snapshots = [
- snapshots_service.snapshot_service(module.params['snapshot_id']).get()
- ]
- else:
- snapshots = snapshots_service.list()
-
- result = dict(
- ovirt_snapshots=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in snapshots
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py b/lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py
deleted file mode 100644
index cd74e8617a..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py
+++ /dev/null
@@ -1,285 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_storage_connection
-short_description: Module to manage storage connections in oVirt
-version_added: "2.4"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage storage connections in oVirt"
-options:
- id:
- description:
- - "Id of the storage connection to manage."
- state:
- description:
- - "Should the storage connection be present or absent."
- choices: ['present', 'absent']
- default: present
- storage:
- description:
- - "Name of the storage domain to be used with storage connection."
- address:
- description:
- - "Address of the storage server. E.g.: myserver.mydomain.com"
- path:
- description:
- - "Path of the mount point of the storage. E.g.: /path/to/my/data"
- nfs_version:
- description:
- - "NFS version. One of: I(auto), I(v3), I(v4) or I(v4_1)."
- nfs_timeout:
- description:
- - "The time in tenths of a second to wait for a response before retrying NFS requests. Range 0 to 65535."
- nfs_retrans:
- description:
- - "The number of times to retry a request before attempting further recovery actions. Range 0 to 65535."
- mount_options:
- description:
- - "Option which will be passed when mounting storage."
- password:
- description:
- - "A CHAP password for logging into a target."
- username:
- description:
- - "A CHAP username for logging into a target."
- port:
- description:
- - "Port of the iSCSI storage server."
- target:
- description:
- - "The target IQN for the storage device."
- type:
- description:
- - "Storage type. For example: I(nfs), I(iscsi), etc."
- vfs_type:
- description:
- - "Virtual File System type."
- force:
- description:
- - "This parameter is relevant only when updating a connection."
- - "If I(true) the storage domain don't have to be in I(MAINTENANCE)
- state, so the storage connection is updated."
- type: bool
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add new storage connection:
-- ovirt_storage_connection:
- storage: myiscsi
- address: 10.34.63.199
- target: iqn.2016-08-09.domain-01:nickname
- port: 3260
- type: iscsi
-
-# Update the existing storage connection address:
-- ovirt_storage_connection:
- id: 26915c96-92ff-47e5-9e77-b581db2f2d36
- address: 10.34.63.204
- force: true
-
-# Remove storage connection:
-- ovirt_storage_connection:
- id: 26915c96-92ff-47e5-9e77-b581db2f2d36
-'''
-
-RETURN = '''
-id:
- description: ID of the storage connection which is managed
- returned: On success if storage connection is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-storage_connection:
- description: "Dictionary of all the storage connection attributes. Storage connection attributes can be found on your oVirt instance
- at following url: https://ovirt.example.com/ovirt-engine/api/model#types/storage_connection."
- returned: On success if storage connection is found.
- type: dict
-'''
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- ovirt_full_argument_spec,
- search_by_name,
-)
-
-
-class StorageConnectionModule(BaseModule):
-
- def build_entity(self):
- return otypes.StorageConnection(
- address=self.param('address'),
- path=self.param('path'),
- nfs_version=otypes.NfsVersion(
- self.param('nfs_version')
- ) if self.param('nfs_version') is not None else None,
- nfs_timeo=self.param('nfs_timeout'),
- nfs_retrans=self.param('nfs_retrans'),
- mount_options=self.param('mount_options'),
- password=self.param('password'),
- username=self.param('username'),
- port=self.param('port'),
- target=self.param('target'),
- type=otypes.StorageType(
- self.param('type')
- ) if self.param('type') is not None else None,
- vfs_type=self.param('vfs_type'),
- )
-
- def _get_storage_domain_service(self):
- sds_service = self._connection.system_service().storage_domains_service()
- sd = search_by_name(sds_service, self.param('storage'))
- if sd is None:
- raise Exception(
- "Storage '%s' was not found." % self.param('storage')
- )
- return sd, sds_service.storage_domain_service(sd.id)
-
- def post_present(self, entity_id):
- if self.param('storage'):
- sd, sd_service = self._get_storage_domain_service()
- if entity_id not in [
- sd_conn.id for sd_conn in self._connection.follow_link(sd.storage_connections)
- ]:
- scs_service = sd_service.storage_connections_service()
- if not self._module.check_mode:
- scs_service.add(
- connection=otypes.StorageConnection(
- id=entity_id,
- ),
- )
- self.changed = True
-
- def pre_remove(self, entity_id):
- if self.param('storage'):
- sd, sd_service = self._get_storage_domain_service()
- if entity_id in [
- sd_conn.id for sd_conn in self._connection.follow_link(sd.storage_connections)
- ]:
- scs_service = sd_service.storage_connections_service()
- sc_service = scs_service.connection_service(entity_id)
- if not self._module.check_mode:
- sc_service.remove()
- self.changed = True
-
- def update_check(self, entity):
- return (
- equal(self.param('address'), entity.address) and
- equal(self.param('path'), entity.path) and
- equal(self.param('nfs_version'), str(entity.nfs_version)) and
- equal(self.param('nfs_timeout'), entity.nfs_timeo) and
- equal(self.param('nfs_retrans'), entity.nfs_retrans) and
- equal(self.param('mount_options'), entity.mount_options) and
- equal(self.param('username'), entity.username) and
- equal(self.param('port'), entity.port) and
- equal(self.param('target'), entity.target) and
- equal(self.param('type'), str(entity.type)) and
- equal(self.param('vfs_type'), entity.vfs_type)
- )
-
-
-def find_sc_by_attributes(module, storage_connections_service):
- for sd_conn in [
- sc for sc in storage_connections_service.list()
- if str(sc.type) == module.params['type']
- ]:
- sd_conn_type = str(sd_conn.type)
- if sd_conn_type in ['nfs', 'posixfs', 'glusterfs', 'localfs']:
- if (
- module.params['address'] == sd_conn.address and
- module.params['path'] == sd_conn.path
- ):
- return sd_conn
- elif sd_conn_type in ['iscsi', 'fcp']:
- if (
- module.params['address'] == sd_conn.address and
- module.params['target'] == sd_conn.target
- ):
- return sd_conn
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- id=dict(default=None),
- address=dict(default=None),
- path=dict(default=None),
- nfs_version=dict(default=None),
- nfs_timeout=dict(default=None, type='int'),
- nfs_retrans=dict(default=None, type='int'),
- mount_options=dict(default=None),
- password=dict(default=None, no_log=True),
- username=dict(default=None),
- port=dict(default=None, type='int'),
- target=dict(default=None),
- type=dict(default=None),
- vfs_type=dict(default=None),
- force=dict(type='bool', default=False),
- storage=dict(default=None),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- storage_connections_service = connection.system_service().storage_connections_service()
- storage_connection_module = StorageConnectionModule(
- connection=connection,
- module=module,
- service=storage_connections_service,
- )
- entity = None
- if module.params['id'] is None:
- entity = find_sc_by_attributes(module, storage_connections_service)
-
- state = module.params['state']
- if state == 'present':
- ret = storage_connection_module.create(
- entity=entity,
- update_params={'force': True},
- )
- storage_connection_module.post_present(ret['id'])
- elif state == 'absent':
- storage_connection_module.pre_remove(module.params['id'])
- ret = storage_connection_module.remove(entity=entity)
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py b/lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py
deleted file mode 100644
index 26d5d12d0d..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py
+++ /dev/null
@@ -1,809 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_storage_domain
-short_description: Module to manage storage domains in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage storage domains in oVirt/RHV"
-options:
- id:
- description:
- - "Id of the storage domain to be imported."
- version_added: "2.4"
- name:
- description:
- - "Name of the storage domain to manage. (Not required when state is I(imported))"
- state:
- description:
- - "Should the storage domain be present/absent/maintenance/unattached/imported/update_ovf_store"
- - "I(imported) is supported since version 2.4."
- - "I(update_ovf_store) is supported since version 2.5, currently if C(wait) is (true), we don't wait for update."
- choices: ['present', 'absent', 'maintenance', 'unattached', 'imported', 'update_ovf_store']
- default: present
- description:
- description:
- - "Description of the storage domain."
- comment:
- description:
- - "Comment of the storage domain."
- data_center:
- description:
- - "Data center name where storage domain should be attached."
- - "This parameter isn't idempotent, it's not possible to change data center of storage domain."
- domain_function:
- description:
- - "Function of the storage domain."
- - "This parameter isn't idempotent, it's not possible to change domain function of storage domain."
- choices: ['data', 'iso', 'export']
- default: 'data'
- aliases: ['type']
- host:
- description:
- - "Host to be used to mount storage."
- localfs:
- description:
- - "Dictionary with values for localfs storage type:"
- - "Note that these parameters are not idempotent."
- suboptions:
- path:
- description:
- - "Path of the mount point. E.g.: /path/to/my/data"
- version_added: "2.4"
- nfs:
- description:
- - "Dictionary with values for NFS storage type:"
- - "Note that these parameters are not idempotent."
- suboptions:
- address:
- description:
- - "Address of the NFS server. E.g.: myserver.mydomain.com"
- path:
- description:
- - "Path of the mount point. E.g.: /path/to/my/data"
- version:
- description:
- - "NFS version. One of: I(auto), I(v3), I(v4) or I(v4_1)."
- timeout:
- description:
- - "The time in tenths of a second to wait for a response before retrying NFS requests. Range 0 to 65535."
- retrans:
- description:
- - "The number of times to retry a request before attempting further recovery actions. Range 0 to 65535."
- mount_options:
- description:
- - "Option which will be passed when mounting storage."
- iscsi:
- description:
- - "Dictionary with values for iSCSI storage type:"
- - "Note that these parameters are not idempotent."
- suboptions:
- address:
- description:
- - Address of the iSCSI storage server.
- port:
- description:
- - Port of the iSCSI storage server.
- target:
- description:
- - The target IQN for the storage device.
- lun_id:
- description:
- - LUN id(s).
- username:
- description:
- - A CHAP user name for logging into a target.
- password:
- description:
- - A CHAP password for logging into a target.
- override_luns:
- description:
- - If I(True) ISCSI storage domain luns will be overridden before adding.
- type: bool
- target_lun_map:
- description:
- - List of dictionary containing targets and LUNs.
- version_added: 2.5
- posixfs:
- description:
- - "Dictionary with values for PosixFS storage type:"
- - "Note that these parameters are not idempotent."
- suboptions:
- path:
- description:
- - "Path of the mount point. E.g.: /path/to/my/data"
- vfs_type:
- description:
- - Virtual File System type.
- mount_options:
- description:
- - Option which will be passed when mounting storage.
- glusterfs:
- description:
- - "Dictionary with values for GlusterFS storage type:"
- - "Note that these parameters are not idempotent."
- suboptions:
- address:
- description:
- - "Address of the Gluster server. E.g.: myserver.mydomain.com"
- path:
- description:
- - "Path of the mount point. E.g.: /path/to/my/data"
- mount_options:
- description:
- - Option which will be passed when mounting storage.
- managed_block_storage:
- description:
- - "Dictionary with values for managed block storage type"
- - "Note: available from ovirt 4.3"
- suboptions:
- driver_options:
- description:
- - "The options to be passed when creating a storage domain using a cinder driver."
- - "List of dictionary containing C(name) and C(value) of driver option"
- driver_sensitive_options:
- description:
- - "Parameters containing sensitive information, to be passed when creating a storage domain using a cinder driver."
- - "List of dictionary containing C(name) and C(value) of driver sensitive option"
- version_added: "2.9"
- fcp:
- description:
- - "Dictionary with values for fibre channel storage type:"
- - "Note that these parameters are not idempotent."
- suboptions:
- lun_id:
- description:
- - LUN id.
- override_luns:
- description:
- - If I(True) FCP storage domain LUNs will be overridden before adding.
- type: bool
- wipe_after_delete:
- description:
- - "Boolean flag which indicates whether the storage domain should wipe the data after delete."
- type: bool
- version_added: "2.5"
- backup:
- description:
- - "Boolean flag which indicates whether the storage domain is configured as backup or not."
- type: bool
- version_added: "2.5"
- critical_space_action_blocker:
- description:
- - "Indicates the minimal free space the storage domain should contain in percentages."
- version_added: "2.5"
- warning_low_space:
- description:
- - "Indicates the minimum percentage of a free space in a storage domain to present a warning."
- version_added: "2.5"
- destroy:
- description:
- - "Logical remove of the storage domain. If I(true) retains the storage domain's data for import."
- - "This parameter is relevant only when C(state) is I(absent)."
- type: bool
- format:
- description:
- - "If I(True) storage domain will be formatted after removing it from oVirt/RHV."
- - "This parameter is relevant only when C(state) is I(absent)."
- type: bool
- discard_after_delete:
- description:
- - "If I(True) storage domain blocks will be discarded upon deletion. Enabled by default."
- - "This parameter is relevant only for block based storage domains."
- type: bool
- version_added: 2.5
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add data NFS storage domain
-- ovirt_storage_domain:
- name: data_nfs
- host: myhost
- data_center: mydatacenter
- nfs:
- address: 10.34.63.199
- path: /path/data
-
-# Add data NFS storage domain with id for data center
-- ovirt_storage_domain:
- name: data_nfs
- host: myhost
- data_center: 11111
- nfs:
- address: 10.34.63.199
- path: /path/data
- mount_options: noexec,nosuid
-
-# Add data localfs storage domain
-- ovirt_storage_domain:
- name: data_localfs
- host: myhost
- data_center: mydatacenter
- localfs:
- path: /path/to/data
-
-# Add data iSCSI storage domain:
-- ovirt_storage_domain:
- name: data_iscsi
- host: myhost
- data_center: mydatacenter
- iscsi:
- target: iqn.2016-08-09.domain-01:nickname
- lun_id:
- - 1IET_000d0001
- - 1IET_000d0002
- address: 10.34.63.204
- discard_after_delete: True
- backup: False
- critical_space_action_blocker: 5
- warning_low_space: 10
-
-# Since Ansible 2.5 you can specify multiple targets for storage domain,
-# Add data iSCSI storage domain with multiple targets:
-- ovirt_storage_domain:
- name: data_iscsi
- host: myhost
- data_center: mydatacenter
- iscsi:
- target_lun_map:
- - target: iqn.2016-08-09.domain-01:nickname
- lun_id: 1IET_000d0001
- - target: iqn.2016-08-09.domain-02:nickname
- lun_id: 1IET_000d0002
- address: 10.34.63.204
- discard_after_delete: True
-
-# Add data glusterfs storage domain
-- ovirt_storage_domain:
- name: glusterfs_1
- host: myhost
- data_center: mydatacenter
- glusterfs:
- address: 10.10.10.10
- path: /path/data
-
-# Create export NFS storage domain:
-- ovirt_storage_domain:
- name: myexportdomain
- domain_function: export
- host: myhost
- data_center: mydatacenter
- nfs:
- address: 10.34.63.199
- path: /path/export
- wipe_after_delete: False
- backup: True
- critical_space_action_blocker: 2
- warning_low_space: 5
-
-# Import export NFS storage domain:
-- ovirt_storage_domain:
- state: imported
- domain_function: export
- host: myhost
- data_center: mydatacenter
- nfs:
- address: 10.34.63.199
- path: /path/export
-
-# Import FCP storage domain:
-- ovirt_storage_domain:
- state: imported
- name: data_fcp
- host: myhost
- data_center: mydatacenter
- fcp: {}
-
-# Update OVF_STORE:
-- ovirt_storage_domain:
- state: update_ovf_store
- name: domain
-
-# Create ISO NFS storage domain
-- ovirt_storage_domain:
- name: myiso
- domain_function: iso
- host: myhost
- data_center: mydatacenter
- nfs:
- address: 10.34.63.199
- path: /path/iso
-
-# Create managed storage domain
-# Available from ovirt 4.3 and ansible 2.9
-- ovirt_storage_domain:
- name: my_managed_domain
- host: myhost
- data_center: mydatacenter
- managed_block_storage:
- driver_options:
- - name: rbd_pool
- value: pool1
- - name: rbd_user
- value: admin
- - name: volume_driver
- value: cinder.volume.drivers.rbd.RBDDriver
- - name: rbd_keyring_conf
- value: /etc/ceph/keyring
- driver_sensitive_options:
- - name: secret_password
- value: password
-
-# Remove storage domain
-- ovirt_storage_domain:
- state: absent
- name: mystorage_domain
- format: true
-'''
-
-RETURN = '''
-id:
- description: ID of the storage domain which is managed
- returned: On success if storage domain is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-storage_domain:
- description: "Dictionary of all the storage domain attributes. Storage domain attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/storage_domain."
- returned: On success if storage domain is found.
- type: dict
-'''
-
-try:
- import ovirtsdk4.types as otypes
-
- from ovirtsdk4.types import StorageDomainStatus as sdstate
- from ovirtsdk4.types import HostStatus as hoststate
- from ovirtsdk4.types import DataCenterStatus as dcstatus
-except ImportError:
- pass
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_entity,
- get_id_by_name,
- OvirtRetry,
- ovirt_full_argument_spec,
- search_by_name,
- search_by_attributes,
- wait,
-)
-
-
-class StorageDomainModule(BaseModule):
-
- def _get_storage_type(self):
- for sd_type in ['nfs', 'iscsi', 'posixfs', 'glusterfs', 'fcp', 'localfs', 'managed_block_storage']:
- if self.param(sd_type) is not None:
- return sd_type
-
- def _get_storage(self):
- for sd_type in ['nfs', 'iscsi', 'posixfs', 'glusterfs', 'fcp', 'localfs', 'managed_block_storage']:
- if self.param(sd_type) is not None:
- return self.param(sd_type)
-
- def _login(self, storage_type, storage):
- if storage_type == 'iscsi':
- hosts_service = self._connection.system_service().hosts_service()
- host_id = get_id_by_name(hosts_service, self.param('host'))
- if storage.get('target'):
- hosts_service.host_service(host_id).iscsi_login(
- iscsi=otypes.IscsiDetails(
- username=storage.get('username'),
- password=storage.get('password'),
- address=storage.get('address'),
- target=storage.get('target'),
- ),
- )
- elif storage.get('target_lun_map'):
- for target in [m['target'] for m in storage.get('target_lun_map')]:
- hosts_service.host_service(host_id).iscsi_login(
- iscsi=otypes.IscsiDetails(
- username=storage.get('username'),
- password=storage.get('password'),
- address=storage.get('address'),
- target=target,
- ),
- )
-
- def __target_lun_map(self, storage):
- if storage.get('target'):
- lun_ids = storage.get('lun_id') if isinstance(storage.get('lun_id'), list) else [(storage.get('lun_id'))]
- return [(lun_id, storage.get('target')) for lun_id in lun_ids]
- elif storage.get('target_lun_map'):
- return [(target_map.get('lun_id'), target_map.get('target')) for target_map in storage.get('target_lun_map')]
- else:
- lun_ids = storage.get('lun_id') if isinstance(storage.get('lun_id'), list) else [(storage.get('lun_id'))]
- return [(lun_id, None) for lun_id in lun_ids]
-
- def build_entity(self):
- storage_type = self._get_storage_type()
- storage = self._get_storage()
- self._login(storage_type, storage)
-
- return otypes.StorageDomain(
- name=self.param('name'),
- description=self.param('description'),
- comment=self.param('comment'),
- wipe_after_delete=self.param('wipe_after_delete'),
- backup=self.param('backup'),
- critical_space_action_blocker=self.param('critical_space_action_blocker'),
- warning_low_space_indicator=self.param('warning_low_space'),
- import_=True if self.param('state') == 'imported' else None,
- id=self.param('id') if self.param('state') == 'imported' else None,
- type=otypes.StorageDomainType(storage_type if storage_type == 'managed_block_storage' else self.param('domain_function')),
- host=otypes.Host(name=self.param('host')),
- discard_after_delete=self.param('discard_after_delete'),
- storage=otypes.HostStorage(
- driver_options=[
- otypes.Property(
- name=do.get('name'),
- value=do.get('value')
- ) for do in storage.get('driver_options')
- ] if storage.get('driver_options') else None,
- driver_sensitive_options=[
- otypes.Property(
- name=dso.get('name'),
- value=dso.get('value')
- ) for dso in storage.get('driver_sensitive_options')
- ] if storage.get('driver_sensitive_options') else None,
- type=otypes.StorageType(storage_type),
- logical_units=[
- otypes.LogicalUnit(
- id=lun_id,
- address=storage.get('address'),
- port=int(storage.get('port', 3260)),
- target=target,
- username=storage.get('username'),
- password=storage.get('password'),
- ) for lun_id, target in self.__target_lun_map(storage)
- ] if storage_type in ['iscsi', 'fcp'] else None,
- override_luns=storage.get('override_luns'),
- mount_options=storage.get('mount_options'),
- vfs_type=(
- 'glusterfs'
- if storage_type in ['glusterfs'] else storage.get('vfs_type')
- ),
- address=storage.get('address'),
- path=storage.get('path'),
- nfs_retrans=storage.get('retrans'),
- nfs_timeo=storage.get('timeout'),
- nfs_version=otypes.NfsVersion(
- storage.get('version')
- ) if storage.get('version') else None,
- ) if storage_type is not None else None
- )
-
- def _find_attached_datacenter_name(self, sd_name):
- """
- Finds the name of the datacenter that a given
- storage domain is attached to.
-
- Args:
- sd_name (str): Storage Domain name
-
- Returns:
- str: Data Center name
-
- Raises:
- Exception: In case storage domain in not attached to
- an active Datacenter
- """
- dcs_service = self._connection.system_service().data_centers_service()
- dc = search_by_attributes(dcs_service, storage=sd_name)
- if dc is None:
- raise Exception(
- "Can't bring storage to state `%s`, because it seems that"
- "it is not attached to any datacenter"
- % self.param('state')
- )
- else:
- if dc.status == dcstatus.UP:
- return dc.name
- else:
- raise Exception(
- "Can't bring storage to state `%s`, because Datacenter "
- "%s is not UP" % (self.param('state'), dc.name)
- )
-
- def _attached_sds_service(self, dc_name):
- # Get data center object of the storage domain:
- dcs_service = self._connection.system_service().data_centers_service()
-
- # Search the data_center name, if it does not exist, try to search by guid.
- dc = search_by_name(dcs_service, dc_name)
- if dc is None:
- dc = get_entity(dcs_service.service(dc_name))
- if dc is None:
- return None
-
- dc_service = dcs_service.data_center_service(dc.id)
- return dc_service.storage_domains_service()
-
- def _attached_sd_service(self, storage_domain):
- dc_name = self.param('data_center')
- if not dc_name:
- # Find the DC, where the storage resides:
- dc_name = self._find_attached_datacenter_name(storage_domain.name)
- attached_sds_service = self._attached_sds_service(dc_name)
- attached_sd_service = attached_sds_service.storage_domain_service(storage_domain.id)
- return attached_sd_service
-
- def _maintenance(self, storage_domain):
- attached_sd_service = self._attached_sd_service(storage_domain)
- attached_sd = get_entity(attached_sd_service)
-
- if attached_sd and attached_sd.status != sdstate.MAINTENANCE:
- if not self._module.check_mode:
- attached_sd_service.deactivate()
- self.changed = True
-
- wait(
- service=attached_sd_service,
- condition=lambda sd: sd.status == sdstate.MAINTENANCE,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
-
- def _unattach(self, storage_domain):
- attached_sd_service = self._attached_sd_service(storage_domain)
- attached_sd = get_entity(attached_sd_service)
-
- if attached_sd and attached_sd.status == sdstate.MAINTENANCE:
- if not self._module.check_mode:
- # Detach the storage domain:
- attached_sd_service.remove()
- self.changed = True
- # Wait until storage domain is detached:
- wait(
- service=attached_sd_service,
- condition=lambda sd: sd is None,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
-
- def pre_remove(self, storage_domain):
- # In case the user chose to destroy the storage domain there is no need to
- # move it to maintenance or detach it, it should simply be removed from the DB.
- # Also if storage domain in already unattached skip this step.
- if storage_domain.status == sdstate.UNATTACHED or self.param('destroy'):
- return
- # Before removing storage domain we need to put it into maintenance state:
- self._maintenance(storage_domain)
-
- # Before removing storage domain we need to detach it from data center:
- self._unattach(storage_domain)
-
- def post_create_check(self, sd_id):
- storage_domain = self._service.service(sd_id).get()
- dc_name = self.param('data_center')
- if not dc_name:
- # Find the DC, where the storage resides:
- dc_name = self._find_attached_datacenter_name(storage_domain.name)
- self._service = self._attached_sds_service(dc_name)
-
- # If storage domain isn't attached, attach it:
- attached_sd_service = self._service.service(storage_domain.id)
- if get_entity(attached_sd_service) is None:
- self._service.add(
- otypes.StorageDomain(
- id=storage_domain.id,
- ),
- )
- self.changed = True
- # Wait until storage domain is in maintenance:
- wait(
- service=attached_sd_service,
- condition=lambda sd: sd.status == sdstate.ACTIVE,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
-
- def unattached_pre_action(self, storage_domain):
- dc_name = self.param('data_center')
- if not dc_name:
- # Find the DC, where the storage resides:
- dc_name = self._find_attached_datacenter_name(storage_domain.name)
- self._service = self._attached_sds_service(dc_name)
- self._maintenance(storage_domain)
-
- def update_check(self, entity):
- return (
- equal(self.param('comment'), entity.comment) and
- equal(self.param('description'), entity.description) and
- equal(self.param('backup'), entity.backup) and
- equal(self.param('critical_space_action_blocker'), entity.critical_space_action_blocker) and
- equal(self.param('discard_after_delete'), entity.discard_after_delete) and
- equal(self.param('wipe_after_delete'), entity.wipe_after_delete) and
- equal(self.param('warning_low_space_indicator'), entity.warning_low_space_indicator)
- )
-
-
-def failed_state(sd):
- return sd.status in [sdstate.UNKNOWN, sdstate.INACTIVE]
-
-
-def control_state(sd_module):
- sd = sd_module.search_entity()
- if sd is None:
- return
-
- sd_service = sd_module._service.service(sd.id)
-
- # In the case of no status returned, it's an attached storage domain.
- # Redetermine the corresponding service and entity:
- if sd.status is None:
- sd_service = sd_module._attached_sd_service(sd)
- sd = get_entity(sd_service)
-
- if sd.status == sdstate.LOCKED:
- wait(
- service=sd_service,
- condition=lambda sd: sd.status != sdstate.LOCKED,
- fail_condition=failed_state,
- )
-
- if failed_state(sd):
- raise Exception("Not possible to manage storage domain '%s'." % sd.name)
- elif sd.status == sdstate.ACTIVATING:
- wait(
- service=sd_service,
- condition=lambda sd: sd.status == sdstate.ACTIVE,
- fail_condition=failed_state,
- )
- elif sd.status == sdstate.DETACHING:
- wait(
- service=sd_service,
- condition=lambda sd: sd.status == sdstate.UNATTACHED,
- fail_condition=failed_state,
- )
- elif sd.status == sdstate.PREPARING_FOR_MAINTENANCE:
- wait(
- service=sd_service,
- condition=lambda sd: sd.status == sdstate.MAINTENANCE,
- fail_condition=failed_state,
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent', 'maintenance', 'unattached', 'imported', 'update_ovf_store'],
- default='present',
- ),
- id=dict(default=None),
- name=dict(default=None),
- description=dict(default=None),
- comment=dict(default=None),
- data_center=dict(default=None),
- domain_function=dict(choices=['data', 'iso', 'export'], default='data', aliases=['type']),
- host=dict(default=None),
- localfs=dict(default=None, type='dict'),
- nfs=dict(default=None, type='dict'),
- iscsi=dict(default=None, type='dict'),
- managed_block_storage=dict(default=None, type='dict', options=dict(
- driver_options=dict(type='list'),
- driver_sensitive_options=dict(type='list', no_log=True))),
- posixfs=dict(default=None, type='dict'),
- glusterfs=dict(default=None, type='dict'),
- fcp=dict(default=None, type='dict'),
- wipe_after_delete=dict(type='bool', default=None),
- backup=dict(type='bool', default=None),
- critical_space_action_blocker=dict(type='int', default=None),
- warning_low_space=dict(type='int', default=None),
- destroy=dict(type='bool', default=None),
- format=dict(type='bool', default=None),
- discard_after_delete=dict(type='bool', default=None)
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- storage_domains_service = connection.system_service().storage_domains_service()
- storage_domains_module = StorageDomainModule(
- connection=connection,
- module=module,
- service=storage_domains_service,
- )
-
- state = module.params['state']
- control_state(storage_domains_module)
- if state == 'absent':
- # Pick random available host when host parameter is missing
- host_param = module.params['host']
- if not host_param:
- host = search_by_attributes(connection.system_service().hosts_service(), status='up')
- if host is None:
- raise Exception(
- "Not possible to remove storage domain '%s' "
- "because no host found with status `up`." % module.params['name']
- )
- host_param = host.name
- ret = storage_domains_module.remove(
- destroy=module.params['destroy'],
- format=module.params['format'],
- host=host_param,
- )
- elif state == 'present' or state == 'imported':
- sd_id = storage_domains_module.create()['id']
- storage_domains_module.post_create_check(sd_id)
- ret = storage_domains_module.action(
- action='activate',
- action_condition=lambda s: s.status == sdstate.MAINTENANCE,
- wait_condition=lambda s: s.status == sdstate.ACTIVE,
- fail_condition=failed_state,
- search_params={'id': sd_id} if state == 'imported' else None
- )
- elif state == 'maintenance':
- sd_id = storage_domains_module.create()['id']
- storage_domains_module.post_create_check(sd_id)
-
- ret = OvirtRetry.backoff(tries=5, delay=1, backoff=2)(
- storage_domains_module.action
- )(
- action='deactivate',
- action_condition=lambda s: s.status == sdstate.ACTIVE,
- wait_condition=lambda s: s.status == sdstate.MAINTENANCE,
- fail_condition=failed_state,
- )
- elif state == 'unattached':
- ret = storage_domains_module.create()
- storage_domains_module.pre_remove(
- storage_domain=storage_domains_service.service(ret['id']).get()
- )
- ret['changed'] = storage_domains_module.changed
- elif state == 'update_ovf_store':
- ret = storage_domains_module.action(
- action='update_ovf_store'
- )
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py
deleted file mode 100644
index 6e446e30c2..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_storage_domain_info
-short_description: Retrieve information about one or more oVirt/RHV storage domains
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV storage domains."
- - This module was called C(ovirt_storage_domain_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_storage_domain_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_storage_domains), which
- contains a list of storage domains. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search storage domain X from datacenter Y use following pattern:
- name=X and datacenter=Y"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all storage domains which names start with C(data) and
-# belong to data center C(west):
-- ovirt_storage_domain_info:
- pattern: name=data* and datacenter=west
- register: result
-- debug:
- msg: "{{ result.ovirt_storage_domains }}"
-'''
-
-RETURN = '''
-ovirt_storage_domains:
- description: "List of dictionaries describing the storage domains. Storage_domain attributes are mapped to dictionary keys,
- all storage domains attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/storage_domain."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_storage_domain_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_storage_domain_facts' module has been renamed to 'ovirt_storage_domain_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- storage_domains_service = connection.system_service().storage_domains_service()
- storage_domains = storage_domains_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_storage_domains=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in storage_domains
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py
deleted file mode 100644
index 5118e419d4..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017 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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_storage_template_info
-short_description: Retrieve information about one or more oVirt/RHV templates relate to a storage domain.
-author: "Maor Lipchuk (@machacekondra)"
-version_added: "2.4"
-description:
- - "Retrieve information about one or more oVirt/RHV templates relate to a storage domain."
- - This module was called C(ovirt_storage_template_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_storage_template_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_storage_templates), which
- contains a list of templates. You need to register the result with
- the I(register) keyword to use it."
-options:
- unregistered:
- description:
- - "Flag which indicates whether to get unregistered templates which contain one or more
- disks which reside on a storage domain or diskless templates."
- type: bool
- default: false
- max:
- description:
- - "Sets the maximum number of templates to return. If not specified all the templates are returned."
- storage_domain:
- description:
- - "The storage domain name where the templates should be listed."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all Templates which relate to a storage domain and
-# are unregistered:
-- ovirt_storage_template_info:
- unregistered=True
- register: result
-- debug:
- msg: "{{ result.ovirt_storage_templates }}"
-'''
-
-RETURN = '''
-ovirt_storage_templates:
- description: "List of dictionaries describing the Templates. Template attributes are mapped to dictionary keys,
- all Templates attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/template."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- get_id_by_name
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- storage_domain=dict(default=None),
- max=dict(default=None, type='int'),
- unregistered=dict(default=False, type='bool'),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_storage_template_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_storage_template_facts' module has been renamed to 'ovirt_storage_template_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- storage_domains_service = connection.system_service().storage_domains_service()
- sd_id = get_id_by_name(storage_domains_service, module.params['storage_domain'])
- storage_domain_service = storage_domains_service.storage_domain_service(sd_id)
- templates_service = storage_domain_service.templates_service()
-
- # Find the unregistered Template we want to register:
- if module.params.get('unregistered'):
- templates = templates_service.list(unregistered=True)
- else:
- templates = templates_service.list(max=module.params['max'])
- result = dict(
- ovirt_storage_templates=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in templates
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py
deleted file mode 100644
index 99a5248451..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017 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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_storage_vm_info
-short_description: Retrieve information about one or more oVirt/RHV virtual machines relate to a storage domain.
-author: "Maor Lipchuk (@machacekondra)"
-version_added: "2.4"
-description:
- - "Retrieve information about one or more oVirt/RHV virtual machines relate to a storage domain."
- - This module was called C(ovirt_storage_vm_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_storage_vm_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_storage_vms), which
- contains a list of virtual machines. You need to register the result with
- the I(register) keyword to use it."
-options:
- unregistered:
- description:
- - "Flag which indicates whether to get unregistered virtual machines which contain one or more
- disks which reside on a storage domain or diskless virtual machines."
- type: bool
- default: false
- max:
- description:
- - "Sets the maximum number of virtual machines to return. If not specified all the virtual machines are returned."
- storage_domain:
- description:
- - "The storage domain name where the virtual machines should be listed."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all VMs which relate to a storage domain and
-# are unregistered:
-- ovirt_vms_info:
- unregistered=True
- register: result
-- debug:
- msg: "{{ result.ovirt_storage_vms }}"
-'''
-
-RETURN = '''
-ovirt_storage_vms:
- description: "List of dictionaries describing the VMs. VM attributes are mapped to dictionary keys,
- all VMs attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- get_id_by_name
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- storage_domain=dict(default=None),
- max=dict(default=None, type='int'),
- unregistered=dict(default=False, type='bool'),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_storage_vm_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_storage_vm_facts' module has been renamed to 'ovirt_storage_vm_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- storage_domains_service = connection.system_service().storage_domains_service()
- sd_id = get_id_by_name(storage_domains_service, module.params['storage_domain'])
- storage_domain_service = storage_domains_service.storage_domain_service(sd_id)
- vms_service = storage_domain_service.vms_service()
-
- # Find the unregistered VM we want to register:
- if module.params.get('unregistered'):
- vms = vms_service.list(unregistered=True)
- else:
- vms = vms_service.list()
- result = dict(
- ovirt_storage_vms=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in vms
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_tag.py b/lib/ansible/modules/cloud/ovirt/ovirt_tag.py
deleted file mode 100644
index 65992d0121..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_tag.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_tag
-short_description: Module to manage tags in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "This module manage tags in oVirt/RHV. It can also manage assignments
- of those tags to entities."
-options:
- id:
- description:
- - "ID of the tag to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the tag to manage."
- required: true
- state:
- description:
- - "Should the tag be present/absent/attached/detached."
- - "C(Note): I(attached) and I(detached) states are supported since version 2.4."
- choices: ['present', 'absent', 'attached', 'detached']
- default: present
- description:
- description:
- - "Description of the tag to manage."
- parent:
- description:
- - "Name of the parent tag."
- vms:
- description:
- - "List of the VMs names, which should have assigned this tag."
- hosts:
- description:
- - "List of the hosts names, which should have assigned this tag."
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create(if not exists) and assign tag to vms vm1 and vm2:
-- ovirt_tag:
- name: mytag
- vms:
- - vm1
- - vm2
-
-# Attach a tag to VM 'vm3', keeping the rest already attached tags on VM:
-- ovirt_tag:
- name: mytag
- state: attached
- vms:
- - vm3
-
-# Detach a tag from VM 'vm3', keeping the rest already attached tags on VM:
-- ovirt_tag:
- name: mytag
- state: detached
- vms:
- - vm3
-
-# To detach all VMs from tag:
-- ovirt_tag:
- name: mytag
- vms: []
-
-# Remove tag
-- ovirt_tag:
- state: absent
- name: mytag
-
-# Change Tag Name
-- ovirt_tag:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_tag_name"
-'''
-
-RETURN = '''
-id:
- description: ID of the tag which is managed
- returned: On success if tag is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-tag:
- description: "Dictionary of all the tag attributes. Tag attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/tag."
- returned: On success if tag is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_id_by_name,
- ovirt_full_argument_spec,
-)
-
-
-class TagsModule(BaseModule):
-
- def build_entity(self):
- return otypes.Tag(
- id=self._module.params['id'],
- name=self._module.params['name'],
- description=self._module.params['description'],
- parent=otypes.Tag(
- name=self._module.params['parent'],
- ) if self._module.params['parent'] else None,
- )
-
- def post_create(self, entity):
- self.update_check(entity)
-
- def _update_tag_assignments(self, entity, name):
- if self._module.params[name] is None:
- return
-
- state = self.param('state')
- entities_service = getattr(self._connection.system_service(), '%s_service' % name)()
- current_vms = [
- vm.name
- for vm in entities_service.list(search='tag=%s' % self._module.params['name'])
- ]
- # Assign tags:
- if state in ['present', 'attached', 'detached']:
- for entity_name in self._module.params[name]:
- entity_id = get_id_by_name(entities_service, entity_name)
- tags_service = entities_service.service(entity_id).tags_service()
- current_tags = [tag.name for tag in tags_service.list()]
- # Assign the tag:
- if state in ['attached', 'present']:
- if self._module.params['name'] not in current_tags:
- if not self._module.check_mode:
- tags_service.add(
- tag=otypes.Tag(
- name=self._module.params['name'],
- ),
- )
- self.changed = True
- # Detach the tag:
- elif state == 'detached':
- if self._module.params['name'] in current_tags:
- tag_id = get_id_by_name(tags_service, self.param('name'))
- if not self._module.check_mode:
- tags_service.tag_service(tag_id).remove()
- self.changed = True
-
- # Unassign tags:
- if state == 'present':
- for entity_name in [e for e in current_vms if e not in self._module.params[name]]:
- if not self._module.check_mode:
- entity_id = get_id_by_name(entities_service, entity_name)
- tags_service = entities_service.service(entity_id).tags_service()
- tag_id = get_id_by_name(tags_service, self.param('name'))
- tags_service.tag_service(tag_id).remove()
- self.changed = True
-
- def _get_parent(self, entity):
- parent = None
- if entity.parent:
- parent = self._connection.follow_link(entity.parent).name
- return parent
-
- def update_check(self, entity):
- self._update_tag_assignments(entity, 'vms')
- self._update_tag_assignments(entity, 'hosts')
- return (
- equal(self._module.params.get('description'), entity.description) and
- equal(self._module.params.get('name'), entity.name) and
- equal(self._module.params.get('parent'), self._get_parent(entity))
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent', 'attached', 'detached'],
- default='present',
- ),
- id=dict(default=None),
- name=dict(required=True),
- description=dict(default=None),
- parent=dict(default=None),
- vms=dict(default=None, type='list'),
- hosts=dict(default=None, type='list'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- tags_service = connection.system_service().tags_service()
- tags_module = TagsModule(
- connection=connection,
- module=module,
- service=tags_service,
- )
-
- state = module.params['state']
- if state in ['present', 'attached', 'detached']:
- ret = tags_module.create()
- elif state == 'absent':
- ret = tags_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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py
deleted file mode 100644
index 1ef257b13d..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_tag_info
-short_description: Retrieve information about one or more oVirt/RHV tags
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV tags."
- - This module was called C(ovirt_tag_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_tag_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_tags), which
- contains a list of tags. You need to register the result with
- the I(register) keyword to use it."
-options:
- name:
- description:
- - "Name of the tag which should be listed."
- vm:
- description:
- - "Name of the VM, which tags should be listed."
- host:
- description:
- - "Name of the host, which tags should be listed."
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all tags, which names start with C(tag):
-- ovirt_tag_info:
- name: tag*
- register: result
-- debug:
- msg: "{{ result.ovirt_tags }}"
-
-# Gather information about all tags, which are assigned to VM C(postgres):
-- ovirt_tag_info:
- vm: postgres
- register: result
-- debug:
- msg: "{{ result.ovirt_tags }}"
-
-# Gather information about all tags, which are assigned to host C(west):
-- ovirt_tag_info:
- host: west
- register: result
-- debug:
- msg: "{{ result.ovirt_tags }}"
-'''
-
-RETURN = '''
-ovirt_tags:
- description: "List of dictionaries describing the tags. Tags attributes are mapped to dictionary keys,
- all tags attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/tag."
- returned: On success.
- type: list
-'''
-
-import fnmatch
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
- search_by_name,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- name=dict(default=None),
- host=dict(default=None),
- vm=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_tag_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_tag_facts' module has been renamed to 'ovirt_tag_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- tags_service = connection.system_service().tags_service()
- tags = []
- all_tags = tags_service.list()
- if module.params['name']:
- tags.extend([
- t for t in all_tags
- if fnmatch.fnmatch(t.name, module.params['name'])
- ])
- if module.params['host']:
- hosts_service = connection.system_service().hosts_service()
- host = search_by_name(hosts_service, module.params['host'])
- if host is None:
- raise Exception("Host '%s' was not found." % module.params['host'])
- tags.extend([
- tag for tag in hosts_service.host_service(host.id).tags_service().list()
- ])
- if module.params['vm']:
- vms_service = connection.system_service().vms_service()
- vm = search_by_name(vms_service, module.params['vm'])
- if vm is None:
- raise Exception("Vm '%s' was not found." % module.params['vm'])
- tags.extend([
- tag for tag in vms_service.vm_service(vm.id).tags_service().list()
- ])
-
- if not (module.params['vm'] or module.params['host'] or module.params['name']):
- tags = all_tags
-
- result = dict(
- ovirt_tags=[
- get_dict_of_struct(
- struct=t,
- connection=connection,
- fetch_nested=module.params['fetch_nested'],
- attributes=module.params['nested_attributes'],
- ) for t in tags
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_template.py b/lib/ansible/modules/cloud/ovirt/ovirt_template.py
deleted file mode 100644
index eb62b316fa..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_template.py
+++ /dev/null
@@ -1,1087 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_template
-short_description: Module to manage virtual machine templates in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage virtual machine templates in oVirt/RHV."
-options:
- name:
- description:
- - "Name of the template to manage."
- id:
- description:
- - "ID of the template to be registered."
- version_added: "2.4"
- state:
- description:
- - "Should the template be present/absent/exported/imported/registered.
- When C(state) is I(registered) and the unregistered template's name
- belongs to an already registered in engine template in the same DC
- then we fail to register the unregistered template."
- choices: ['present', 'absent', 'exported', 'imported', 'registered']
- default: present
- vm:
- description:
- - "Name of the VM, which will be used to create template."
- description:
- description:
- - "Description of the template."
- cpu_profile:
- description:
- - "CPU profile to be set to template."
- cluster:
- description:
- - "Name of the cluster, where template should be created/imported."
- allow_partial_import:
- description:
- - "Boolean indication whether to allow partial registration of a template when C(state) is registered."
- type: bool
- version_added: "2.4"
- vnic_profile_mappings:
- description:
- - "Mapper which maps an external virtual NIC profile to one that exists in the engine when C(state) is registered.
- vnic_profile is described by the following dictionary:"
- suboptions:
- source_network_name:
- description:
- - The network name of the source network.
- source_profile_name:
- description:
- - The profile name related to the source network.
- target_profile_id:
- description:
- - The id of the target profile id to be mapped to in the engine.
- version_added: "2.5"
- cluster_mappings:
- description:
- - "Mapper which maps cluster name between Template's OVF and the destination cluster this Template should be registered to,
- relevant when C(state) is registered.
- Cluster mapping is described by the following dictionary:"
- suboptions:
- source_name:
- description:
- - The name of the source cluster.
- dest_name:
- description:
- - The name of the destination cluster.
- version_added: "2.5"
- role_mappings:
- description:
- - "Mapper which maps role name between Template's OVF and the destination role this Template should be registered to,
- relevant when C(state) is registered.
- Role mapping is described by the following dictionary:"
- suboptions:
- source_name:
- description:
- - The name of the source role.
- dest_name:
- description:
- - The name of the destination role.
- version_added: "2.5"
- domain_mappings:
- description:
- - "Mapper which maps aaa domain name between Template's OVF and the destination aaa domain this Template should be registered to,
- relevant when C(state) is registered.
- The aaa domain mapping is described by the following dictionary:"
- suboptions:
- source_name:
- description:
- - The name of the source aaa domain.
- dest_name:
- description:
- - The name of the destination aaa domain.
- version_added: "2.5"
- exclusive:
- description:
- - "When C(state) is I(exported) this parameter indicates if the existing templates with the
- same name should be overwritten."
- type: bool
- export_domain:
- description:
- - "When C(state) is I(exported) or I(imported) this parameter specifies the name of the
- export storage domain."
- image_provider:
- description:
- - "When C(state) is I(imported) this parameter specifies the name of the image provider to be used."
- image_disk:
- description:
- - "When C(state) is I(imported) and C(image_provider) is used this parameter specifies the name of disk
- to be imported as template."
- aliases: ['glance_image_disk_name']
- io_threads:
- description:
- - "Number of IO threads used by virtual machine. I(0) means IO threading disabled."
- version_added: "2.7"
- template_image_disk_name:
- description:
- - "When C(state) is I(imported) and C(image_provider) is used this parameter specifies the new name for imported disk,
- if omitted then I(image_disk) name is used by default.
- This parameter is used only in case of importing disk image from Glance domain."
- version_added: "2.4"
- storage_domain:
- description:
- - "When C(state) is I(imported) this parameter specifies the name of the destination data storage domain.
- When C(state) is I(registered) this parameter specifies the name of the data storage domain of the unregistered template."
- clone_permissions:
- description:
- - "If I(True) then the permissions of the VM (only the direct ones, not the inherited ones)
- will be copied to the created template."
- - "This parameter is used only when C(state) I(present)."
- type: bool
- default: False
- seal:
- description:
- - "'Sealing' is an operation that erases all machine-specific configurations from a filesystem:
- This includes SSH keys, UDEV rules, MAC addresses, system ID, hostname, etc.
- If I(true) subsequent virtual machines made from this template will avoid configuration inheritance."
- - "This parameter is used only when C(state) I(present)."
- default: False
- type: bool
- version_added: "2.5"
- operating_system:
- description:
- - Operating system of the template.
- - Default value is set by oVirt/RHV engine.
- - "Possible values are: debian_7, freebsd, freebsdx64, other, other_linux,
- other_linux_ppc64, other_ppc64, rhel_3, rhel_4, rhel_4x64, rhel_5, rhel_5x64,
- rhel_6, rhel_6x64, rhel_6_ppc64, rhel_7x64, rhel_7_ppc64, sles_11,
- sles_11_ppc64, ubuntu_12_04, ubuntu_12_10, ubuntu_13_04, ubuntu_13_10,
- ubuntu_14_04, ubuntu_14_04_ppc64, windows_10, windows_10x64, windows_2003,
- windows_2003x64, windows_2008, windows_2008x64, windows_2008r2x64,
- windows_2008R2x64, windows_2012x64, windows_2012R2x64,
- windows_7, windows_7x64, windows_8, windows_8x64, windows_xp"
- version_added: "2.6"
- memory:
- description:
- - Amount of memory of the template. Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB).
- version_added: "2.6"
- memory_guaranteed:
- description:
- - Amount of minimal guaranteed memory of the template.
- Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB).
- - C(memory_guaranteed) parameter can't be lower than C(memory) parameter.
- version_added: "2.6"
- memory_max:
- description:
- - Upper bound of template memory up to which memory hot-plug can be performed.
- Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB).
- version_added: "2.6"
- version:
- description:
- - "C(name) - The name of this version."
- - "C(number) - The index of this version in the versions hierarchy of the template. Used for editing of sub template."
- version_added: "2.8"
- clone_name:
- description:
- - Name for importing Template from storage domain.
- - If not defined, C(name) will be used.
- version_added: "2.8"
- usb_support:
- description:
- - "I(True) enable USB support, I(False) to disable it. By default is chosen by oVirt/RHV engine."
- type: bool
- version_added: "2.9"
- timezone:
- description:
- - Sets time zone offset of the guest hardware clock.
- - For example C(Etc/GMT)
- version_added: "2.9"
- 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
- version_added: "2.9"
- soundcard_enabled:
- description:
- - "If I(true), the sound card is added to the virtual machine."
- type: bool
- version_added: "2.9"
- smartcard_enabled:
- description:
- - "If I(true), use smart card authentication."
- type: bool
- version_added: "2.9"
- cloud_init:
- description:
- - Dictionary with values for Unix-like Virtual Machine initialization using cloud init.
- suboptions:
- host_name:
- description:
- - Hostname to be set to Virtual Machine when deployed.
- timezone:
- description:
- - Timezone to be set to Virtual Machine when deployed.
- user_name:
- description:
- - Username to be used to set password to Virtual Machine when deployed.
- root_password:
- description:
- - Password to be set for user specified by C(user_name) parameter.
- authorized_ssh_keys:
- description:
- - Use this SSH keys to login to Virtual Machine.
- regenerate_ssh_keys:
- description:
- - If I(True) SSH keys will be regenerated on Virtual Machine.
- type: bool
- custom_script:
- description:
- - 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.
- dns_servers:
- description:
- - DNS servers to be configured on Virtual Machine.
- dns_search:
- description:
- - DNS search domains to be configured on Virtual Machine.
- nic_boot_protocol:
- description:
- - Set boot protocol of the network interface of Virtual Machine.
- choices: ['none', 'dhcp', 'static']
- nic_ip_address:
- description:
- - If boot protocol is static, set this IP address to network interface of Virtual Machine.
- nic_netmask:
- description:
- - If boot protocol is static, set this netmask to network interface of Virtual Machine.
- nic_gateway:
- description:
- - If boot protocol is static, set this gateway to network interface of Virtual Machine.
- nic_name:
- description:
- - Set name to network interface of Virtual Machine.
- nic_on_boot:
- description:
- - If I(True) network interface will be set to start on boot.
- type: bool
- version_added: "2.9"
- cloud_init_nics:
- description:
- - List of dictionaries representing network interfaces to be setup by cloud init.
- - This option is used, when user needs to setup more network interfaces via cloud init.
- - If one network interface is enough, user should use C(cloud_init) I(nic_*) parameters. C(cloud_init) I(nic_*) parameters
- are merged with C(cloud_init_nics) parameters.
- suboptions:
- nic_boot_protocol:
- description:
- - Set boot protocol of the network interface of Virtual Machine. Can be one of C(none), C(dhcp) or C(static).
- nic_ip_address:
- description:
- - If boot protocol is static, set this IP address to network interface of Virtual Machine.
- nic_netmask:
- description:
- - If boot protocol is static, set this netmask to network interface of Virtual Machine.
- nic_gateway:
- description:
- - If boot protocol is static, set this gateway to network interface of Virtual Machine.
- nic_name:
- description:
- - Set name to network interface of Virtual Machine.
- nic_on_boot:
- description:
- - If I(True) network interface will be set to start on boot.
- type: bool
- version_added: "2.9"
- ballooning_enabled:
- description:
- - "If I(true), use memory ballooning."
- - "Memory balloon is a guest device, which may be used to re-distribute / reclaim the host memory
- based on VM needs in a dynamic way. In this way it's possible to create memory over commitment states."
- type: bool
- version_added: "2.9"
- nics:
- description:
- - List of NICs, which should be attached to Virtual Machine. NIC is described by following dictionary.
- suboptions:
- name:
- description:
- - Name of the NIC.
- profile_name:
- description:
- - Profile name where NIC should be attached.
- interface:
- description:
- - Type of the network interface.
- choices: ['virtio', 'e1000', 'rtl8139']
- default: 'virtio'
- mac_address:
- description:
- - Custom MAC address of the network interface, by default it's obtained from MAC pool.
- version_added: "2.9"
- sysprep:
- description:
- - Dictionary with values for Windows Virtual Machine initialization using sysprep.
- suboptions:
- host_name:
- description:
- - Hostname to be set to Virtual Machine when deployed.
- active_directory_ou:
- description:
- - Active Directory Organizational Unit, to be used for login of user.
- org_name:
- description:
- - Organization name to be set to Windows Virtual Machine.
- domain:
- description:
- - Domain to be set to Windows Virtual Machine.
- timezone:
- description:
- - Timezone to be set to Windows Virtual Machine.
- ui_language:
- description:
- - UI language of the Windows Virtual Machine.
- system_locale:
- description:
- - System localization of the Windows Virtual Machine.
- input_locale:
- description:
- - Input localization of the Windows Virtual Machine.
- windows_license_key:
- description:
- - License key to be set to Windows Virtual Machine.
- user_name:
- description:
- - Username to be used for set password to Windows Virtual Machine.
- root_password:
- description:
- - Password to be set for username to Windows Virtual Machine.
- version_added: "2.9"
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Create template from vm
-- ovirt_template:
- cluster: Default
- name: mytemplate
- vm: rhel7
- cpu_profile: Default
- description: Test
-
-# Import template
-- ovirt_template:
- state: imported
- name: mytemplate
- export_domain: myexport
- storage_domain: mystorage
- cluster: mycluster
-
-# Remove template
-- ovirt_template:
- state: absent
- name: mytemplate
-
-# Change Template Name
-- ovirt_template:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_template_name"
-
-# Register template
-- ovirt_template:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- name: mytemplate
-
-# Register template using id
-- ovirt_template:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- id: 1111-1111-1111-1111
-
-# Register template, allowing partial import
-- ovirt_template:
- state: registered
- storage_domain: mystorage
- allow_partial_import: "True"
- cluster: mycluster
- id: 1111-1111-1111-1111
-
-# Register template with vnic profile mappings
-- ovirt_template:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- id: 1111-1111-1111-1111
- vnic_profile_mappings:
- - source_network_name: mynetwork
- source_profile_name: mynetwork
- target_profile_id: 3333-3333-3333-3333
- - source_network_name: mynetwork2
- source_profile_name: mynetwork2
- target_profile_id: 4444-4444-4444-4444
-
-# Register template with mapping
-- ovirt_template:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- id: 1111-1111-1111-1111
- role_mappings:
- - source_name: Role_A
- dest_name: Role_B
- domain_mappings:
- - source_name: Domain_A
- dest_name: Domain_B
- cluster_mappings:
- - source_name: cluster_A
- dest_name: cluster_B
-
-# Import image from Glance s a template
-- ovirt_template:
- state: imported
- name: mytemplate
- image_disk: "centos7"
- template_image_disk_name: centos7_from_glance
- image_provider: "glance_domain"
- storage_domain: mystorage
- cluster: mycluster
-
-# Edit template subversion
-- ovirt_template:
- cluster: mycluster
- name: mytemplate
- vm: rhel7
- version:
- number: 2
- name: subversion
-
-# Create new template subversion
-- ovirt_template:
- cluster: mycluster
- name: mytemplate
- vm: rhel7
- version:
- name: subversion
-
-- name: Template with cloud init
- ovirt_template:
- name: mytemplate
- cluster: Default
- memory: 1GiB
- 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
- nic_on_boot: true
- host_name: example.com
- custom_script: |
- write_files:
- - content: |
- Hello, world!
- path: /tmp/greeting.txt
- permissions: '0644'
- user_name: root
- root_password: super_password
-
-- name: Template with cloud init, with multiple network interfaces
- ovirt_template:
- name: mytemplate
- cluster: mycluster
- cloud_init_nics:
- - nic_name: eth0
- nic_boot_protocol: dhcp
- nic_on_boot: true
- - nic_name: eth1
- nic_boot_protocol: static
- nic_ip_address: 10.34.60.86
- nic_netmask: 255.255.252.0
- nic_gateway: 10.34.63.254
- nic_on_boot: true
-
-- name: Template with timezone and nic
- ovirt_template:
- cluster: MyCluster
- name: mytemplate
- timezone: America/Godthab
- memory_max: 2Gib
- nics:
- - name: nic1
-
-- name: Template with sysprep
- ovirt_vm:
- name: windows2012R2_AD
- cluster: Default
- memory: 3GiB
- sysprep:
- host_name: windowsad.example.com
- user_name: Administrator
- root_password: SuperPassword123
-'''
-
-RETURN = '''
-id:
- description: ID of the template which is managed
- returned: On success if template is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-template:
- description: "Dictionary of all the template attributes. Template attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/template."
- returned: On success if template is found.
- type: dict
-'''
-
-import time
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- convert_to_bytes,
- create_connection,
- equal,
- get_dict_of_struct,
- get_link_name,
- get_id_by_name,
- ovirt_full_argument_spec,
- search_by_attributes,
- search_by_name,
-)
-
-
-class TemplatesModule(BaseModule):
-
- def __init__(self, *args, **kwargs):
- super(TemplatesModule, self).__init__(*args, **kwargs)
- self._initialization = None
-
- def build_entity(self):
- return otypes.Template(
- id=self._module.params['id'],
- name=self._module.params['name'],
- cluster=otypes.Cluster(
- name=self._module.params['cluster']
- ) if self._module.params['cluster'] else None,
- vm=otypes.Vm(
- name=self._module.params['vm']
- ) if self._module.params['vm'] else None,
- description=self._module.params['description'],
- cpu_profile=otypes.CpuProfile(
- id=search_by_name(
- self._connection.system_service().cpu_profiles_service(),
- self._module.params['cpu_profile'],
- ).id
- ) if self._module.params['cpu_profile'] else None,
- display=otypes.Display(
- smartcard_enabled=self.param('smartcard_enabled')
- ) if self.param('smartcard_enabled') is not None else None,
- os=otypes.OperatingSystem(
- type=self.param('operating_system'),
- ) if self.param('operating_system') else None,
- memory=convert_to_bytes(
- self.param('memory')
- ) if self.param('memory') else None,
- soundcard_enabled=self.param('soundcard_enabled'),
- usb=(
- otypes.Usb(enabled=self.param('usb_support'))
- ) if self.param('usb_support') is not None else None,
- sso=(
- otypes.Sso(
- methods=[otypes.Method(id=otypes.SsoMethod.GUEST_AGENT)] if self.param('sso') else []
- )
- ) if self.param('sso') is not None else None,
- time_zone=otypes.TimeZone(
- name=self.param('timezone'),
- ) if self.param('timezone') else None,
- version=otypes.TemplateVersion(
- base_template=self._get_base_template(),
- version_name=self.param('version').get('name'),
- ) if self.param('version') else None,
- memory_policy=otypes.MemoryPolicy(
- guaranteed=convert_to_bytes(self.param('memory_guaranteed')),
- ballooning=self.param('ballooning_enabled'),
- max=convert_to_bytes(self.param('memory_max')),
- ) if any((
- self.param('memory_guaranteed'),
- self.param('ballooning_enabled'),
- self.param('memory_max')
- )) else None,
- io=otypes.Io(
- threads=self.param('io_threads'),
- ) if self.param('io_threads') is not None else None,
- initialization=self.get_initialization(),
- )
-
- def _get_base_template(self):
- templates = self._connection.system_service().templates_service().list()
- for template in templates:
- if template.version.version_number == 1 and template.name == self.param('name'):
- return otypes.Template(
- id=template.id
- )
-
- def post_update(self, entity):
- self.post_present(entity.id)
-
- def post_present(self, entity_id):
- # After creation of the VM, attach disks and NICs:
- entity = self._service.service(entity_id).get()
- self.__attach_nics(entity)
-
- 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 __attach_nics(self, entity):
- # Attach NICs to VM, if specified:
- nics_service = self._service.service(entity.id).nics_service()
- for nic in self.param('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_initialization(self):
- if self._initialization is not None:
- return self._initialization
-
- sysprep = self.param('sysprep')
- cloud_init = self.param('cloud_init')
- cloud_init_nics = self.param('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=nic.pop('nic_on_boot', None),
- 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 or
- nic.get('nic_on_boot') is not None
- )
- ] if cloud_init_nics else None,
- **cloud_init
- )
- elif sysprep:
- self._initialization = otypes.Initialization(
- **sysprep
- )
- return self._initialization
-
- def update_check(self, entity):
- template_display = entity.display
- return (
- 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.param('operating_system'), str(entity.os.type)) and
- equal(self.param('name'), str(entity.name)) and
- equal(self.param('smartcard_enabled'), getattr(template_display, 'smartcard_enabled', False)) and
- equal(self.param('soundcard_enabled'), entity.soundcard_enabled) and
- equal(self.param('ballooning_enabled'), entity.memory_policy.ballooning) and
- equal(self.param('sso'), True if entity.sso.methods else False) and
- equal(self.param('timezone'), getattr(entity.time_zone, 'name', None)) and
- equal(self.param('usb_support'), entity.usb.enabled) and
- equal(convert_to_bytes(self.param('memory_guaranteed')), entity.memory_policy.guaranteed) and
- equal(convert_to_bytes(self.param('memory_max')), entity.memory_policy.max) and
- equal(convert_to_bytes(self.param('memory')), entity.memory) and
- equal(self._module.params.get('cpu_profile'), get_link_name(self._connection, entity.cpu_profile)) and
- equal(self.param('io_threads'), entity.io.threads)
- )
-
- def _get_export_domain_service(self):
- provider_name = self._module.params['export_domain'] or self._module.params['image_provider']
- export_sds_service = self._connection.system_service().storage_domains_service()
- export_sd = search_by_name(export_sds_service, provider_name)
- if export_sd is None:
- raise ValueError(
- "Export storage domain/Image Provider '%s' wasn't found." % provider_name
- )
-
- return export_sds_service.service(export_sd.id)
-
- def post_export_action(self, entity):
- self._service = self._get_export_domain_service().templates_service()
-
- def post_import_action(self, entity):
- self._service = self._connection.system_service().templates_service()
-
-
-def _get_role_mappings(module):
- roleMappings = list()
-
- for roleMapping in module.params['role_mappings']:
- roleMappings.append(
- otypes.RegistrationRoleMapping(
- from_=otypes.Role(
- name=roleMapping['source_name'],
- ) if roleMapping['source_name'] else None,
- to=otypes.Role(
- name=roleMapping['dest_name'],
- ) if roleMapping['dest_name'] else None,
- )
- )
- return roleMappings
-
-
-def _get_domain_mappings(module):
- domainMappings = list()
-
- for domainMapping in module.params['domain_mappings']:
- domainMappings.append(
- otypes.RegistrationDomainMapping(
- from_=otypes.Domain(
- name=domainMapping['source_name'],
- ) if domainMapping['source_name'] else None,
- to=otypes.Domain(
- name=domainMapping['dest_name'],
- ) if domainMapping['dest_name'] else None,
- )
- )
- return domainMappings
-
-
-def _get_cluster_mappings(module):
- clusterMappings = list()
-
- for clusterMapping in module.params['cluster_mappings']:
- clusterMappings.append(
- otypes.RegistrationClusterMapping(
- from_=otypes.Cluster(
- name=clusterMapping['source_name'],
- ),
- to=otypes.Cluster(
- name=clusterMapping['dest_name'],
- ),
- )
- )
- return clusterMappings
-
-
-def _get_vnic_profile_mappings(module):
- vnicProfileMappings = list()
-
- for vnicProfileMapping in module.params['vnic_profile_mappings']:
- vnicProfileMappings.append(
- otypes.VnicProfileMapping(
- source_network_name=vnicProfileMapping['source_network_name'],
- source_network_profile_name=vnicProfileMapping['source_profile_name'],
- target_vnic_profile=otypes.VnicProfile(
- id=vnicProfileMapping['target_profile_id'],
- ) if vnicProfileMapping['target_profile_id'] else None,
- )
- )
-
- return vnicProfileMappings
-
-
-def find_subversion_template(module, templates_service):
- version = module.params.get('version')
- templates = templates_service.list()
- for template in templates:
- if version.get('number') == template.version.version_number and module.params.get('name') == template.name:
- return template
-
- # when user puts version number which does not exist
- raise ValueError(
- "Template with name '%s' and version '%s' in cluster '%s' was not found'" % (
- module.params['name'],
- module.params['version']['number'],
- module.params['cluster'],
- )
- )
-
-
-def searchable_attributes(module):
- """
- Return all searchable template attributes passed to module.
- """
- attributes = {
- 'name': module.params.get('name'),
- 'cluster': module.params.get('cluster'),
- }
- return dict((k, v) for k, v in attributes.items() if v is not None)
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent', 'exported', 'imported', 'registered'],
- default='present',
- ),
- id=dict(default=None),
- name=dict(default=None),
- vm=dict(default=None),
- timezone=dict(type='str'),
- description=dict(default=None),
- sso=dict(type='bool'),
- ballooning_enabled=dict(type='bool', default=None),
- cluster=dict(default=None),
- usb_support=dict(type='bool'),
- allow_partial_import=dict(default=None, type='bool'),
- cpu_profile=dict(default=None),
- clone_permissions=dict(type='bool'),
- export_domain=dict(default=None),
- storage_domain=dict(default=None),
- exclusive=dict(type='bool'),
- clone_name=dict(default=None),
- image_provider=dict(default=None),
- soundcard_enabled=dict(type='bool', default=None),
- smartcard_enabled=dict(type='bool', default=None),
- image_disk=dict(default=None, aliases=['glance_image_disk_name']),
- io_threads=dict(type='int', default=None),
- template_image_disk_name=dict(default=None),
- version=dict(default=None, type='dict'),
- seal=dict(type='bool'),
- vnic_profile_mappings=dict(default=[], type='list'),
- cluster_mappings=dict(default=[], type='list'),
- role_mappings=dict(default=[], type='list'),
- domain_mappings=dict(default=[], type='list'),
- operating_system=dict(type='str'),
- memory=dict(type='str'),
- memory_guaranteed=dict(type='str'),
- memory_max=dict(type='str'),
- nics=dict(type='list', default=[]),
- cloud_init=dict(type='dict'),
- cloud_init_nics=dict(type='list', default=[]),
- sysprep=dict(type='dict'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_one_of=[['id', 'name']],
- )
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- templates_service = connection.system_service().templates_service()
- templates_module = TemplatesModule(
- connection=connection,
- module=module,
- service=templates_service,
- )
-
- entity = None
- if module.params['version'] is not None and module.params['version'].get('number') is not None:
- entity = find_subversion_template(module, templates_service)
-
- state = module.params['state']
- if state == 'present':
- force_create = False
- if entity is None and module.params['version'] is not None:
- force_create = True
-
- ret = templates_module.create(
- entity=entity,
- # When user want to create new template subversion, we must make sure
- # template is force created as it already exists, but new version should be created.
- force_create=force_create,
- result_state=otypes.TemplateStatus.OK,
- search_params=searchable_attributes(module),
- clone_permissions=module.params['clone_permissions'],
- seal=module.params['seal'],
- )
- elif state == 'absent':
- ret = templates_module.remove(entity=entity)
- elif state == 'exported':
- template = templates_module.search_entity()
- if entity is not None:
- template = entity
- export_service = templates_module._get_export_domain_service()
- export_template = search_by_attributes(export_service.templates_service(), id=template.id)
-
- ret = templates_module.action(
- entity=template,
- action='export',
- action_condition=lambda t: export_template is None or module.params['exclusive'],
- wait_condition=lambda t: t is not None,
- post_action=templates_module.post_export_action,
- storage_domain=otypes.StorageDomain(id=export_service.get().id),
- exclusive=module.params['exclusive'],
- )
- elif state == 'imported':
- template = templates_module.search_entity()
- if entity is not None:
- template = entity
- if template and module.params['clone_name'] is None:
- ret = templates_module.create(
- result_state=otypes.TemplateStatus.OK,
- )
- else:
- kwargs = {}
- if module.params['image_provider']:
- kwargs.update(
- disk=otypes.Disk(
- name=module.params['template_image_disk_name'] or module.params['image_disk']
- ),
- template=otypes.Template(
- name=module.params['name'] if module.params['clone_name'] is None else module.params['clone_name'],
- ),
- clone=True if module.params['clone_name'] is not None else False,
- import_as_template=True,
- )
-
- if module.params['image_disk']:
- # We need to refresh storage domain to get list of images:
- templates_module._get_export_domain_service().images_service().list()
-
- glance_service = connection.system_service().openstack_image_providers_service()
- image_provider = search_by_name(glance_service, module.params['image_provider'])
- images_service = glance_service.service(image_provider.id).images_service()
- else:
- images_service = templates_module._get_export_domain_service().templates_service()
- template_name = module.params['image_disk'] or module.params['name']
- entity = search_by_name(images_service, template_name)
- if entity is None:
- raise Exception("Image/template '%s' was not found." % template_name)
-
- images_service.service(entity.id).import_(
- storage_domain=otypes.StorageDomain(
- name=module.params['storage_domain']
- ) if module.params['storage_domain'] else None,
- cluster=otypes.Cluster(
- name=module.params['cluster']
- ) if module.params['cluster'] else None,
- **kwargs
- )
- # Wait for template to appear in system:
- template = templates_module.wait_for_import(
- condition=lambda t: t.status == otypes.TemplateStatus.OK
- )
- if template is None:
- raise TimeoutError("Image/template '%s' could not be imported. Try again with larger timeout." % template_name)
- ret = templates_module.create(result_state=otypes.TemplateStatus.OK)
- elif state == 'registered':
- storage_domains_service = connection.system_service().storage_domains_service()
- # Find the storage domain with unregistered template:
- sd_id = get_id_by_name(storage_domains_service, module.params['storage_domain'])
- storage_domain_service = storage_domains_service.storage_domain_service(sd_id)
- templates_service = storage_domain_service.templates_service()
-
- # Find the unregistered Template we want to register:
- templates = templates_service.list(unregistered=True)
- template = next(
- (t for t in templates if (t.id == module.params['id'] or t.name == module.params['name'])),
- None
- )
- changed = False
- if template is None:
- template = templates_module.search_entity()
- if template is None:
- raise ValueError(
- "Template '%s(%s)' wasn't found." % (module.params['name'], module.params['id'])
- )
- else:
- # Register the template into the system:
- changed = True
- template_service = templates_service.template_service(template.id)
- template_service.register(
- allow_partial_import=module.params['allow_partial_import'],
- cluster=otypes.Cluster(
- name=module.params['cluster']
- ) if module.params['cluster'] else None,
- vnic_profile_mappings=_get_vnic_profile_mappings(module)
- if module.params['vnic_profile_mappings'] else None,
- registration_configuration=otypes.RegistrationConfiguration(
- cluster_mappings=_get_cluster_mappings(module),
- role_mappings=_get_role_mappings(module),
- domain_mappings=_get_domain_mappings(module),
- ) if (module.params['cluster_mappings']
- or module.params['role_mappings']
- or module.params['domain_mappings']) else None
- )
-
- if module.params['wait']:
- template = templates_module.wait_for_import()
- else:
- # Fetch template to initialize return.
- template = template_service.get()
- ret = templates_module.create(result_state=otypes.TemplateStatus.OK)
- ret = {
- 'changed': changed,
- 'id': template.id,
- 'template': get_dict_of_struct(template)
- }
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_template_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_template_info.py
deleted file mode 100644
index 72b8b1504a..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_template_info.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_template_info
-short_description: Retrieve information about one or more oVirt/RHV templates
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV templates."
- - This module was called C(ovirt_template_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_template_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_templates), which
- contains a list of templates. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search template X from datacenter Y use following pattern:
- name=X and datacenter=Y"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all templates which names start with C(centos) and
-# belongs to data center C(west):
-- ovirt_template_info:
- pattern: name=centos* and datacenter=west
- register: result
-- debug:
- msg: "{{ result.ovirt_templates }}"
-'''
-
-RETURN = '''
-ovirt_templates:
- description: "List of dictionaries describing the templates. Template attributes are mapped to dictionary keys,
- all templates attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/template."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_template_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_template_facts' module has been renamed to 'ovirt_template_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- templates_service = connection.system_service().templates_service()
- templates = templates_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_templates=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in templates
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_user.py b/lib/ansible/modules/cloud/ovirt/ovirt_user.py
deleted file mode 100644
index dc37ff4d91..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_user.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_user
-short_description: Module to manage users in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage users in oVirt/RHV."
-options:
- name:
- description:
- - "Name of the user to manage. In most LDAPs it's I(uid) of the user, but in Active Directory you must specify I(UPN) of the user."
- required: true
- state:
- description:
- - "Should the user be present/absent."
- choices: ['present', 'absent']
- default: present
- authz_name:
- description:
- - "Authorization provider of the user. In previous versions of oVirt/RHV known as domain."
- required: true
- aliases: ['domain']
- namespace:
- description:
- - "Namespace where the user resides. When using the authorization provider that stores users in the LDAP server,
- this attribute equals the naming context of the LDAP server."
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Add user user1 from authorization provider example.com-authz
-- ovirt_user:
- name: user1
- domain: example.com-authz
-
-# Add user user1 from authorization provider example.com-authz
-# In case of Active Directory specify UPN:
-- ovirt_user:
- name: user1@ad2.example.com
- domain: example.com-authz
-
-# Remove user user1 with authorization provider example.com-authz
-- ovirt_user:
- state: absent
- name: user1
- authz_name: example.com-authz
-'''
-
-RETURN = '''
-id:
- description: ID of the user which is managed
- returned: On success if user is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-user:
- description: "Dictionary of all the user attributes. User attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/user."
- returned: On success if user is found.
- type: dict
-'''
-
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- check_params,
- create_connection,
- ovirt_full_argument_spec,
-)
-
-
-def username(module):
- return '{0}@{1}'.format(module.params['name'], module.params['authz_name'])
-
-
-class UsersModule(BaseModule):
-
- def build_entity(self):
- return otypes.User(
- domain=otypes.Domain(
- name=self._module.params['authz_name']
- ),
- user_name=username(self._module),
- principal=self._module.params['name'],
- namespace=self._module.params['namespace'],
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(
- choices=['present', 'absent'],
- default='present',
- ),
- name=dict(required=True),
- authz_name=dict(required=True, aliases=['domain']),
- namespace=dict(default=None),
- )
- 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)
- users_service = connection.system_service().users_service()
- users_module = UsersModule(
- connection=connection,
- module=module,
- service=users_service,
- )
-
- state = module.params['state']
- if state == 'present':
- ret = users_module.create(
- search_params={
- 'usrname': username(module),
- }
- )
- elif state == 'absent':
- ret = users_module.remove(
- search_params={
- 'usrname': username(module),
- }
- )
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_user_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_user_info.py
deleted file mode 100644
index 117ddddb38..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_user_info.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_user_info
-short_description: Retrieve information about one or more oVirt/RHV users
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV users."
- - This module was called C(ovirt_user_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_user_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_users), which
- contains a list of users. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search user X use following pattern: name=X"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all users which first names start with C(john):
-- ovirt_user_info:
- pattern: name=john*
- register: result
-- debug:
- msg: "{{ result.ovirt_users }}"
-'''
-
-RETURN = '''
-ovirt_users:
- description: "List of dictionaries describing the users. User attributes are mapped to dictionary keys,
- all users attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/user."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_user_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_user_facts' module has been renamed to 'ovirt_user_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- users_service = connection.system_service().users_service()
- users = users_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_users=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in users
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_vm.py b/lib/ansible/modules/cloud/ovirt/ovirt_vm.py
deleted file mode 100644
index 202bf9dfb1..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_vm.py
+++ /dev/null
@@ -1,2727 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2017, Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_vm
-short_description: Module to manage Virtual Machines in oVirt/RHV
-version_added: "2.2"
-author:
-- Ondra Machacek (@machacekondra)
-description:
- - This module manages whole lifecycle of the Virtual Machine(VM) in oVirt/RHV.
- - Since VM can hold many states in oVirt/RHV, this see notes to see how the states of the VM are handled.
-options:
- name:
- description:
- - Name of the Virtual Machine to manage.
- - If VM don't exists C(name) is required. Otherwise C(id) or C(name) can be used.
- id:
- description:
- - ID of the Virtual Machine to manage.
- state:
- description:
- - Should the Virtual Machine be running/stopped/present/absent/suspended/next_run/registered/exported/reboot.
- When C(state) is I(registered) and the unregistered VM's name
- belongs to an already registered in engine VM in the same DC
- then we fail to register the unregistered template.
- - I(present) state will create/update VM and don't change its state if it already exists.
- - I(running) state will create/update VM and start it.
- - I(next_run) state updates the VM and if the VM has next run configuration it will be rebooted.
- - Please check I(notes) to more detailed description of states.
- - I(exported) state will export the VM to export domain or as OVA.
- - I(registered) is supported since 2.4.
- - I(reboot) is supported since 2.10, virtual machine is rebooted only if it's in up state.
- choices: [ absent, next_run, present, registered, running, stopped, suspended, exported, reboot ]
- default: present
- cluster:
- description:
- - Name of the cluster, where Virtual Machine should be created.
- - Required if creating VM.
- allow_partial_import:
- description:
- - Boolean indication whether to allow partial registration of Virtual Machine when C(state) is registered.
- type: bool
- version_added: "2.4"
- vnic_profile_mappings:
- description:
- - "Mapper which maps an external virtual NIC profile to one that exists in the engine when C(state) is registered.
- vnic_profile is described by the following dictionary:"
- suboptions:
- source_network_name:
- description:
- - The network name of the source network.
- source_profile_name:
- description:
- - The profile name related to the source network.
- target_profile_id:
- description:
- - The id of the target profile id to be mapped to in the engine.
- version_added: "2.5"
- cluster_mappings:
- description:
- - "Mapper which maps cluster name between VM's OVF and the destination cluster this VM should be registered to,
- relevant when C(state) is registered.
- Cluster mapping is described by the following dictionary:"
- suboptions:
- source_name:
- description:
- - The name of the source cluster.
- dest_name:
- description:
- - The name of the destination cluster.
- version_added: "2.5"
- role_mappings:
- description:
- - "Mapper which maps role name between VM's OVF and the destination role this VM should be registered to,
- relevant when C(state) is registered.
- Role mapping is described by the following dictionary:"
- suboptions:
- source_name:
- description:
- - The name of the source role.
- dest_name:
- description:
- - The name of the destination role.
- version_added: "2.5"
- domain_mappings:
- description:
- - "Mapper which maps aaa domain name between VM's OVF and the destination aaa domain this VM should be registered to,
- relevant when C(state) is registered.
- The aaa domain mapping is described by the following dictionary:"
- suboptions:
- source_name:
- description:
- - The name of the source aaa domain.
- dest_name:
- description:
- - The name of the destination aaa domain.
- version_added: "2.5"
- affinity_group_mappings:
- description:
- - "Mapper which maps affinity name between VM's OVF and the destination affinity this VM should be registered to,
- relevant when C(state) is registered."
- version_added: "2.5"
- affinity_label_mappings:
- description:
- - "Mapper which maps affinity label name between VM's OVF and the destination label this VM should be registered to,
- relevant when C(state) is registered."
- version_added: "2.5"
- lun_mappings:
- description:
- - "Mapper which maps lun between VM's OVF and the destination lun this VM should contain, relevant when C(state) is registered.
- lun_mappings is described by the following dictionary:
- - C(logical_unit_id): The logical unit number to identify a logical unit,
- - C(logical_unit_port): The port being used to connect with the LUN disk.
- - C(logical_unit_portal): The portal being used to connect with the LUN disk.
- - C(logical_unit_address): The address of the block storage host.
- - C(logical_unit_target): The iSCSI specification located on an iSCSI server
- - C(logical_unit_username): Username to be used to connect to the block storage host.
- - C(logical_unit_password): Password to be used to connect to the block storage host.
- - C(storage_type): The storage type which the LUN reside on (iscsi or fcp)"
- version_added: "2.5"
- reassign_bad_macs:
- description:
- - "Boolean indication whether to reassign bad macs when C(state) is registered."
- type: bool
- version_added: "2.5"
- template:
- description:
- - Name of the template, which should be used to create Virtual Machine.
- - Required if creating VM.
- - If template is not specified and VM doesn't exist, VM will be created from I(Blank) template.
- template_version:
- description:
- - Version number of the template to be used for VM.
- - By default the latest available version of the template is used.
- version_added: "2.3"
- use_latest_template_version:
- description:
- - Specify if latest template version should be used, when running a stateless VM.
- - If this parameter is set to I(yes) stateless VM is created.
- type: bool
- version_added: "2.3"
- storage_domain:
- description:
- - Name of the storage domain where all template disks should be created.
- - This parameter is considered only when C(template) is provided.
- - IMPORTANT - This parameter is not idempotent, if the VM exists and you specify different storage domain,
- disk won't move.
- version_added: "2.4"
- disk_format:
- description:
- - Specify format of the disk.
- - If C(cow) format is used, disk will by created as sparse, so space will be allocated for the volume as needed, also known as I(thin provision).
- - If C(raw) format is used, disk storage will be allocated right away, also known as I(preallocated).
- - Note that this option isn't idempotent as it's not currently possible to change format of the disk via API.
- - This parameter is considered only when C(template) and C(storage domain) is provided.
- choices: [ cow, raw ]
- default: cow
- version_added: "2.4"
- 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.
- version_added: "2.5"
- cpu_shares:
- description:
- - Set a CPU shares for this Virtual Machine.
- - Default value is set by oVirt/RHV engine.
- cpu_cores:
- description:
- - Number of virtual CPUs cores of the Virtual Machine.
- - Default value is set by oVirt/RHV engine.
- cpu_sockets:
- description:
- - Number of virtual CPUs sockets of the Virtual Machine.
- - Default value is set by oVirt/RHV engine.
- cpu_threads:
- description:
- - Number of threads per core of the Virtual Machine.
- - Default value is set by oVirt/RHV engine.
- version_added: "2.5"
- type:
- description:
- - Type of the Virtual Machine.
- - Default value is set by oVirt/RHV engine.
- - I(high_performance) is supported since Ansible 2.5 and oVirt/RHV 4.2.
- choices: [ desktop, server, high_performance ]
- quota_id:
- description:
- - "Virtual Machine quota ID to be used for disk. By default quota is chosen by oVirt/RHV engine."
- version_added: "2.5"
- operating_system:
- description:
- - Operating system of the Virtual Machine.
- - Default value is set by oVirt/RHV engine.
- - "Possible values: debian_7, freebsd, freebsdx64, other, other_linux,
- other_linux_ppc64, other_ppc64, rhel_3, rhel_4, rhel_4x64, rhel_5, rhel_5x64,
- rhel_6, rhel_6x64, rhel_6_ppc64, rhel_7x64, rhel_7_ppc64, sles_11, sles_11_ppc64,
- ubuntu_12_04, ubuntu_12_10, ubuntu_13_04, ubuntu_13_10, ubuntu_14_04, ubuntu_14_04_ppc64,
- windows_10, windows_10x64, windows_2003, windows_2003x64, windows_2008, windows_2008x64,
- windows_2008r2x64, windows_2008R2x64, windows_2012x64, windows_2012R2x64, windows_7,
- windows_7x64, windows_8, windows_8x64, windows_xp"
- boot_devices:
- description:
- - List of boot devices which should be used to boot. For example C([ cdrom, hd ]).
- - Default value is set by oVirt/RHV engine.
- choices: [ cdrom, hd, network ]
- boot_menu:
- description:
- - "I(True) enable menu to select boot device, I(False) to disable it. By default is chosen by oVirt/RHV engine."
- type: bool
- version_added: "2.5"
- usb_support:
- description:
- - "I(True) enable USB support, I(False) to disable it. By default is chosen by oVirt/RHV engine."
- type: bool
- version_added: "2.5"
- serial_console:
- description:
- - "I(True) enable VirtIO serial console, I(False) to disable it. By default is chosen by oVirt/RHV engine."
- type: bool
- version_added: "2.5"
- 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
- version_added: "2.5"
- host:
- description:
- - Specify host where Virtual Machine should be running. By default the host is chosen by engine scheduler.
- - This parameter is used only when C(state) is I(running) or I(present).
- high_availability:
- description:
- - If I(yes) Virtual Machine will be set as highly available.
- - If I(no) Virtual Machine won't be set as highly available.
- - If no value is passed, default value is set by oVirt/RHV engine.
- type: bool
- high_availability_priority:
- description:
- - Indicates the priority of the virtual machine inside the run and migration queues.
- Virtual machines with higher priorities will be started and migrated before virtual machines with lower
- priorities. The value is an integer between 0 and 100. The higher the value, the higher the priority.
- - If no value is passed, default value is set by oVirt/RHV engine.
- version_added: "2.5"
- lease:
- description:
- - Name of the storage domain this virtual machine lease reside on. Pass an empty string to remove the lease.
- - NOTE - Supported since oVirt 4.1.
- version_added: "2.4"
- custom_compatibility_version:
- description:
- - "Enables a virtual machine to be customized to its own compatibility version. If
- 'C(custom_compatibility_version)' is set, it overrides the cluster's compatibility version
- for this particular virtual machine."
- version_added: "2.7"
- host_devices:
- description:
- - Single Root I/O Virtualization - technology that allows single device to expose multiple endpoints that can be passed to VMs
- - host_devices is an list which contain dictionary with name and state of device
- version_added: "2.7"
- delete_protected:
- description:
- - If I(yes) Virtual Machine will be set as delete protected.
- - If I(no) Virtual Machine won't be set as delete protected.
- - If no value is passed, default value is set by oVirt/RHV engine.
- type: bool
- stateless:
- description:
- - If I(yes) Virtual Machine will be set as stateless.
- - If I(no) Virtual Machine will be unset as stateless.
- - If no value is passed, default value is set by oVirt/RHV engine.
- type: bool
- clone:
- description:
- - If I(yes) then the disks of the created virtual machine will be cloned and independent of the template.
- - This parameter is used only when C(state) is I(running) or I(present) and VM didn't exist before.
- type: bool
- default: 'no'
- clone_permissions:
- description:
- - If I(yes) then the permissions of the template (only the direct ones, not the inherited ones)
- will be copied to the created virtual machine.
- - This parameter is used only when C(state) is I(running) or I(present) and VM didn't exist before.
- type: bool
- default: 'no'
- cd_iso:
- description:
- - ISO file from ISO storage domain which should be attached to Virtual Machine.
- - If you pass empty string the CD will be ejected from VM.
- - If used with C(state) I(running) or I(present) and VM is running the CD will be attached to VM.
- - If used with C(state) I(running) or I(present) and VM is down the CD will be attached to VM persistently.
- force:
- description:
- - Please check to I(Synopsis) to more detailed description of force parameter, it can behave differently
- in different situations.
- type: bool
- default: 'no'
- nics:
- description:
- - List of NICs, which should be attached to Virtual Machine. NIC is described by following dictionary.
- suboptions:
- name:
- description:
- - Name of the NIC.
- profile_name:
- description:
- - Profile name where NIC should be attached.
- interface:
- description:
- - Type of the network interface.
- choices: ['virtio', 'e1000', 'rtl8139']
- default: 'virtio'
- mac_address:
- description:
- - 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_nic) module instead."
- disks:
- description:
- - List of disks, which should be attached to Virtual Machine. Disk is described by following dictionary.
- suboptions:
- name:
- description:
- - Name of the disk. Either C(name) or C(id) is required.
- id:
- description:
- - ID of the disk. Either C(name) or C(id) is required.
- interface:
- description:
- - Interface of the disk.
- choices: ['virtio', 'ide']
- default: 'virtio'
- bootable:
- description:
- - I(True) if the disk should be bootable, default is non bootable.
- type: bool
- activate:
- description:
- - I(True) if the disk should be activated, default is activated.
- - "NOTE - This parameter is used only when C(state) is I(running) or I(present) and is able to only attach disks.
- To manage disks of the VM in more depth please use M(ovirt_disk) module instead."
- type: bool
- sysprep:
- description:
- - Dictionary with values for Windows Virtual Machine initialization using sysprep.
- suboptions:
- host_name:
- description:
- - Hostname to be set to Virtual Machine when deployed.
- active_directory_ou:
- description:
- - Active Directory Organizational Unit, to be used for login of user.
- org_name:
- description:
- - Organization name to be set to Windows Virtual Machine.
- domain:
- description:
- - Domain to be set to Windows Virtual Machine.
- timezone:
- description:
- - Timezone to be set to Windows Virtual Machine.
- ui_language:
- description:
- - UI language of the Windows Virtual Machine.
- system_locale:
- description:
- - System localization of the Windows Virtual Machine.
- input_locale:
- description:
- - Input localization of the Windows Virtual Machine.
- windows_license_key:
- description:
- - License key to be set to Windows Virtual Machine.
- user_name:
- description:
- - Username to be used for set password to Windows Virtual Machine.
- root_password:
- description:
- - Password to be set for username to Windows Virtual Machine.
- cloud_init:
- description:
- - Dictionary with values for Unix-like Virtual Machine initialization using cloud init.
- suboptions:
- host_name:
- description:
- - Hostname to be set to Virtual Machine when deployed.
- timezone:
- description:
- - Timezone to be set to Virtual Machine when deployed.
- user_name:
- description:
- - Username to be used to set password to Virtual Machine when deployed.
- root_password:
- description:
- - Password to be set for user specified by C(user_name) parameter.
- authorized_ssh_keys:
- description:
- - Use this SSH keys to login to Virtual Machine.
- regenerate_ssh_keys:
- description:
- - If I(True) SSH keys will be regenerated on Virtual Machine.
- type: bool
- custom_script:
- description:
- - 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.
- dns_servers:
- description:
- - DNS servers to be configured on Virtual Machine.
- dns_search:
- description:
- - DNS search domains to be configured on Virtual Machine.
- nic_boot_protocol:
- description:
- - Set boot protocol of the network interface of Virtual Machine.
- choices: ['none', 'dhcp', 'static']
- nic_ip_address:
- description:
- - If boot protocol is static, set this IP address to network interface of Virtual Machine.
- nic_netmask:
- description:
- - If boot protocol is static, set this netmask to network interface of Virtual Machine.
- nic_gateway:
- description:
- - If boot protocol is static, set this gateway to network interface of Virtual Machine.
- nic_boot_protocol_v6:
- description:
- - Set boot protocol of the network interface of Virtual Machine.
- choices: ['none', 'dhcp', 'static']
- version_added: "2.9"
- nic_ip_address_v6:
- description:
- - If boot protocol is static, set this IP address to network interface of Virtual Machine.
- version_added: "2.9"
- nic_netmask_v6:
- description:
- - If boot protocol is static, set this netmask to network interface of Virtual Machine.
- version_added: "2.9"
- nic_gateway_v6:
- description:
- - If boot protocol is static, set this gateway to network interface of Virtual Machine.
- - For IPv6 addresses the value is an integer in the range of 0-128, which represents the subnet prefix.
- version_added: "2.9"
- nic_name:
- description:
- - Set name to network interface of Virtual Machine.
- nic_on_boot:
- description:
- - If I(True) network interface will be set to start on boot.
- type: bool
- cloud_init_nics:
- description:
- - List of dictionaries representing network interfaces to be setup by cloud init.
- - This option is used, when user needs to setup more network interfaces via cloud init.
- - If one network interface is enough, user should use C(cloud_init) I(nic_*) parameters. C(cloud_init) I(nic_*) parameters
- are merged with C(cloud_init_nics) parameters.
- suboptions:
- nic_boot_protocol:
- description:
- - Set boot protocol of the network interface of Virtual Machine. Can be one of C(none), C(dhcp) or C(static).
- nic_ip_address:
- description:
- - If boot protocol is static, set this IP address to network interface of Virtual Machine.
- nic_netmask:
- description:
- - If boot protocol is static, set this netmask to network interface of Virtual Machine.
- nic_gateway:
- description:
- - If boot protocol is static, set this gateway to network interface of Virtual Machine.
- nic_boot_protocol_v6:
- description:
- - Set boot protocol of the network interface of Virtual Machine. Can be one of C(none), C(dhcp) or C(static).
- version_added: "2.9"
- nic_ip_address_v6:
- description:
- - If boot protocol is static, set this IP address to network interface of Virtual Machine.
- version_added: "2.9"
- nic_netmask_v6:
- description:
- - If boot protocol is static, set this netmask to network interface of Virtual Machine.
- version_added: "2.9"
- nic_gateway_v6:
- description:
- - If boot protocol is static, set this gateway to network interface of Virtual Machine.
- - For IPv6 addresses the value is an integer in the range of 0-128, which represents the subnet prefix.
- version_added: "2.9"
- nic_name:
- description:
- - Set name to network interface of Virtual Machine.
- nic_on_boot:
- description:
- - If I(True) network interface will be set to start on boot.
- type: bool
- version_added: "2.3"
- cloud_init_persist:
- description:
- - "If I(yes) the C(cloud_init) or C(sysprep) parameters will be saved for the virtual machine
- and the virtual machine won't be started as run-once."
- type: bool
- version_added: "2.5"
- aliases: [ 'sysprep_persist' ]
- default: 'no'
- kernel_params_persist:
- description:
- - "If I(true) C(kernel_params), C(initrd_path) and C(kernel_path) will persist in virtual machine configuration,
- if I(False) it will be used for run once."
- type: bool
- version_added: "2.8"
- kernel_path:
- description:
- - Path to a kernel image used to boot the virtual machine.
- - Kernel image must be stored on either the ISO domain or on the host's storage.
- version_added: "2.3"
- initrd_path:
- description:
- - Path to an initial ramdisk to be used with the kernel specified by C(kernel_path) option.
- - Ramdisk image must be stored on either the ISO domain or on the host's storage.
- version_added: "2.3"
- kernel_params:
- description:
- - Kernel command line parameters (formatted as string) to be used with the kernel specified by C(kernel_path) option.
- version_added: "2.3"
- instance_type:
- description:
- - Name of virtual machine's hardware configuration.
- - By default no instance type is used.
- version_added: "2.3"
- description:
- description:
- - Description of the Virtual Machine.
- version_added: "2.3"
- comment:
- description:
- - Comment of the Virtual Machine.
- version_added: "2.3"
- timezone:
- description:
- - Sets time zone offset of the guest hardware clock.
- - For example C(Etc/GMT)
- version_added: "2.3"
- serial_policy:
- description:
- - Specify a serial number policy for the Virtual Machine.
- - Following options are supported.
- - C(vm) - Sets the Virtual Machine's UUID as its serial number.
- - C(host) - Sets the host's UUID as the Virtual Machine's serial number.
- - C(custom) - Allows you to specify a custom serial number in C(serial_policy_value).
- choices: ['vm', 'host', 'custom']
- version_added: "2.3"
- serial_policy_value:
- description:
- - Allows you to specify a custom serial number.
- - This parameter is used only when C(serial_policy) is I(custom).
- version_added: "2.3"
- vmware:
- description:
- - Dictionary of values to be used to connect to VMware and import
- a virtual machine to oVirt.
- suboptions:
- username:
- description:
- - The username to authenticate against the VMware.
- password:
- description:
- - The password to authenticate against the VMware.
- url:
- description:
- - The URL to be passed to the I(virt-v2v) tool for conversion.
- - For example I(vpx://wmware_user@vcenter-host/DataCenter/Cluster/esxi-host?no_verify=1)
- drivers_iso:
- description:
- - The name of the ISO containing drivers that can be used during the I(virt-v2v) conversion process.
- sparse:
- description:
- - Specifies the disk allocation policy of the resulting virtual machine. I(true) for sparse, I(false) for preallocated.
- type: bool
- default: true
- storage_domain:
- description:
- - Specifies the target storage domain for converted disks. This is required parameter.
- version_added: "2.3"
- xen:
- description:
- - Dictionary of values to be used to connect to XEN and import
- a virtual machine to oVirt.
- suboptions:
- url:
- description:
- - The URL to be passed to the I(virt-v2v) tool for conversion.
- - For example I(xen+ssh://root@zen.server). This is required parameter.
- drivers_iso:
- description:
- - The name of the ISO containing drivers that can be used during the I(virt-v2v) conversion process.
- sparse:
- description:
- - Specifies the disk allocation policy of the resulting virtual machine. I(true) for sparse, I(false) for preallocated.
- type: bool
- default: true
- storage_domain:
- description:
- - Specifies the target storage domain for converted disks. This is required parameter.
- version_added: "2.3"
- kvm:
- description:
- - Dictionary of values to be used to connect to kvm and import
- a virtual machine to oVirt.
- suboptions:
- name:
- description:
- - The name of the KVM virtual machine.
- username:
- description:
- - The username to authenticate against the KVM.
- password:
- description:
- - The password to authenticate against the KVM.
- url:
- description:
- - The URL to be passed to the I(virt-v2v) tool for conversion.
- - For example I(qemu:///system). This is required parameter.
- drivers_iso:
- description:
- - The name of the ISO containing drivers that can be used during the I(virt-v2v) conversion process.
- sparse:
- description:
- - Specifies the disk allocation policy of the resulting virtual machine. I(true) for sparse, I(false) for preallocated.
- type: bool
- default: true
- storage_domain:
- description:
- - Specifies the target storage domain for converted disks. This is required parameter.
- version_added: "2.3"
- cpu_mode:
- description:
- - "CPU mode of the virtual machine. It can be some of the following: I(host_passthrough), I(host_model) or I(custom)."
- - "For I(host_passthrough) CPU type you need to set C(placement_policy) to I(pinned)."
- - "If no value is passed, default value is set by oVirt/RHV engine."
- version_added: "2.5"
- placement_policy:
- description:
- - "The configuration of the virtual machine's placement policy."
- - "If no value is passed, default value is set by oVirt/RHV engine."
- - "Placement policy can be one of the following values:"
- suboptions:
- migratable:
- description:
- - "Allow manual and automatic migration."
- pinned:
- description:
- - "Do not allow migration."
- user_migratable:
- description:
- - "Allow manual migration only."
- version_added: "2.5"
- ticket:
- description:
- - "If I(true), in addition return I(remote_vv_file) inside I(vm) dictionary, which contains compatible
- content for remote-viewer application. Works only C(state) is I(running)."
- version_added: "2.7"
- type: bool
- cpu_pinning:
- description:
- - "CPU Pinning topology to map virtual machine CPU to host CPU."
- - "CPU Pinning topology is a list of dictionary which can have following values:"
- suboptions:
- cpu:
- description:
- - "Number of the host CPU."
- vcpu:
- description:
- - "Number of the virtual machine CPU."
- version_added: "2.5"
- soundcard_enabled:
- description:
- - "If I(true), the sound card is added to the virtual machine."
- type: bool
- version_added: "2.5"
- smartcard_enabled:
- description:
- - "If I(true), use smart card authentication."
- type: bool
- version_added: "2.5"
- io_threads:
- description:
- - "Number of IO threads used by virtual machine. I(0) means IO threading disabled."
- version_added: "2.5"
- ballooning_enabled:
- description:
- - "If I(true), use memory ballooning."
- - "Memory balloon is a guest device, which may be used to re-distribute / reclaim the host memory
- based on VM needs in a dynamic way. In this way it's possible to create memory over commitment states."
- type: bool
- version_added: "2.5"
- numa_tune_mode:
- description:
- - "Set how the memory allocation for NUMA nodes of this VM is applied (relevant if NUMA nodes are set for this VM)."
- - "It can be one of the following: I(interleave), I(preferred) or I(strict)."
- - "If no value is passed, default value is set by oVirt/RHV engine."
- choices: ['interleave', 'preferred', 'strict']
- version_added: "2.6"
- numa_nodes:
- description:
- - "List of vNUMA Nodes to set for this VM and pin them to assigned host's physical NUMA node."
- - "Each vNUMA node is described by following dictionary:"
- suboptions:
- index:
- description:
- - "The index of this NUMA node."
- required: True
- memory:
- description:
- - "Memory size of the NUMA node in MiB."
- required: True
- cores:
- description:
- - "List of VM CPU cores indexes to be included in this NUMA node."
- type: list
- required: True
- numa_node_pins:
- description:
- - "List of physical NUMA node indexes to pin this virtual NUMA node to."
- type: list
- version_added: "2.6"
- rng_device:
- description:
- - "Random number generator (RNG). You can choose of one the following devices I(urandom), I(random) or I(hwrng)."
- - "In order to select I(hwrng), you must have it enabled on cluster first."
- - "/dev/urandom is used for cluster version >= 4.1, and /dev/random for cluster version <= 4.0"
- version_added: "2.5"
- custom_properties:
- description:
- - "Properties sent to VDSM to configure various hooks."
- - "Custom properties is a list of dictionary which can have following values:"
- suboptions:
- name:
- description:
- - "Name of the custom property. For example: I(hugepages), I(vhost), I(sap_agent), etc."
- regexp:
- description:
- - "Regular expression to set for custom property."
- value:
- description:
- - "Value to set for custom property."
- version_added: "2.5"
- watchdog:
- description:
- - "Assign watchdog device for the virtual machine."
- - "Watchdogs is a dictionary which can have following values:"
- suboptions:
- model:
- description:
- - "Model of the watchdog device. For example: I(i6300esb), I(diag288) or I(null)."
- action:
- description:
- - "Watchdog action to be performed when watchdog is triggered. For example: I(none), I(reset), I(poweroff), I(pause) or I(dump)."
- version_added: "2.5"
- graphical_console:
- description:
- - "Assign graphical console to the virtual machine."
- suboptions:
- headless_mode:
- description:
- - If I(true) disable the graphics console for this virtual machine.
- type: bool
- protocol:
- description:
- - Graphical protocol, a list of I(spice), I(vnc), or both.
- type: list
- disconnect_action:
- description:
- - "Returns the action that will take place when the graphic console(SPICE only) is disconnected. The options are:"
- - I(none) No action is taken.
- - I(lock_screen) Locks the currently active user session.
- - I(logout) Logs out the currently active user session.
- - I(reboot) Initiates a graceful virtual machine reboot.
- - I(shutdown) Initiates a graceful virtual machine shutdown.
- type: str
- version_added: "2.10"
- keyboard_layout:
- description:
- - The keyboard layout to use with this graphic console.
- - This option is only available for the VNC console type.
- - If no keyboard is enabled then it won't be reported.
- type: str
- version_added: "2.10"
- monitors:
- description:
- - The number of monitors opened for this graphic console.
- - This option is only available for the SPICE protocol.
- - Possible values are 1, 2 or 4.
- type: int
- version_added: "2.10"
- version_added: "2.5"
- exclusive:
- description:
- - "When C(state) is I(exported) this parameter indicates if the existing VM with the
- same name should be overwritten."
- version_added: "2.8"
- type: bool
- export_domain:
- description:
- - "When C(state) is I(exported)this parameter specifies the name of the export storage domain."
- version_added: "2.8"
- export_ova:
- description:
- - Dictionary of values to be used to export VM as OVA.
- suboptions:
- host:
- description:
- - The name of the destination host where the OVA has to be exported.
- directory:
- description:
- - The name of the directory where the OVA has to be exported.
- filename:
- description:
- - The name of the exported OVA file.
- version_added: "2.8"
- force_migrate:
- description:
- - If I(true), the VM will migrate when I(placement_policy=user-migratable) but not when I(placement_policy=pinned).
- version_added: "2.8"
- type: bool
- migrate:
- description:
- - "If I(true), the VM will migrate to any available host."
- version_added: "2.8"
- type: bool
- next_run:
- description:
- - "If I(true), the update will not be applied to the VM immediately and will be only applied when virtual machine is restarted."
- - NOTE - If there are multiple next run configuration changes on the VM, the first change may get reverted if this option is not passed.
- version_added: "2.8"
- type: bool
- snapshot_name:
- description:
- - "Snapshot to clone VM from."
- - "Snapshot with description specified should exist."
- - "You have to specify C(snapshot_vm) parameter with virtual machine name of this snapshot."
- version_added: "2.9"
- snapshot_vm:
- description:
- - "Source VM to clone VM from."
- - "VM should have snapshot specified by C(snapshot)."
- - "If C(snapshot_name) specified C(snapshot_vm) is required."
- version_added: "2.9"
- custom_emulated_machine:
- description:
- - "Sets the value of the custom_emulated_machine attribute."
- version_added: "2.10"
-
-notes:
- - If VM is in I(UNASSIGNED) or I(UNKNOWN) state before any operation, the module will fail.
- If VM is in I(IMAGE_LOCKED) state before any operation, we try to wait for VM to be I(DOWN).
- If VM is in I(SAVING_STATE) state before any operation, we try to wait for VM to be I(SUSPENDED).
- If VM is in I(POWERING_DOWN) state before any operation, we try to wait for VM to be I(UP) or I(DOWN). VM can
- get into I(UP) state from I(POWERING_DOWN) state, when there is no ACPI or guest agent running inside VM, or
- if the shutdown operation fails.
- When user specify I(UP) C(state), we always wait to VM to be in I(UP) state in case VM is I(MIGRATING),
- I(REBOOTING), I(POWERING_UP), I(RESTORING_STATE), I(WAIT_FOR_LAUNCH). In other states we run start operation on VM.
- When user specify I(stopped) C(state), and If user pass C(force) parameter set to I(true) we forcibly stop the VM in
- any state. If user don't pass C(force) parameter, we always wait to VM to be in UP state in case VM is
- I(MIGRATING), I(REBOOTING), I(POWERING_UP), I(RESTORING_STATE), I(WAIT_FOR_LAUNCH). If VM is in I(PAUSED) or
- I(SUSPENDED) state, we start the VM. Then we gracefully shutdown the VM.
- When user specify I(suspended) C(state), we always wait to VM to be in UP state in case VM is I(MIGRATING),
- I(REBOOTING), I(POWERING_UP), I(RESTORING_STATE), I(WAIT_FOR_LAUNCH). If VM is in I(PAUSED) or I(DOWN) state,
- we start the VM. Then we suspend the VM.
- When user specify I(absent) C(state), we forcibly stop the VM in any state and remove it.
- - "If you update a VM parameter that requires a reboot, the oVirt engine always creates a new snapshot for the VM,
- and an Ansible playbook will report this as changed."
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-- name: Creates a new Virtual Machine from template named 'rhel7_template'
- ovirt_vm:
- state: present
- name: myvm
- template: rhel7_template
- cluster: mycluster
-
-- name: Register VM
- ovirt_vm:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- name: myvm
-
-- name: Register VM using id
- ovirt_vm:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- id: 1111-1111-1111-1111
-
-- name: Register VM, allowing partial import
- ovirt_vm:
- state: registered
- storage_domain: mystorage
- allow_partial_import: "True"
- cluster: mycluster
- id: 1111-1111-1111-1111
-
-- name: Register VM with vnic profile mappings and reassign bad macs
- ovirt_vm:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- id: 1111-1111-1111-1111
- vnic_profile_mappings:
- - source_network_name: mynetwork
- source_profile_name: mynetwork
- target_profile_id: 3333-3333-3333-3333
- - source_network_name: mynetwork2
- source_profile_name: mynetwork2
- target_profile_id: 4444-4444-4444-4444
- reassign_bad_macs: "True"
-
-- name: Register VM with mappings
- ovirt_vm:
- state: registered
- storage_domain: mystorage
- cluster: mycluster
- id: 1111-1111-1111-1111
- role_mappings:
- - source_name: Role_A
- dest_name: Role_B
- domain_mappings:
- - source_name: Domain_A
- dest_name: Domain_B
- lun_mappings:
- - source_storage_type: iscsi
- source_logical_unit_id: 1IET_000d0001
- source_logical_unit_port: 3260
- source_logical_unit_portal: 1
- source_logical_unit_address: 10.34.63.203
- source_logical_unit_target: iqn.2016-08-09.brq.str-01:omachace
- dest_storage_type: iscsi
- dest_logical_unit_id: 1IET_000d0002
- dest_logical_unit_port: 3260
- dest_logical_unit_portal: 1
- dest_logical_unit_address: 10.34.63.204
- dest_logical_unit_target: iqn.2016-08-09.brq.str-02:omachace
- affinity_group_mappings:
- - source_name: Affinity_A
- dest_name: Affinity_B
- affinity_label_mappings:
- - source_name: Label_A
- dest_name: Label_B
- cluster_mappings:
- - source_name: cluster_A
- dest_name: cluster_B
-
-- name: Creates a stateless VM which will always use latest template version
- ovirt_vm:
- name: myvm
- template: rhel7
- cluster: mycluster
- use_latest_template_version: true
-
-# Creates a new server rhel7 Virtual Machine from Blank template
-# on brq01 cluster with 2GiB memory and 2 vcpu cores/sockets
-# and attach bootable disk with name rhel7_disk and attach virtio NIC
-- ovirt_vm:
- state: present
- cluster: brq01
- name: myvm
- memory: 2GiB
- cpu_cores: 2
- cpu_sockets: 2
- cpu_shares: 1024
- type: server
- operating_system: rhel_7x64
- disks:
- - name: rhel7_disk
- bootable: True
- nics:
- - name: nic1
-
-# Change VM Name
-- ovirt_vm:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_vm_name"
-
-- name: Run VM with cloud init
- ovirt_vm:
- name: rhel7
- template: rhel7
- cluster: Default
- memory: 1GiB
- high_availability: true
- high_availability_priority: 50 # Available from Ansible 2.5
- 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
- nic_on_boot: true
- host_name: example.com
- custom_script: |
- write_files:
- - content: |
- Hello, world!
- path: /tmp/greeting.txt
- permissions: '0644'
- user_name: root
- root_password: super_password
-
-- name: Run VM with cloud init, with multiple network interfaces
- ovirt_vm:
- name: rhel7_4
- template: rhel7
- cluster: mycluster
- cloud_init_nics:
- - nic_name: eth0
- nic_boot_protocol: dhcp
- nic_on_boot: true
- - nic_name: eth1
- nic_boot_protocol: static
- nic_ip_address: 10.34.60.86
- nic_netmask: 255.255.252.0
- nic_gateway: 10.34.63.254
- nic_on_boot: true
- # IP version 6 parameters are supported since ansible 2.9
- - nic_name: eth2
- nic_boot_protocol_v6: static
- nic_ip_address_v6: '2620:52:0:2282:b898:1f69:6512:36c5'
- nic_gateway_v6: '2620:52:0:2282:b898:1f69:6512:36c9'
- nic_netmask_v6: '120'
- nic_on_boot: true
- - nic_name: eth3
- nic_on_boot: true
- nic_boot_protocol_v6: dhcp
-
-- name: Run VM with sysprep
- ovirt_vm:
- name: windows2012R2_AD
- template: windows2012R2
- cluster: Default
- memory: 3GiB
- high_availability: true
- sysprep:
- host_name: windowsad.example.com
- user_name: Administrator
- root_password: SuperPassword123
-
-- name: Migrate/Run VM to/on host named 'host1'
- ovirt_vm:
- state: running
- name: myvm
- host: host1
-
-- name: Migrate VM to any available host
- ovirt_vm:
- state: running
- name: myvm
- migrate: true
-
-- name: Change VMs CD
- ovirt_vm:
- name: myvm
- cd_iso: drivers.iso
-
-- name: Eject VMs CD
- ovirt_vm:
- name: myvm
- cd_iso: ''
-
-- name: Boot VM from CD
- ovirt_vm:
- name: myvm
- cd_iso: centos7_x64.iso
- boot_devices:
- - cdrom
-
-- name: Stop vm
- ovirt_vm:
- state: stopped
- name: myvm
-
-- name: Upgrade memory to already created VM
- ovirt_vm:
- name: myvm
- memory: 4GiB
-
-- name: Hot plug memory to already created and running VM (VM won't be restarted)
- ovirt_vm:
- name: myvm
- memory: 4GiB
-
-# Create/update a VM to run with two vNUMA nodes and pin them to physical NUMA nodes as follows:
-# vnuma index 0-> numa index 0, vnuma index 1-> numa index 1
-- name: Create a VM to run with two vNUMA nodes
- ovirt_vm:
- name: myvm
- cluster: mycluster
- numa_tune_mode: "interleave"
- numa_nodes:
- - index: 0
- cores: [0]
- memory: 20
- numa_node_pins: [0]
- - index: 1
- cores: [1]
- memory: 30
- numa_node_pins: [1]
-
-- name: Update an existing VM to run without previously created vNUMA nodes (i.e. remove all vNUMA nodes+NUMA pinning setting)
- ovirt_vm:
- name: myvm
- cluster: mycluster
- state: "present"
- numa_tune_mode: "interleave"
- numa_nodes:
- - index: -1
-
-# When change on the VM needs restart of the VM, use next_run state,
-# The VM will be updated and rebooted if there are any changes.
-# If present state would be used, VM won't be restarted.
-- ovirt_vm:
- state: next_run
- name: myvm
- boot_devices:
- - network
-
-- name: Import virtual machine from VMware
- ovirt_vm:
- state: stopped
- cluster: mycluster
- name: vmware_win10
- timeout: 1800
- poll_interval: 30
- vmware:
- url: vpx://user@1.2.3.4/Folder1/Cluster1/2.3.4.5?no_verify=1
- name: windows10
- storage_domain: mynfs
- username: user
- password: password
-
-- name: Create vm from template and create all disks on specific storage domain
- ovirt_vm:
- name: vm_test
- cluster: mycluster
- template: mytemplate
- storage_domain: mynfs
- nics:
- - name: nic1
-
-- name: Remove VM, if VM is running it will be stopped
- ovirt_vm:
- state: absent
- name: myvm
-
-# Defining a specific quota for a VM:
-# Since Ansible 2.5
-- ovirt_quotas_facts:
- data_center: Default
- name: myquota
-- ovirt_vm:
- name: myvm
- sso: False
- boot_menu: True
- usb_support: True
- serial_console: True
- quota_id: "{{ ovirt_quotas[0]['id'] }}"
-
-- name: Create a VM that has the console configured for both Spice and VNC
- ovirt_vm:
- name: myvm
- template: mytemplate
- cluster: mycluster
- graphical_console:
- protocol:
- - spice
- - vnc
-
-# Execute remote viewer to VM
-- block:
- - name: Create a ticket for console for a running VM
- ovirt_vm:
- name: myvm
- ticket: true
- state: running
- register: myvm
-
- - name: Save ticket to file
- copy:
- content: "{{ myvm.vm.remote_vv_file }}"
- dest: ~/vvfile.vv
-
- - name: Run remote viewer with file
- command: remote-viewer ~/vvfile.vv
-
-# Default value of host_device state is present
-- name: Attach host devices to virtual machine
- ovirt_vm:
- name: myvm
- host: myhost
- placement_policy: pinned
- host_devices:
- - name: pci_0000_00_06_0
- - name: pci_0000_00_07_0
- state: absent
- - name: pci_0000_00_08_0
- state: present
-
-- name: Export the VM as OVA
- ovirt_vm:
- name: myvm
- state: exported
- cluster: mycluster
- export_ova:
- host: myhost
- filename: myvm.ova
- directory: /tmp/
-
-- name: Clone VM from snapshot
- ovirt_vm:
- snapshot_vm: myvm
- snapshot_name: myvm_snap
- name: myvm_clone
- state: present
-
-- name: Import external ova VM
- ovirt_vm:
- cluster: mycluster
- name: myvm
- host: myhost
- timeout: 1800
- poll_interval: 30
- kvm:
- name: myvm
- url: ova:///path/myvm.ova
- storage_domain: mystorage
-
-- name: Cpu pinning of 0#12_1#13_2#14_3#15
- ovirt_vm:
- state: present
- cluster: mycluster
- name: myvm
- cpu_pinning:
- - cpu: 12
- vcpu: 0
- - cpu: 13
- vcpu: 1
- - cpu: 14
- vcpu: 2
- - cpu: 15
- vcpu: 3
-'''
-
-
-RETURN = '''
-id:
- description: ID of the VM which is managed
- returned: On success if VM is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-vm:
- description: "Dictionary of all the VM attributes. VM attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm.
- Additionally when user sent ticket=true, this module will return also remote_vv_file
- parameter in vm dictionary, which contains remote-viewer compatible file to open virtual
- machine console. Please note that this file contains sensible information."
- returned: On success if VM is found.
- type: dict
-'''
-import traceback
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_params,
- check_sdk,
- convert_to_bytes,
- create_connection,
- equal,
- get_dict_of_struct,
- get_entity,
- get_link_name,
- get_id_by_name,
- ovirt_full_argument_spec,
- search_by_attributes,
- search_by_name,
- wait,
-)
-
-
-class VmsModule(BaseModule):
-
- def __init__(self, *args, **kwargs):
- super(VmsModule, self).__init__(*args, **kwargs)
- self._initialization = None
- self._is_new = False
-
- def __get_template_with_version(self):
- """
- oVirt/RHV in version 4.1 doesn't support search by template+version_number,
- so we need to list all templates with specific name and then iterate
- through it's version until we find the version we look for.
- """
- template = None
- templates_service = self._connection.system_service().templates_service()
- if self._is_new:
- if self.param('template'):
- clusters_service = self._connection.system_service().clusters_service()
- cluster = search_by_name(clusters_service, self.param('cluster'))
- data_center = self._connection.follow_link(cluster.data_center)
- templates = templates_service.list(
- search='name=%s and datacenter=%s' % (self.param('template'), data_center.name)
- )
- if self.param('template_version'):
- templates = [
- t for t in templates
- if t.version.version_number == self.param('template_version')
- ]
- if not templates:
- raise ValueError(
- "Template with name '%s' and version '%s' in data center '%s' was not found'" % (
- self.param('template'),
- self.param('template_version'),
- data_center.name
- )
- )
- template = sorted(templates, key=lambda t: t.version.version_number, reverse=True)[0]
- else:
- # If template isn't specified and VM is about to be created specify default template:
- template = templates_service.template_service('00000000-0000-0000-0000-000000000000').get()
-
- return template
-
- def __get_storage_domain_and_all_template_disks(self, template):
-
- if self.param('template') is None:
- return None
-
- if self.param('storage_domain') is None:
- return None
-
- disks = list()
-
- for att in self._connection.follow_link(template.disk_attachments):
- disks.append(
- otypes.DiskAttachment(
- disk=otypes.Disk(
- id=att.disk.id,
- format=otypes.DiskFormat(self.param('disk_format')),
- storage_domains=[
- otypes.StorageDomain(
- id=get_id_by_name(
- self._connection.system_service().storage_domains_service(),
- self.param('storage_domain')
- )
- )
- ]
- )
- )
- )
-
- return disks
-
- def __get_snapshot(self):
-
- if self.param('snapshot_vm') is None:
- return None
-
- if self.param('snapshot_name') is None:
- return None
-
- vms_service = self._connection.system_service().vms_service()
- vm_id = get_id_by_name(vms_service, self.param('snapshot_vm'))
- vm_service = vms_service.vm_service(vm_id)
-
- snaps_service = vm_service.snapshots_service()
- snaps = snaps_service.list()
- snap = next(
- (s for s in snaps if s.description == self.param('snapshot_name')),
- None
- )
- return snap
-
- def __get_cluster(self):
- if self.param('cluster') is not None:
- return self.param('cluster')
- elif self.param('snapshot_name') is not None and self.param('snapshot_vm') is not None:
- vms_service = self._connection.system_service().vms_service()
- vm = search_by_name(vms_service, self.param('snapshot_vm'))
- return self._connection.system_service().clusters_service().cluster_service(vm.cluster.id).get().name
-
- def build_entity(self):
- template = self.__get_template_with_version()
- cluster = self.__get_cluster()
- snapshot = self.__get_snapshot()
- display = self.param('graphical_console') or dict()
-
- disk_attachments = self.__get_storage_domain_and_all_template_disks(template)
-
- return otypes.Vm(
- id=self.param('id'),
- name=self.param('name'),
- cluster=otypes.Cluster(
- name=cluster
- ) if cluster else None,
- disk_attachments=disk_attachments,
- template=otypes.Template(
- id=template.id,
- ) if template else None,
- use_latest_template_version=self.param('use_latest_template_version'),
- stateless=self.param('stateless') or self.param('use_latest_template_version'),
- delete_protected=self.param('delete_protected'),
- custom_emulated_machine=self.param('custom_emulated_machine'),
- bios=(
- otypes.Bios(boot_menu=otypes.BootMenu(enabled=self.param('boot_menu')))
- ) if self.param('boot_menu') is not None else None,
- console=(
- otypes.Console(enabled=self.param('serial_console'))
- ) if self.param('serial_console') is not None else None,
- usb=(
- otypes.Usb(enabled=self.param('usb_support'))
- ) if self.param('usb_support') is not None else None,
- sso=(
- otypes.Sso(
- methods=[otypes.Method(id=otypes.SsoMethod.GUEST_AGENT)] if self.param('sso') else []
- )
- ) if self.param('sso') is not None else None,
- quota=otypes.Quota(id=self._module.params.get('quota_id')) if self.param('quota_id') is not None else None,
- high_availability=otypes.HighAvailability(
- enabled=self.param('high_availability'),
- priority=self.param('high_availability_priority'),
- ) if self.param('high_availability') is not None or self.param('high_availability_priority') else None,
- lease=otypes.StorageDomainLease(
- storage_domain=otypes.StorageDomain(
- id=get_id_by_name(
- service=self._connection.system_service().storage_domains_service(),
- name=self.param('lease')
- ) if self.param('lease') else None
- )
- ) if self.param('lease') is not None else None,
- cpu=otypes.Cpu(
- topology=otypes.CpuTopology(
- cores=self.param('cpu_cores'),
- sockets=self.param('cpu_sockets'),
- threads=self.param('cpu_threads'),
- ) if any((
- self.param('cpu_cores'),
- self.param('cpu_sockets'),
- self.param('cpu_threads')
- )) else None,
- cpu_tune=otypes.CpuTune(
- vcpu_pins=[
- otypes.VcpuPin(vcpu=int(pin['vcpu']), cpu_set=str(pin['cpu'])) for pin in self.param('cpu_pinning')
- ],
- ) if self.param('cpu_pinning') else None,
- mode=otypes.CpuMode(self.param('cpu_mode')) if self.param('cpu_mode') else None,
- ) if any((
- self.param('cpu_cores'),
- self.param('cpu_sockets'),
- self.param('cpu_threads'),
- self.param('cpu_mode'),
- self.param('cpu_pinning')
- )) else None,
- cpu_shares=self.param('cpu_shares'),
- os=otypes.OperatingSystem(
- type=self.param('operating_system'),
- boot=otypes.Boot(
- devices=[
- otypes.BootDevice(dev) for dev in self.param('boot_devices')
- ],
- ) if self.param('boot_devices') else None,
- cmdline=self.param('kernel_params') if self.param('kernel_params_persist') else None,
- initrd=self.param('initrd_path') if self.param('kernel_params_persist') else None,
- kernel=self.param('kernel_path') if self.param('kernel_params_persist') else None,
- ) if (
- self.param('operating_system') or self.param('boot_devices') or self.param('kernel_params_persist')
- ) else None,
- type=otypes.VmType(
- self.param('type')
- ) if self.param('type') else None,
- memory=convert_to_bytes(
- self.param('memory')
- ) if self.param('memory') else None,
- memory_policy=otypes.MemoryPolicy(
- guaranteed=convert_to_bytes(self.param('memory_guaranteed')),
- ballooning=self.param('ballooning_enabled'),
- max=convert_to_bytes(self.param('memory_max')),
- ) if any((
- self.param('memory_guaranteed'),
- self.param('ballooning_enabled') is not None,
- self.param('memory_max')
- )) else None,
- instance_type=otypes.InstanceType(
- id=get_id_by_name(
- self._connection.system_service().instance_types_service(),
- self.param('instance_type'),
- ),
- ) if self.param('instance_type') else None,
- custom_compatibility_version=otypes.Version(
- major=self._get_major(self.param('custom_compatibility_version')),
- minor=self._get_minor(self.param('custom_compatibility_version')),
- ) if self.param('custom_compatibility_version') is not None else None,
- description=self.param('description'),
- comment=self.param('comment'),
- time_zone=otypes.TimeZone(
- name=self.param('timezone'),
- ) if self.param('timezone') else None,
- serial_number=otypes.SerialNumber(
- policy=otypes.SerialNumberPolicy(self.param('serial_policy')),
- value=self.param('serial_policy_value'),
- ) if (
- self.param('serial_policy') is not None or
- self.param('serial_policy_value') is not None
- ) else None,
- placement_policy=otypes.VmPlacementPolicy(
- affinity=otypes.VmAffinity(self.param('placement_policy')),
- hosts=[
- otypes.Host(name=self.param('host')),
- ] if self.param('host') else None,
- ) if self.param('placement_policy') else None,
- soundcard_enabled=self.param('soundcard_enabled'),
- display=otypes.Display(
- smartcard_enabled=self.param('smartcard_enabled'),
- disconnect_action=display.get('disconnect_action'),
- keyboard_layout=display.get('keyboard_layout'),
- monitors=display.get('monitors'),
- ) if (
- self.param('smartcard_enabled') is not None or
- display.get('disconnect_action') is not None or
- display.get('keyboard_layout') is not None or
- display.get('monitors') is not None
- ) else None,
- io=otypes.Io(
- threads=self.param('io_threads'),
- ) if self.param('io_threads') is not None else None,
- numa_tune_mode=otypes.NumaTuneMode(
- self.param('numa_tune_mode')
- ) if self.param('numa_tune_mode') else None,
- rng_device=otypes.RngDevice(
- source=otypes.RngSource(self.param('rng_device')),
- ) if self.param('rng_device') else None,
- custom_properties=[
- otypes.CustomProperty(
- name=cp.get('name'),
- regexp=cp.get('regexp'),
- value=str(cp.get('value')),
- ) for cp in self.param('custom_properties') if cp
- ] if self.param('custom_properties') is not None else None,
- initialization=self.get_initialization() if self.param('cloud_init_persist') else None,
- snapshots=[otypes.Snapshot(id=snapshot.id)] if snapshot is not None else None,
- )
-
- def _get_export_domain_service(self):
- provider_name = self._module.params['export_domain']
- export_sds_service = self._connection.system_service().storage_domains_service()
- export_sd_id = get_id_by_name(export_sds_service, provider_name)
- return export_sds_service.service(export_sd_id)
-
- def post_export_action(self, entity):
- self._service = self._get_export_domain_service().vms_service()
-
- def update_check(self, entity):
- res = self._update_check(entity)
- if entity.next_run_configuration_exists:
- res = res and self._update_check(self._service.service(entity.id).get(next_run=True))
-
- return res
-
- def _update_check(self, entity):
- def check_cpu_pinning():
- if self.param('cpu_pinning'):
- current = []
- if entity.cpu.cpu_tune:
- current = [(str(pin.cpu_set), int(pin.vcpu)) for pin in entity.cpu.cpu_tune.vcpu_pins]
- passed = [(str(pin['cpu']), int(pin['vcpu'])) for pin in self.param('cpu_pinning')]
- return sorted(current) == sorted(passed)
- return True
-
- def check_custom_properties():
- if self.param('custom_properties'):
- current = []
- if entity.custom_properties:
- current = [(cp.name, cp.regexp, str(cp.value)) for cp in entity.custom_properties]
- passed = [(cp.get('name'), cp.get('regexp'), str(cp.get('value'))) for cp in self.param('custom_properties') if cp]
- return sorted(current) == sorted(passed)
- return True
-
- def check_host():
- if self.param('host') is not None:
- return self.param('host') in [self._connection.follow_link(host).name for host in getattr(entity.placement_policy, 'hosts', None) or []]
- return True
-
- def check_custom_compatibility_version():
- if self.param('custom_compatibility_version') is not None:
- return (self._get_minor(self.param('custom_compatibility_version')) == self._get_minor(entity.custom_compatibility_version) and
- self._get_major(self.param('custom_compatibility_version')) == self._get_major(entity.custom_compatibility_version))
- return True
-
- cpu_mode = getattr(entity.cpu, 'mode')
- vm_display = entity.display
- provided_vm_display = self.param('graphical_console') or dict()
- return (
- check_cpu_pinning() and
- check_custom_properties() and
- check_host() and
- check_custom_compatibility_version() and
- not self.param('cloud_init_persist') and
- not self.param('kernel_params_persist') and
- equal(self.param('cluster'), get_link_name(self._connection, entity.cluster)) and equal(convert_to_bytes(self.param('memory')), entity.memory) and
- equal(convert_to_bytes(self.param('memory_guaranteed')), entity.memory_policy.guaranteed) and
- equal(convert_to_bytes(self.param('memory_max')), entity.memory_policy.max) and
- equal(self.param('cpu_cores'), entity.cpu.topology.cores) and
- equal(self.param('cpu_sockets'), entity.cpu.topology.sockets) and
- equal(self.param('cpu_threads'), entity.cpu.topology.threads) and
- equal(self.param('cpu_mode'), str(cpu_mode) if cpu_mode else None) and
- equal(self.param('type'), str(entity.type)) and
- equal(self.param('name'), str(entity.name)) and
- equal(self.param('operating_system'), str(entity.os.type)) and
- equal(self.param('boot_menu'), entity.bios.boot_menu.enabled) and
- equal(self.param('soundcard_enabled'), entity.soundcard_enabled) and
- equal(self.param('smartcard_enabled'), getattr(vm_display, 'smartcard_enabled', False)) and
- equal(self.param('io_threads'), entity.io.threads) and
- equal(self.param('ballooning_enabled'), entity.memory_policy.ballooning) and
- equal(self.param('serial_console'), getattr(entity.console, 'enabled', None)) and
- equal(self.param('usb_support'), entity.usb.enabled) and
- equal(self.param('sso'), True if entity.sso.methods else False) and
- equal(self.param('quota_id'), getattr(entity.quota, 'id', None)) and
- equal(self.param('high_availability'), entity.high_availability.enabled) and
- equal(self.param('high_availability_priority'), entity.high_availability.priority) and
- equal(self.param('lease'), get_link_name(self._connection, getattr(entity.lease, 'storage_domain', None))) and
- equal(self.param('stateless'), entity.stateless) and
- equal(self.param('cpu_shares'), entity.cpu_shares) and
- equal(self.param('delete_protected'), entity.delete_protected) and
- equal(self.param('custom_emulated_machine'), entity.custom_emulated_machine) and
- equal(self.param('use_latest_template_version'), entity.use_latest_template_version) and
- equal(self.param('boot_devices'), [str(dev) for dev in getattr(entity.os.boot, 'devices', [])]) and
- equal(self.param('instance_type'), get_link_name(self._connection, entity.instance_type), ignore_case=True) and
- equal(self.param('description'), entity.description) and
- equal(self.param('comment'), entity.comment) and
- equal(self.param('timezone'), getattr(entity.time_zone, 'name', None)) and
- equal(self.param('serial_policy'), str(getattr(entity.serial_number, 'policy', None))) and
- equal(self.param('serial_policy_value'), getattr(entity.serial_number, 'value', None)) and
- equal(self.param('placement_policy'), str(entity.placement_policy.affinity) if entity.placement_policy else None) and
- equal(self.param('numa_tune_mode'), str(entity.numa_tune_mode)) and
- equal(self.param('rng_device'), str(entity.rng_device.source) if entity.rng_device else None) and
- equal(provided_vm_display.get('monitors'), getattr(vm_display, 'monitors', None)) and
- equal(provided_vm_display.get('keyboard_layout'), getattr(vm_display, 'keyboard_layout', None)) and
- equal(provided_vm_display.get('disconnect_action'), getattr(vm_display, 'disconnect_action', None), ignore_case=True)
- )
-
- def pre_create(self, entity):
- # Mark if entity exists before touching it:
- if entity is None:
- self._is_new = True
-
- def post_update(self, entity):
- self.post_present(entity.id)
-
- def post_present(self, entity_id):
- # After creation of the VM, attach disks and NICs:
- entity = self._service.service(entity_id).get()
- self.__attach_disks(entity)
- self.__attach_nics(entity)
- self._attach_cd(entity)
- self.changed = self.__attach_numa_nodes(entity)
- self.changed = self.__attach_watchdog(entity)
- self.changed = self.__attach_graphical_console(entity)
- self.changed = self.__attach_host_devices(entity)
-
- def pre_remove(self, entity):
- # Forcibly stop the VM, if it's not in DOWN state:
- if entity.status != otypes.VmStatus.DOWN:
- if not self._module.check_mode:
- self.changed = self.action(
- action='stop',
- action_condition=lambda vm: vm.status != otypes.VmStatus.DOWN,
- wait_condition=lambda vm: vm.status == otypes.VmStatus.DOWN,
- )['changed']
-
- def __suspend_shutdown_common(self, vm_service):
- if vm_service.get().status in [
- otypes.VmStatus.MIGRATING,
- otypes.VmStatus.POWERING_UP,
- otypes.VmStatus.REBOOT_IN_PROGRESS,
- otypes.VmStatus.WAIT_FOR_LAUNCH,
- otypes.VmStatus.UP,
- otypes.VmStatus.RESTORING_STATE,
- ]:
- self._wait_for_UP(vm_service)
-
- def _pre_shutdown_action(self, entity):
- vm_service = self._service.vm_service(entity.id)
- self.__suspend_shutdown_common(vm_service)
- if entity.status in [otypes.VmStatus.SUSPENDED, otypes.VmStatus.PAUSED]:
- vm_service.start()
- self._wait_for_UP(vm_service)
- return vm_service.get()
-
- def _pre_suspend_action(self, entity):
- vm_service = self._service.vm_service(entity.id)
- self.__suspend_shutdown_common(vm_service)
- if entity.status in [otypes.VmStatus.PAUSED, otypes.VmStatus.DOWN]:
- vm_service.start()
- self._wait_for_UP(vm_service)
- return vm_service.get()
-
- def _post_start_action(self, entity):
- vm_service = self._service.service(entity.id)
- self._wait_for_UP(vm_service)
- self._attach_cd(vm_service.get())
-
- def _attach_cd(self, entity):
- cd_iso = self.param('cd_iso')
- if cd_iso is not None:
- vm_service = self._service.service(entity.id)
- current = vm_service.get().status == otypes.VmStatus.UP and self.param('state') == 'running'
- cdroms_service = vm_service.cdroms_service()
- cdrom_device = cdroms_service.list()[0]
- cdrom_service = cdroms_service.cdrom_service(cdrom_device.id)
- cdrom = cdrom_service.get(current=current)
- if getattr(cdrom.file, 'id', '') != cd_iso:
- if not self._module.check_mode:
- cdrom_service.update(
- cdrom=otypes.Cdrom(
- file=otypes.File(id=cd_iso)
- ),
- current=current,
- )
- self.changed = True
-
- return entity
-
- def _migrate_vm(self, entity):
- vm_host = self.param('host')
- vm_service = self._service.vm_service(entity.id)
- # In case VM is preparing to be UP, wait to be up, to migrate it:
- if entity.status == otypes.VmStatus.UP:
- if vm_host is not None:
- hosts_service = self._connection.system_service().hosts_service()
- current_vm_host = hosts_service.host_service(entity.host.id).get().name
- if vm_host != current_vm_host:
- if not self._module.check_mode:
- vm_service.migrate(host=otypes.Host(name=vm_host), force=self.param('force_migrate'))
- self._wait_for_UP(vm_service)
- self.changed = True
- elif self.param('migrate'):
- if not self._module.check_mode:
- vm_service.migrate(force=self.param('force_migrate'))
- self._wait_for_UP(vm_service)
- self.changed = True
- return entity
-
- def _wait_for_UP(self, vm_service):
- wait(
- service=vm_service,
- condition=lambda vm: vm.status == otypes.VmStatus.UP,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
-
- def _wait_for_vm_disks(self, vm_service):
- disks_service = self._connection.system_service().disks_service()
- for da in vm_service.disk_attachments_service().list():
- disk_service = disks_service.disk_service(da.disk.id)
- wait(
- service=disk_service,
- condition=lambda disk: disk.status == otypes.DiskStatus.OK if disk.storage_type == otypes.DiskStorageType.IMAGE else True,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
-
- def wait_for_down(self, vm):
- """
- This function will first wait for the status DOWN of the VM.
- Then it will find the active snapshot and wait until it's state is OK for
- stateless VMs and stateless snapshot is removed.
- """
- vm_service = self._service.vm_service(vm.id)
- wait(
- service=vm_service,
- condition=lambda vm: vm.status == otypes.VmStatus.DOWN,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
- if vm.stateless:
- snapshots_service = vm_service.snapshots_service()
- snapshots = snapshots_service.list()
- snap_active = [
- snap for snap in snapshots
- if snap.snapshot_type == otypes.SnapshotType.ACTIVE
- ][0]
- snap_stateless = [
- snap for snap in snapshots
- if snap.snapshot_type == otypes.SnapshotType.STATELESS
- ]
- # Stateless snapshot may be already removed:
- if snap_stateless:
- """
- We need to wait for Active snapshot ID, to be removed as it's current
- stateless snapshot. Then we need to wait for staless snapshot ID to
- be read, for use, because it will become active snapshot.
- """
- wait(
- service=snapshots_service.snapshot_service(snap_active.id),
- condition=lambda snap: snap is None,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
- wait(
- service=snapshots_service.snapshot_service(snap_stateless[0].id),
- condition=lambda snap: snap.snapshot_status == otypes.SnapshotStatus.OK,
- wait=self.param('wait'),
- timeout=self.param('timeout'),
- )
- return True
-
- def __attach_graphical_console(self, entity):
- graphical_console = self.param('graphical_console')
- if not graphical_console:
- return False
-
- vm_service = self._service.service(entity.id)
- gcs_service = vm_service.graphics_consoles_service()
- graphical_consoles = gcs_service.list()
-
- # Remove all graphical consoles if there are any:
- if bool(graphical_console.get('headless_mode')):
- if not self._module.check_mode:
- for gc in graphical_consoles:
- gcs_service.console_service(gc.id).remove()
- return len(graphical_consoles) > 0
-
- # If there are not gc add any gc to be added:
- protocol = graphical_console.get('protocol')
- current_protocols = [str(gc.protocol) for gc in graphical_consoles]
- if not current_protocols:
- if not self._module.check_mode:
- for p in protocol:
- gcs_service.add(
- otypes.GraphicsConsole(
- protocol=otypes.GraphicsType(p),
- )
- )
- return True
-
- # Update consoles:
- if sorted(protocol) != sorted(current_protocols):
- if not self._module.check_mode:
- for gc in graphical_consoles:
- gcs_service.console_service(gc.id).remove()
- for p in protocol:
- gcs_service.add(
- otypes.GraphicsConsole(
- protocol=otypes.GraphicsType(p),
- )
- )
- return True
-
- def __attach_disks(self, entity):
- if not self.param('disks'):
- return
-
- vm_service = self._service.service(entity.id)
- disks_service = self._connection.system_service().disks_service()
- disk_attachments_service = vm_service.disk_attachments_service()
-
- self._wait_for_vm_disks(vm_service)
- for disk in self.param('disks'):
- # If disk ID is not specified, find disk by name:
- disk_id = disk.get('id')
- if disk_id is None:
- disk_id = getattr(
- search_by_name(
- service=disks_service,
- name=disk.get('name')
- ),
- 'id',
- None
- )
-
- # Attach disk to VM:
- disk_attachment = disk_attachments_service.attachment_service(disk_id)
- if get_entity(disk_attachment) is None:
- if not self._module.check_mode:
- disk_attachments_service.add(
- otypes.DiskAttachment(
- disk=otypes.Disk(
- id=disk_id,
- ),
- active=disk.get('activate', True),
- interface=otypes.DiskInterface(
- disk.get('interface', 'virtio')
- ),
- bootable=disk.get('bootable', False),
- )
- )
- 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 __get_numa_serialized(self, numa):
- return sorted([(x.index,
- [y.index for y in x.cpu.cores] if x.cpu else [],
- x.memory,
- [y.index for y in x.numa_node_pins] if x.numa_node_pins else []
- ) for x in numa], key=lambda x: x[0])
-
- def __attach_numa_nodes(self, entity):
- numa_nodes_service = self._service.service(entity.id).numa_nodes_service()
- existed_numa_nodes = numa_nodes_service.list()
- if len(self.param('numa_nodes')) > 0:
- # Remove all existing virtual numa nodes before adding new ones
- for current_numa_node in sorted(existed_numa_nodes, reverse=True, key=lambda x: x.index):
- numa_nodes_service.node_service(current_numa_node.id).remove()
-
- for numa_node in self.param('numa_nodes'):
- if numa_node is None or numa_node.get('index') is None or numa_node.get('cores') is None or numa_node.get('memory') is None:
- continue
-
- numa_nodes_service.add(
- otypes.VirtualNumaNode(
- index=numa_node.get('index'),
- memory=numa_node.get('memory'),
- cpu=otypes.Cpu(
- cores=[
- otypes.Core(
- index=core
- ) for core in numa_node.get('cores')
- ],
- ),
- numa_node_pins=[
- otypes.NumaNodePin(
- index=pin
- ) for pin in numa_node.get('numa_node_pins')
- ] if numa_node.get('numa_node_pins') is not None else None,
- )
- )
- return self.__get_numa_serialized(numa_nodes_service.list()) != self.__get_numa_serialized(existed_numa_nodes)
-
- def __attach_watchdog(self, entity):
- watchdogs_service = self._service.service(entity.id).watchdogs_service()
- watchdog = self.param('watchdog')
- if watchdog is not None:
- current_watchdog = next(iter(watchdogs_service.list()), None)
- if watchdog.get('model') is None and current_watchdog:
- watchdogs_service.watchdog_service(current_watchdog.id).remove()
- return True
- elif watchdog.get('model') is not None and current_watchdog is None:
- watchdogs_service.add(
- otypes.Watchdog(
- model=otypes.WatchdogModel(watchdog.get('model').lower()),
- action=otypes.WatchdogAction(watchdog.get('action')),
- )
- )
- return True
- elif current_watchdog is not None:
- if (
- str(current_watchdog.model).lower() != watchdog.get('model').lower() or
- str(current_watchdog.action).lower() != watchdog.get('action').lower()
- ):
- watchdogs_service.watchdog_service(current_watchdog.id).update(
- otypes.Watchdog(
- model=otypes.WatchdogModel(watchdog.get('model')),
- action=otypes.WatchdogAction(watchdog.get('action')),
- )
- )
- return True
- return False
-
- def __attach_nics(self, entity):
- # Attach NICs to VM, if specified:
- nics_service = self._service.service(entity.id).nics_service()
- for nic in self.param('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_initialization(self):
- if self._initialization is not None:
- return self._initialization
-
- sysprep = self.param('sysprep')
- cloud_init = self.param('cloud_init')
- cloud_init_nics = self.param('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,
- ipv6_boot_protocol=otypes.BootProtocol(
- nic.pop('nic_boot_protocol_v6').lower()
- ) if nic.get('nic_boot_protocol_v6') else None,
- name=nic.pop('nic_name', None),
- on_boot=nic.pop('nic_on_boot', None),
- ip=otypes.Ip(
- address=nic.pop('nic_ip_address', None),
- netmask=nic.pop('nic_netmask', None),
- gateway=nic.pop('nic_gateway', None),
- version=otypes.IpVersion('v4')
- ) 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,
- ipv6=otypes.Ip(
- address=nic.pop('nic_ip_address_v6', None),
- netmask=nic.pop('nic_netmask_v6', None),
- gateway=nic.pop('nic_gateway_v6', None),
- version=otypes.IpVersion('v6')
- ) if (
- nic.get('nic_gateway_v6') is not None or
- nic.get('nic_netmask_v6') is not None or
- nic.get('nic_ip_address_v6') is not None
- ) else None,
- )
- for nic in cloud_init_nics
- if (
- nic.get('nic_boot_protocol_v6') is not None or
- nic.get('nic_ip_address_v6') is not None or
- nic.get('nic_gateway_v6') is not None or
- nic.get('nic_netmask_v6') is not None or
- 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 or
- nic.get('nic_on_boot') is not None
- )
- ] if cloud_init_nics else None,
- **cloud_init
- )
- elif sysprep:
- self._initialization = otypes.Initialization(
- **sysprep
- )
- return self._initialization
-
- def __attach_host_devices(self, entity):
- vm_service = self._service.service(entity.id)
- host_devices_service = vm_service.host_devices_service()
- host_devices = self.param('host_devices')
- updated = False
- if host_devices:
- device_names = [dev.name for dev in host_devices_service.list()]
- for device in host_devices:
- device_name = device.get('name')
- state = device.get('state', 'present')
- if state == 'absent' and device_name in device_names:
- updated = True
- if not self._module.check_mode:
- device_id = get_id_by_name(host_devices_service, device.get('name'))
- host_devices_service.device_service(device_id).remove()
-
- elif state == 'present' and device_name not in device_names:
- updated = True
- if not self._module.check_mode:
- host_devices_service.add(
- otypes.HostDevice(
- name=device.get('name'),
- )
- )
-
- return updated
-
-
-def _get_role_mappings(module):
- roleMappings = list()
- for roleMapping in module.params['role_mappings']:
- roleMappings.append(
- otypes.RegistrationRoleMapping(
- from_=otypes.Role(
- name=roleMapping['source_name'],
- ) if roleMapping['source_name'] else None,
- to=otypes.Role(
- name=roleMapping['dest_name'],
- ) if roleMapping['dest_name'] else None,
- )
- )
- return roleMappings
-
-
-def _get_affinity_group_mappings(module):
- affinityGroupMappings = list()
-
- for affinityGroupMapping in module.params['affinity_group_mappings']:
- affinityGroupMappings.append(
- otypes.RegistrationAffinityGroupMapping(
- from_=otypes.AffinityGroup(
- name=affinityGroupMapping['source_name'],
- ) if affinityGroupMapping['source_name'] else None,
- to=otypes.AffinityGroup(
- name=affinityGroupMapping['dest_name'],
- ) if affinityGroupMapping['dest_name'] else None,
- )
- )
- return affinityGroupMappings
-
-
-def _get_affinity_label_mappings(module):
- affinityLabelMappings = list()
-
- for affinityLabelMapping in module.params['affinity_label_mappings']:
- affinityLabelMappings.append(
- otypes.RegistrationAffinityLabelMapping(
- from_=otypes.AffinityLabel(
- name=affinityLabelMapping['source_name'],
- ) if affinityLabelMapping['source_name'] else None,
- to=otypes.AffinityLabel(
- name=affinityLabelMapping['dest_name'],
- ) if affinityLabelMapping['dest_name'] else None,
- )
- )
- return affinityLabelMappings
-
-
-def _get_domain_mappings(module):
- domainMappings = list()
-
- for domainMapping in module.params['domain_mappings']:
- domainMappings.append(
- otypes.RegistrationDomainMapping(
- from_=otypes.Domain(
- name=domainMapping['source_name'],
- ) if domainMapping['source_name'] else None,
- to=otypes.Domain(
- name=domainMapping['dest_name'],
- ) if domainMapping['dest_name'] else None,
- )
- )
- return domainMappings
-
-
-def _get_lun_mappings(module):
- lunMappings = list()
- for lunMapping in module.params['lun_mappings']:
- lunMappings.append(
- otypes.RegistrationLunMapping(
- from_=otypes.Disk(
- lun_storage=otypes.HostStorage(
- type=otypes.StorageType(lunMapping['source_storage_type'])
- if (lunMapping['source_storage_type'] in
- ['iscsi', 'fcp']) else None,
- logical_units=[
- otypes.LogicalUnit(
- id=lunMapping['source_logical_unit_id'],
- )
- ],
- ),
- ) if lunMapping['source_logical_unit_id'] else None,
- to=otypes.Disk(
- lun_storage=otypes.HostStorage(
- type=otypes.StorageType(lunMapping['dest_storage_type'])
- if (lunMapping['dest_storage_type'] in
- ['iscsi', 'fcp']) else None,
- logical_units=[
- otypes.LogicalUnit(
- id=lunMapping.get('dest_logical_unit_id'),
- port=lunMapping.get('dest_logical_unit_port'),
- portal=lunMapping.get('dest_logical_unit_portal'),
- address=lunMapping.get('dest_logical_unit_address'),
- target=lunMapping.get('dest_logical_unit_target'),
- password=lunMapping.get('dest_logical_unit_password'),
- username=lunMapping.get('dest_logical_unit_username'),
- )
- ],
- ),
- ) if lunMapping['dest_logical_unit_id'] else None,
- ),
- ),
- return lunMappings
-
-
-def _get_cluster_mappings(module):
- clusterMappings = list()
-
- for clusterMapping in module.params['cluster_mappings']:
- clusterMappings.append(
- otypes.RegistrationClusterMapping(
- from_=otypes.Cluster(
- name=clusterMapping['source_name'],
- ),
- to=otypes.Cluster(
- name=clusterMapping['dest_name'],
- ) if clusterMapping['dest_name'] else None,
- )
- )
- return clusterMappings
-
-
-def _get_vnic_profile_mappings(module):
- vnicProfileMappings = list()
-
- for vnicProfileMapping in module.params['vnic_profile_mappings']:
- vnicProfileMappings.append(
- otypes.VnicProfileMapping(
- source_network_name=vnicProfileMapping['source_network_name'],
- source_network_profile_name=vnicProfileMapping['source_profile_name'],
- target_vnic_profile=otypes.VnicProfile(
- id=vnicProfileMapping['target_profile_id'],
- ) if vnicProfileMapping['target_profile_id'] else None,
- )
- )
-
- return vnicProfileMappings
-
-
-def import_vm(module, connection):
- vms_service = connection.system_service().vms_service()
- if search_by_name(vms_service, module.params['name']) is not None:
- return False
-
- events_service = connection.system_service().events_service()
- last_event = events_service.list(max=1)[0]
-
- external_type = [
- tmp for tmp in ['kvm', 'xen', 'vmware']
- if module.params[tmp] is not None
- ][0]
-
- external_vm = module.params[external_type]
- imports_service = connection.system_service().external_vm_imports_service()
- imported_vm = imports_service.add(
- otypes.ExternalVmImport(
- vm=otypes.Vm(
- name=module.params['name']
- ),
- name=external_vm.get('name'),
- username=external_vm.get('username', 'test'),
- password=external_vm.get('password', 'test'),
- provider=otypes.ExternalVmProviderType(external_type),
- url=external_vm.get('url'),
- cluster=otypes.Cluster(
- name=module.params['cluster'],
- ) if module.params['cluster'] else None,
- storage_domain=otypes.StorageDomain(
- name=external_vm.get('storage_domain'),
- ) if external_vm.get('storage_domain') else None,
- sparse=external_vm.get('sparse', True),
- host=otypes.Host(
- name=module.params['host'],
- ) if module.params['host'] else None,
- )
- )
-
- # Wait until event with code 1152 for our VM don't appear:
- vms_service = connection.system_service().vms_service()
- wait(
- service=vms_service.vm_service(imported_vm.vm.id),
- condition=lambda vm: len([
- event
- for event in events_service.list(
- from_=int(last_event.id),
- search='type=1152 and vm.id=%s' % vm.id,
- )
- ]) > 0 if vm is not None else False,
- fail_condition=lambda vm: vm is None,
- timeout=module.params['timeout'],
- poll_interval=module.params['poll_interval'],
- )
- return True
-
-
-def control_state(vm, vms_service, module):
- if vm is None:
- return
-
- force = module.params['force']
- state = module.params['state']
-
- vm_service = vms_service.vm_service(vm.id)
- if vm.status == otypes.VmStatus.IMAGE_LOCKED:
- wait(
- service=vm_service,
- condition=lambda vm: vm.status == otypes.VmStatus.DOWN,
- )
- elif vm.status == otypes.VmStatus.SAVING_STATE:
- # Result state is SUSPENDED, we should wait to be suspended:
- wait(
- service=vm_service,
- condition=lambda vm: vm.status == otypes.VmStatus.SUSPENDED,
- )
- elif (
- vm.status == otypes.VmStatus.UNASSIGNED or
- vm.status == otypes.VmStatus.UNKNOWN
- ):
- # Invalid states:
- module.fail_json(msg="Not possible to control VM, if it's in '{0}' status".format(vm.status))
- elif vm.status == otypes.VmStatus.POWERING_DOWN:
- if (force and state == 'stopped') or state == 'absent':
- vm_service.stop()
- wait(
- service=vm_service,
- condition=lambda vm: vm.status == otypes.VmStatus.DOWN,
- )
- else:
- # If VM is powering down, wait to be DOWN or UP.
- # VM can end in UP state in case there is no GA
- # or ACPI on the VM or shutdown operation crashed:
- wait(
- service=vm_service,
- condition=lambda vm: vm.status in [otypes.VmStatus.DOWN, otypes.VmStatus.UP],
- )
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(type='str', default='present', choices=[
- 'absent', 'next_run', 'present', 'registered', 'running', 'stopped', 'suspended', 'exported', 'reboot'
- ]),
- name=dict(type='str'),
- id=dict(type='str'),
- cluster=dict(type='str'),
- allow_partial_import=dict(type='bool'),
- template=dict(type='str'),
- template_version=dict(type='int'),
- use_latest_template_version=dict(type='bool'),
- storage_domain=dict(type='str'),
- disk_format=dict(type='str', default='cow', choices=['cow', 'raw']),
- disks=dict(type='list', default=[]),
- memory=dict(type='str'),
- memory_guaranteed=dict(type='str'),
- memory_max=dict(type='str'),
- cpu_sockets=dict(type='int'),
- cpu_cores=dict(type='int'),
- cpu_shares=dict(type='int'),
- cpu_threads=dict(type='int'),
- type=dict(type='str', choices=['server', 'desktop', 'high_performance']),
- operating_system=dict(type='str'),
- cd_iso=dict(type='str'),
- boot_devices=dict(type='list', choices=['cdrom', 'hd', 'network']),
- vnic_profile_mappings=dict(default=[], type='list'),
- cluster_mappings=dict(default=[], type='list'),
- role_mappings=dict(default=[], type='list'),
- affinity_group_mappings=dict(default=[], type='list'),
- affinity_label_mappings=dict(default=[], type='list'),
- lun_mappings=dict(default=[], type='list'),
- domain_mappings=dict(default=[], type='list'),
- reassign_bad_macs=dict(default=None, type='bool'),
- boot_menu=dict(type='bool'),
- serial_console=dict(type='bool'),
- usb_support=dict(type='bool'),
- sso=dict(type='bool'),
- quota_id=dict(type='str'),
- high_availability=dict(type='bool'),
- high_availability_priority=dict(type='int'),
- lease=dict(type='str'),
- stateless=dict(type='bool'),
- delete_protected=dict(type='bool'),
- custom_emulated_machine=dict(type='str'),
- force=dict(type='bool', default=False),
- nics=dict(type='list', default=[]),
- cloud_init=dict(type='dict'),
- cloud_init_nics=dict(type='list', default=[]),
- cloud_init_persist=dict(type='bool', default=False, aliases=['sysprep_persist']),
- kernel_params_persist=dict(type='bool', default=False),
- sysprep=dict(type='dict'),
- host=dict(type='str'),
- clone=dict(type='bool', default=False),
- clone_permissions=dict(type='bool', default=False),
- kernel_path=dict(type='str'),
- initrd_path=dict(type='str'),
- kernel_params=dict(type='str'),
- instance_type=dict(type='str'),
- description=dict(type='str'),
- comment=dict(type='str'),
- timezone=dict(type='str'),
- serial_policy=dict(type='str', choices=['vm', 'host', 'custom']),
- serial_policy_value=dict(type='str'),
- vmware=dict(type='dict'),
- xen=dict(type='dict'),
- kvm=dict(type='dict'),
- cpu_mode=dict(type='str'),
- placement_policy=dict(type='str'),
- custom_compatibility_version=dict(type='str'),
- ticket=dict(type='bool', default=None),
- cpu_pinning=dict(type='list'),
- soundcard_enabled=dict(type='bool', default=None),
- smartcard_enabled=dict(type='bool', default=None),
- io_threads=dict(type='int', default=None),
- ballooning_enabled=dict(type='bool', default=None),
- rng_device=dict(type='str'),
- numa_tune_mode=dict(type='str', choices=['interleave', 'preferred', 'strict']),
- numa_nodes=dict(type='list', default=[]),
- custom_properties=dict(type='list'),
- watchdog=dict(type='dict'),
- host_devices=dict(type='list'),
- graphical_console=dict(
- type='dict',
- options=dict(
- headless_mode=dict(type='bool'),
- protocol=dict(type='list'),
- disconnect_action=dict(type='str'),
- keyboard_layout=dict(type='str'),
- monitors=dict(type='int'),
- )
- ),
- exclusive=dict(type='bool'),
- export_domain=dict(default=None),
- export_ova=dict(type='dict'),
- force_migrate=dict(type='bool'),
- migrate=dict(type='bool', default=None),
- next_run=dict(type='bool'),
- snapshot_name=dict(type='str'),
- snapshot_vm=dict(type='str'),
- )
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_one_of=[['id', 'name']],
- required_if=[
- ('state', 'registered', ['storage_domain']),
- ],
- required_together=[['snapshot_name', 'snapshot_vm']]
- )
-
- check_sdk(module)
- check_params(module)
-
- try:
- state = module.params['state']
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- vms_service = connection.system_service().vms_service()
- vms_module = VmsModule(
- connection=connection,
- module=module,
- service=vms_service,
- )
- vm = vms_module.search_entity(list_params={'all_content': True})
-
- # Boolean variable to mark if vm existed before module was executed
- vm_existed = True if vm else False
- control_state(vm, vms_service, module)
- if state in ('present', 'running', 'next_run'):
- if module.params['xen'] or module.params['kvm'] or module.params['vmware']:
- vms_module.changed = import_vm(module, connection)
-
- # In case of wait=false and state=running, waits for VM to be created
- # In case VM don't exist, wait for VM DOWN state,
- # otherwise don't wait for any state, just update VM:
- ret = vms_module.create(
- entity=vm,
- result_state=otypes.VmStatus.DOWN if vm is None else None,
- update_params={'next_run': module.params['next_run']} if module.params['next_run'] is not None else None,
- clone=module.params['clone'],
- clone_permissions=module.params['clone_permissions'],
- _wait=True if not module.params['wait'] and state == 'running' else module.params['wait'],
- )
- # If VM is going to be created and check_mode is on, return now:
- if module.check_mode and ret.get('id') is None:
- module.exit_json(**ret)
-
- vms_module.post_present(ret['id'])
- # Run the VM if it was just created, else don't run it:
- if state == 'running':
- def kernel_persist_check():
- return (module.params.get('kernel_params') or
- module.params.get('initrd_path') or
- module.params.get('kernel_path')
- and not module.params.get('cloud_init_persist'))
- initialization = vms_module.get_initialization()
- ret = vms_module.action(
- action='start',
- post_action=vms_module._post_start_action,
- action_condition=lambda vm: (
- vm.status not in [
- otypes.VmStatus.MIGRATING,
- otypes.VmStatus.POWERING_UP,
- otypes.VmStatus.REBOOT_IN_PROGRESS,
- otypes.VmStatus.WAIT_FOR_LAUNCH,
- otypes.VmStatus.UP,
- otypes.VmStatus.RESTORING_STATE,
- ]
- ),
- wait_condition=lambda vm: vm.status == otypes.VmStatus.UP,
- # Start action kwargs:
- use_cloud_init=True if not module.params.get('cloud_init_persist') and module.params.get('cloud_init') else None,
- use_sysprep=True if not module.params.get('cloud_init_persist') and module.params.get('sysprep') else None,
- vm=otypes.Vm(
- placement_policy=otypes.VmPlacementPolicy(
- hosts=[otypes.Host(name=module.params['host'])]
- ) if module.params['host'] else None,
- initialization=initialization,
- os=otypes.OperatingSystem(
- cmdline=module.params.get('kernel_params'),
- initrd=module.params.get('initrd_path'),
- kernel=module.params.get('kernel_path'),
- ) if (kernel_persist_check()) else None,
- ) if (
- kernel_persist_check() or
- module.params.get('host') or
- initialization is not None
- and not module.params.get('cloud_init_persist')
- ) else None,
- )
-
- if module.params['ticket']:
- vm_service = vms_service.vm_service(ret['id'])
- graphics_consoles_service = vm_service.graphics_consoles_service()
- graphics_console = graphics_consoles_service.list()[0]
- console_service = graphics_consoles_service.console_service(graphics_console.id)
- ticket = console_service.remote_viewer_connection_file()
- if ticket:
- ret['vm']['remote_vv_file'] = ticket
-
- if state == 'next_run':
- # Apply next run configuration, if needed:
- vm = vms_service.vm_service(ret['id']).get()
- if vm.next_run_configuration_exists:
- ret = vms_module.action(
- action='reboot',
- entity=vm,
- action_condition=lambda vm: vm.status == otypes.VmStatus.UP,
- wait_condition=lambda vm: vm.status == otypes.VmStatus.UP,
- )
- # Allow migrate vm when state present.
- if vm_existed:
- vms_module._migrate_vm(vm)
- ret['changed'] = vms_module.changed
- elif state == 'stopped':
- if module.params['xen'] or module.params['kvm'] or module.params['vmware']:
- vms_module.changed = import_vm(module, connection)
-
- ret = vms_module.create(
- entity=vm,
- result_state=otypes.VmStatus.DOWN if vm is None else None,
- clone=module.params['clone'],
- clone_permissions=module.params['clone_permissions'],
- )
- if module.params['force']:
- ret = vms_module.action(
- action='stop',
- action_condition=lambda vm: vm.status != otypes.VmStatus.DOWN,
- wait_condition=vms_module.wait_for_down,
- )
- else:
- ret = vms_module.action(
- action='shutdown',
- pre_action=vms_module._pre_shutdown_action,
- action_condition=lambda vm: vm.status != otypes.VmStatus.DOWN,
- wait_condition=vms_module.wait_for_down,
- )
- vms_module.post_present(ret['id'])
- elif state == 'suspended':
- ret = vms_module.create(
- entity=vm,
- result_state=otypes.VmStatus.DOWN if vm is None else None,
- clone=module.params['clone'],
- clone_permissions=module.params['clone_permissions'],
- )
- vms_module.post_present(ret['id'])
- ret = vms_module.action(
- action='suspend',
- pre_action=vms_module._pre_suspend_action,
- action_condition=lambda vm: vm.status != otypes.VmStatus.SUSPENDED,
- wait_condition=lambda vm: vm.status == otypes.VmStatus.SUSPENDED,
- )
- elif state == 'absent':
- ret = vms_module.remove()
- elif state == 'registered':
- storage_domains_service = connection.system_service().storage_domains_service()
-
- # Find the storage domain with unregistered VM:
- sd_id = get_id_by_name(storage_domains_service, module.params['storage_domain'])
- storage_domain_service = storage_domains_service.storage_domain_service(sd_id)
- vms_service = storage_domain_service.vms_service()
-
- # Find the unregistered VM we want to register:
- vms = vms_service.list(unregistered=True)
- vm = next(
- (vm for vm in vms if (vm.id == module.params['id'] or vm.name == module.params['name'])),
- None
- )
- changed = False
- if vm is None:
- vm = vms_module.search_entity()
- if vm is None:
- raise ValueError(
- "VM '%s(%s)' wasn't found." % (module.params['name'], module.params['id'])
- )
- else:
- # Register the vm into the system:
- changed = True
- vm_service = vms_service.vm_service(vm.id)
- vm_service.register(
- allow_partial_import=module.params['allow_partial_import'],
- cluster=otypes.Cluster(
- name=module.params['cluster']
- ) if module.params['cluster'] else None,
- vnic_profile_mappings=_get_vnic_profile_mappings(module)
- if module.params['vnic_profile_mappings'] else None,
- reassign_bad_macs=module.params['reassign_bad_macs']
- if module.params['reassign_bad_macs'] is not None else None,
- registration_configuration=otypes.RegistrationConfiguration(
- cluster_mappings=_get_cluster_mappings(module),
- role_mappings=_get_role_mappings(module),
- domain_mappings=_get_domain_mappings(module),
- lun_mappings=_get_lun_mappings(module),
- affinity_group_mappings=_get_affinity_group_mappings(module),
- affinity_label_mappings=_get_affinity_label_mappings(module),
- ) if (module.params['cluster_mappings']
- or module.params['role_mappings']
- or module.params['domain_mappings']
- or module.params['lun_mappings']
- or module.params['affinity_group_mappings']
- or module.params['affinity_label_mappings']) else None
- )
-
- if module.params['wait']:
- vm = vms_module.wait_for_import()
- else:
- # Fetch vm to initialize return.
- vm = vm_service.get()
- ret = {
- 'changed': changed,
- 'id': vm.id,
- 'vm': get_dict_of_struct(vm)
- }
- elif state == 'exported':
- if module.params['export_domain']:
- export_service = vms_module._get_export_domain_service()
- export_vm = search_by_attributes(export_service.vms_service(), id=vm.id)
-
- ret = vms_module.action(
- entity=vm,
- action='export',
- action_condition=lambda t: export_vm is None or module.params['exclusive'],
- wait_condition=lambda t: t is not None,
- post_action=vms_module.post_export_action,
- storage_domain=otypes.StorageDomain(id=export_service.get().id),
- exclusive=module.params['exclusive'],
- )
- elif module.params['export_ova']:
- export_vm = module.params['export_ova']
- ret = vms_module.action(
- entity=vm,
- action='export_to_path_on_host',
- host=otypes.Host(name=export_vm.get('host')),
- directory=export_vm.get('directory'),
- filename=export_vm.get('filename'),
- )
- elif state == 'reboot':
- ret = vms_module.action(
- action='reboot',
- entity=vm,
- action_condition=lambda vm: vm.status == otypes.VmStatus.UP,
- wait_condition=lambda vm: vm.status == otypes.VmStatus.UP,
- )
-
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py
deleted file mode 100644
index 9e5a1edff2..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_vm_info
-short_description: Retrieve information about one or more oVirt/RHV virtual machines
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV virtual machines."
- - This module was called C(ovirt_vm_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_vm_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_vms), which
- contains a list of virtual machines. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search VM X from cluster Y use following pattern:
- name=X and cluster=Y"
- all_content:
- description:
- - "If I(true) all the attributes of the virtual machines should be
- included in the response."
- type: bool
- case_sensitive:
- description:
- - "If I(true) performed search will take case into account."
- type: bool
- default: true
- max:
- description:
- - "The maximum number of results to return."
- next_run:
- description:
- - "Indicates if the returned result describes the virtual machine as it is currently running or if describes
- the virtual machine with the modifications that have already been performed but that will only come into
- effect when the virtual machine is restarted. By default the value is set by engine."
- type: bool
- version_added: "2.8"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all VMs which names start with C(centos) and
-# belong to cluster C(west):
-- ovirt_vm_info:
- pattern: name=centos* and cluster=west
- register: result
-- debug:
- msg: "{{ result.ovirt_vms }}"
-
-# Gather info about next run configuration of virtual machine named myvm
-- ovirt_vm_info:
- pattern: name=myvm
- next_run: true
- register: result
-- debug:
- msg: "{{ result.ovirt_vms[0] }}"
-'''
-
-RETURN = '''
-ovirt_vms:
- description: "List of dictionaries describing the VMs. VM attributes are mapped to dictionary keys,
- all VMs attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- all_content=dict(default=False, type='bool'),
- next_run=dict(default=None, type='bool'),
- case_sensitive=dict(default=True, type='bool'),
- max=dict(default=None, type='int'),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_vm_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_vm_facts' module has been renamed to 'ovirt_vm_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- vms_service = connection.system_service().vms_service()
- vms = vms_service.list(
- search=module.params['pattern'],
- all_content=module.params['all_content'],
- case_sensitive=module.params['case_sensitive'],
- max=module.params['max'],
- )
- if module.params['next_run']:
- vms = [vms_service.vm_service(vm.id).get(next_run=True) for vm in vms]
-
- result = dict(
- ovirt_vms=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in vms
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py b/lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py
deleted file mode 100644
index 88a689ca6e..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py
+++ /dev/null
@@ -1,485 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_vmpool
-short_description: Module to manage VM pools in oVirt/RHV
-version_added: "2.3"
-author: "Ondra Machacek (@machacekondra)"
-description:
- - "Module to manage VM pools in oVirt/RHV."
-options:
- id:
- description:
- - "ID of the vmpool to manage."
- version_added: "2.8"
- name:
- description:
- - "Name of the VM pool to manage."
- required: true
- comment:
- description:
- - Comment of the Virtual Machine pool.
- 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
- template:
- description:
- - "Name of the template, which will be used to create VM pool."
- description:
- description:
- - "Description of the VM pool."
- cluster:
- description:
- - "Name of the cluster, where VM pool should be created."
- 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']
- vm_per_user:
- description:
- - "Maximum number of VMs a single user can attach to from this pool."
- - "Default value is set by engine."
- 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."
- vm_count:
- description:
- - "Number of VMs in the pool."
- - "Default value is set by engine."
- 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.
- - C(dns_servers) - DNS servers to be configured on Virtual Machine.
- - 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.
- - C(nic_on_boot) - If I(True) network interface will be set to start on boot.
- 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_nics) module instead.
- version_added: "2.9"
-extends_documentation_fragment: 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_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_vmpool:
- state: absent
- name: myvmpool
-
-- name: Change Pool Name
- ovirt_vmpool:
- id: 00000000-0000-0000-0000-000000000000
- name: "new_pool_name"
-
-- name: Create vm pool and override the pool values
- 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
- nic_on_boot: true
- 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.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=nic.pop('nic_on_boot', None),
- 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 or
- nic.get('nic_on_boot') 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py
deleted file mode 100644
index 52f2a5e494..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_vmpool_info
-short_description: Retrieve information about one or more oVirt/RHV vmpools
-author: "Ondra Machacek (@machacekondra)"
-version_added: "2.3"
-description:
- - "Retrieve information about one or more oVirt/RHV vmpools."
- - This module was called C(ovirt_vmpool_facts) before Ansible 2.9, returning C(ansible_facts).
- Note that the M(ovirt_vmpool_info) module no longer returns C(ansible_facts)!
-notes:
- - "This module returns a variable C(ovirt_vmpools), which
- contains a list of vmpools. You need to register the result with
- the I(register) keyword to use it."
-options:
- pattern:
- description:
- - "Search term which is accepted by oVirt/RHV search backend."
- - "For example to search vmpool X: name=X"
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information about all vm pools which names start with C(centos):
-- ovirt_vmpool_info:
- pattern: name=centos*
- register: result
-- debug:
- msg: "{{ result.ovirt_vm_pools }}"
-'''
-
-RETURN = '''
-ovirt_vm_pools:
- description: "List of dictionaries describing the vmpools. Vm pool attributes are mapped to dictionary keys,
- all vmpools attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm_pool."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- pattern=dict(default='', required=False),
- )
- module = AnsibleModule(argument_spec)
- is_old_facts = module._name == 'ovirt_vmpool_facts'
- if is_old_facts:
- module.deprecate("The 'ovirt_vmpool_facts' module has been renamed to 'ovirt_vmpool_info', "
- "and the renamed one no longer returns ansible_facts", version='2.13')
-
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- vmpools_service = connection.system_service().vm_pools_service()
- vmpools = vmpools_service.list(search=module.params['pattern'])
- result = dict(
- ovirt_vm_pools=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in vmpools
- ],
- )
- if is_old_facts:
- module.exit_json(changed=False, ansible_facts=result)
- else:
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py b/lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py
deleted file mode 100644
index 6013e3de46..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py
+++ /dev/null
@@ -1,321 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2017, Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ovirt_vnic_profile
-short_description: Module to manage vNIC profile of network in oVirt/RHV
-version_added: "2.8"
-author:
-- "Ondra Machacek (@machacekondra)"
-- "Martin Necas (@mnecas)"
-description:
- - "Module to manage vNIC profile of network in oVirt/RHV"
-options:
- name:
- description:
- - "A human-readable name in plain text."
- required: true
- state:
- description:
- - "Should the vNIC be absent/present."
- choices: ['absent', 'present']
- default: present
- description:
- description:
- - "A human-readable description in plain text."
- data_center:
- description:
- - "Datacenter name where network reside."
- required: true
- network:
- description:
- - "Name of network to which is vNIC attached."
- required: true
- network_filter:
- description:
- - "The network filter enables to filter packets send to/from the VM's nic according to defined rules."
- custom_properties:
- description:
- - "Custom properties applied to the vNIC profile."
- - "Custom properties is a list of dictionary which can have following values:"
- suboptions:
- name:
- description:
- - "Name of the custom property. For example: I(hugepages), I(vhost), I(sap_agent), etc."
- regexp:
- description:
- - Regular expression to set for custom property.
- value:
- description:
- - Value to set for custom property.
- qos:
- description:
- - "Quality of Service attributes regulate inbound and outbound network traffic of the NIC."
- port_mirroring:
- description:
- - "Enables port mirroring."
- type: bool
- pass_through:
- description:
- - "Enables passthrough to an SR-IOV-enabled host NIC."
- - "When enabled C(qos) and C(network_filter) are automatically set to None and C(port_mirroring) to False."
- - "When enabled and C(migratable) not specified then C(migratable) is enabled."
- - "Port mirroring, QoS and network filters are not supported on passthrough profiles."
- choices: ['disabled', 'enabled']
- migratable:
- description:
- - "Marks whether pass_through NIC is migratable or not."
- type: bool
-extends_documentation_fragment: ovirt
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-- name: Add vNIC
- ovirt_vnic_profile:
- name: myvnic
- network: mynetwork
- state: present
- data_center: datacenter
-
-- name: Editing vNICs network_filter, custom_properties, qos
- ovirt_vnic_profile:
- name: myvnic
- network: mynetwork
- data_center: datacenter
- qos: myqos
- custom_properties:
- - name: SecurityGroups
- value: 9bd9bde9-39da-44a8-9541-aa39e1a81c9d
- network_filter: allow-dhcp
-
-- name: Remove vNICs network_filter, custom_properties, qos
- ovirt_vnic_profile:
- name: myvnic
- network: mynetwork
- data_center: datacenter
- qos: ""
- custom_properties: ""
- network_filter: ""
-
-- name: Dont use migratable
- ovirt_vnic_profile:
- name: myvnic
- network: mynetwork
- data_center: datacenter
- migratable: False
- pass_through: enabled
-
-- name: Remove vNIC
- ovirt_vnic_profile:
- name: myvnic
- network: mynetwork
- state: absent
- data_center: datacenter
-'''
-
-RETURN = '''
-id:
- description: ID of the vNIC profile which is managed
- returned: On success if vNIC profile is found.
- type: str
- sample: 7de90f31-222c-436c-a1ca-7e655bd5b60c
-vnic:
- description: "Dictionary of all the vNIC profile attributes. Network interface attributes can be found on your oVirt/RHV instance
- at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/nic."
- returned: On success if vNIC profile is found.
- type: dict
-'''
-
-try:
- import ovirtsdk4.types as otypes
-except ImportError:
- pass
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- BaseModule,
- check_sdk,
- create_connection,
- equal,
- get_link_name,
- ovirt_full_argument_spec,
- search_by_name,
- get_id_by_name
-)
-
-
-class EntityVnicPorfileModule(BaseModule):
-
- def __init__(self, *args, **kwargs):
- super(EntityVnicPorfileModule, self).__init__(*args, **kwargs)
-
- def _get_dcs_service(self):
- return self._connection.system_service().data_centers_service()
-
- def _get_dcs_id(self):
- return get_id_by_name(self._get_dcs_service(), self.param('data_center'))
-
- def _get_network_id(self):
- networks_service = self._get_dcs_service().service(self._get_dcs_id()).networks_service()
- return get_id_by_name(networks_service, self.param('network'))
-
- def _get_qos_id(self):
- if self.param('qos'):
- qoss_service = self._get_dcs_service().service(self._get_dcs_id()).qoss_service()
- return get_id_by_name(qoss_service, self.param('qos')) if self.param('qos') else None
- return None
-
- def _get_network_filter_id(self):
- nf_service = self._connection.system_service().network_filters_service()
- return get_id_by_name(nf_service, self.param('network_filter')) if self.param('network_filter') else None
-
- def _get_network_filter(self):
- network_filter = None
- # The order of these condition is necessary.
- # When would network_filter and pass_through specified it would try to create and network_filter and fail on engine.
- if self.param('network_filter') == '' or self.param('pass_through') == 'enabled':
- network_filter = otypes.NetworkFilter()
- elif self.param('network_filter'):
- network_filter = otypes.NetworkFilter(id=self._get_network_filter_id())
- return network_filter
-
- def _get_qos(self):
- qos = None
- # The order of these condition is necessary. When would qos and pass_through specified it would try to create and qos and fail on engine.
- if self.param('qos') == '' or self.param('pass_through') == 'enabled':
- qos = otypes.Qos()
- elif self.param('qos'):
- qos = otypes.Qos(id=self._get_qos_id())
- return qos
-
- def _get_port_mirroring(self):
- if self.param('pass_through') == 'enabled':
- return False
- return self.param('port_mirroring')
-
- def _get_migratable(self):
- if self.param('migratable') is not None:
- return self.param('migratable')
- if self.param('pass_through') == 'enabled':
- return True
-
- def build_entity(self):
- return otypes.VnicProfile(
- name=self.param('name'),
- network=otypes.Network(id=self._get_network_id()),
- description=self.param('description') if self.param('description') is not None else None,
- pass_through=otypes.VnicPassThrough(mode=otypes.VnicPassThroughMode(self.param('pass_through'))) if self.param('pass_through') else None,
- custom_properties=[
- otypes.CustomProperty(
- name=cp.get('name'),
- regexp=cp.get('regexp'),
- value=str(cp.get('value')),
- ) for cp in self.param('custom_properties') if cp
- ] if self.param('custom_properties') else None,
- migratable=self._get_migratable(),
- qos=self._get_qos(),
- port_mirroring=self._get_port_mirroring(),
- network_filter=self._get_network_filter()
- )
-
- def update_check(self, entity):
- def check_custom_properties():
- if self.param('custom_properties'):
- current = []
- if entity.custom_properties:
- current = [(cp.name, cp.regexp, str(cp.value)) for cp in entity.custom_properties]
- passed = [(cp.get('name'), cp.get('regexp'), str(cp.get('value'))) for cp in self.param('custom_properties') if cp]
- return sorted(current) == sorted(passed)
- return True
-
- pass_through = getattr(entity.pass_through.mode, 'name', None)
- return (
- check_custom_properties() and
- # The reason why we can't use equal method, is we get None from _get_network_filter_id or _get_qos_id method, when passing empty string.
- # And when first param of equal method is None it returns true.
- self._get_network_filter_id() == getattr(entity.network_filter, 'id', None) and
- self._get_qos_id() == getattr(entity.qos, 'id', None) and
- equal(self.param('migratable'), getattr(entity, 'migratable', None)) and
- equal(self.param('pass_through'), pass_through.lower() if pass_through else None) and
- equal(self.param('description'), entity.description) and
- equal(self.param('port_mirroring'), getattr(entity, 'port_mirroring', None))
- )
-
-
-def get_entity(vnic_services, entitynics_module):
- vnic_profiles = vnic_services.list()
- network_id = entitynics_module._get_network_id()
- for vnic in vnic_profiles:
- # When vNIC already exist update it, when not create it
- if vnic.name == entitynics_module.param('name') and network_id == vnic.network.id:
- return vnic
-
-
-def check_params(module):
- if (module.params.get('port_mirroring') or module.params.get('network_filter') or module.params.get('qos'))\
- and module.params.get('pass_through') == 'enabled':
- module.fail_json(msg="Cannot edit VM network interface profile. 'Port Mirroring,'Qos' and 'Network Filter' are not supported on passthrough profiles.")
-
-
-def main():
- argument_spec = ovirt_full_argument_spec(
- state=dict(type='str', default='present', choices=['absent', 'present']),
- network=dict(type='str', required=True),
- data_center=dict(type='str', required=True),
- description=dict(type='str'),
- name=dict(type='str', required=True),
- network_filter=dict(type='str'),
- custom_properties=dict(type='list'),
- qos=dict(type='str'),
- pass_through=dict(type='str', choices=['disabled', 'enabled']),
- port_mirroring=dict(type='bool'),
- migratable=dict(type='bool'),
- )
- 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)
-
- vnic_services = connection.system_service().vnic_profiles_service()
-
- entitynics_module = EntityVnicPorfileModule(
- connection=connection,
- module=module,
- service=vnic_services,
- )
- state = module.params['state']
- entity = get_entity(vnic_services, entitynics_module)
- if state == 'present':
- ret = entitynics_module.create(entity=entity, force_create=entity is None)
- elif state == 'absent':
- if entity is not None:
- ret = entitynics_module.remove(entity=entity)
- else:
- raise Exception("Vnic profile '%s' in network '%s' was not found." % (module.params['name'], module.params['network']))
- 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()
diff --git a/lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile_info.py b/lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile_info.py
deleted file mode 100644
index 8fda8b5b10..0000000000
--- a/lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile_info.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/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
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: ovirt_vnic_profile_info
-short_description: Retrieve information about one or more oVirt/RHV vnic profiles
-author: "Martin Necas (@mnecas)"
-version_added: "2.10"
-description:
- - "Retrieve information about one or more oVirt/RHV vnic profiles."
-notes:
- - "This module returns a variable C(ovirt_vnic_profiles), which
- contains a list of vnic profiles. You need to register the result with
- the I(register) keyword to use it."
-options:
- max:
- description:
- - "The maximum number of results to return."
- type: int
- name:
- description:
- - "Name of vnic profile."
- type: str
-extends_documentation_fragment: ovirt_info
-'''
-
-EXAMPLES = '''
-# Examples don't contain auth parameter for simplicity,
-# look at ovirt_auth module to see how to reuse authentication:
-
-# Gather information 10 vnic profiles
-- ovirt_vnic_profile_info:
- max: 10
- register: result
-- debug:
- msg: "{{ result.ovirt_vnic_profiles }}"
-'''
-
-RETURN = '''
-ovirt_vnic_profiles:
- description: "List of dictionaries describing the vnic profiles. Vnic_profile attributes are mapped to dictionary keys,
- all vnic profiles attributes can be found at following url: http://ovirt.github.io/ovirt-engine-api-model/master/#types/vnic_profile."
- returned: On success.
- type: list
-'''
-
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.ovirt import (
- check_sdk,
- create_connection,
- get_dict_of_struct,
- ovirt_info_full_argument_spec,
-)
-
-
-def main():
- argument_spec = ovirt_info_full_argument_spec(
- max=dict(default=None, type='int'),
- name=dict(default=None),
- )
- module = AnsibleModule(argument_spec)
- check_sdk(module)
-
- try:
- auth = module.params.pop('auth')
- connection = create_connection(auth)
- vnic_profiles_service = connection.system_service().vnic_profiles_service()
- vnic_profiles = vnic_profiles_service.list(max=module.params.get('max'))
- if module.params.get('name') and vnic_profiles:
- vnic_profiles = [vnic_profile for vnic_profile in vnic_profiles if vnic_profile.name == module.params.get("name")]
-
- result = dict(
- ovirt_vnic_profiles=[
- get_dict_of_struct(
- struct=c,
- connection=connection,
- fetch_nested=module.params.get('fetch_nested'),
- attributes=module.params.get('nested_attributes'),
- ) for c in vnic_profiles
- ],
- )
- module.exit_json(changed=False, **result)
- 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()
diff --git a/lib/ansible/plugins/doc_fragments/ovirt.py b/lib/ansible/plugins/doc_fragments/ovirt.py
deleted file mode 100644
index 3667b7d886..0000000000
--- a/lib/ansible/plugins/doc_fragments/ovirt.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2016, Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-
-class ModuleDocFragment(object):
-
- # Standard oVirt documentation fragment
- DOCUMENTATION = r'''
-options:
- wait:
- description:
- - "C(yes) if the module should wait for the entity to get into desired state."
- type: bool
- default: yes
- fetch_nested:
- description:
- - "If I(True) the module will fetch additional data from the API."
- - "It will fetch IDs of the VMs disks, snapshots, etc. User can configure to fetch other
- attributes of the nested entities by specifying C(nested_attributes)."
- type: bool
- version_added: "2.3"
- nested_attributes:
- description:
- - "Specifies list of the attributes which should be fetched from the API."
- - "This parameter apply only when C(fetch_nested) is I(true)."
- type: list
- version_added: "2.3"
- auth:
- description:
- - "Dictionary with values needed to create HTTP/HTTPS connection to oVirt:"
- suboptions:
- username:
- description:
- - The name of the user, something like I(admin@internal).
- - Default value is set by C(OVIRT_USERNAME) environment variable.
- type: str
- required: true
- password:
- description:
- - The password of the user.
- - Default value is set by C(OVIRT_PASSWORD) environment variable.
- type: str
- required: true
- url:
- description:
- - A string containing the API URL of the server, usually something like `I(https://server.example.com/ovirt-engine/api)`.
- - Default value is set by C(OVIRT_URL) environment variable.
- - Either C(url) or C(hostname) is required.
- type: str
- hostname:
- description:
- - A string containing the hostname of the server, usually something like `I(server.example.com)`.
- - Default value is set by C(OVIRT_HOSTNAME) environment variable.
- - Either C(url) or C(hostname) is required.
- type: str
- token:
- description:
- - Token to be used instead of login with username/password.
- - Default value is set by C(OVIRT_TOKEN) environment variable.
- type: str
- insecure:
- description:
- - A boolean flag that indicates if the server TLS certificate and host name should be checked.
- type: bool
- ca_file:
- description:
- - A PEM file containing the trusted CA certificates.
- - The certificate presented by the server will be verified using these CA certificates.
- - If C(ca_file) parameter is not set, system wide CA certificate store is used.
- - Default value is set by C(OVIRT_CAFILE) environment variable.
- type: str
- kerberos:
- description:
- - A boolean flag indicating if Kerberos authentication should be used instead of the default basic authentication.
- type: bool
- headers:
- description:
- - Dictionary of HTTP headers to be added to each API call.
- type: dict
- type: dict
- required: true
- timeout:
- description:
- - "The amount of time in seconds the module should wait for the instance to
- get into desired state."
- type: int
- default: 180
- poll_interval:
- description:
- - "Number of the seconds the module waits until another poll request on entity status is sent."
- type: int
- default: 3
-requirements:
- - python >= 2.7
- - ovirt-engine-sdk-python >= 4.3.0
-notes:
- - "In order to use this module you have to install oVirt Python SDK.
- To ensure it's installed with correct version you can create the following task:
- I(pip: name=ovirt-engine-sdk-python version=4.3.0)"
-'''
diff --git a/lib/ansible/plugins/doc_fragments/ovirt_info.py b/lib/ansible/plugins/doc_fragments/ovirt_info.py
deleted file mode 100644
index b16356a230..0000000000
--- a/lib/ansible/plugins/doc_fragments/ovirt_info.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2016, Red Hat, Inc.
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-
-class ModuleDocFragment(object):
-
- # info standard oVirt documentation fragment
- DOCUMENTATION = r'''
-options:
- fetch_nested:
- description:
- - If I(yes) the module will fetch additional data from the API.
- - It will fetch only IDs of nested entity. It doesn't fetch multiple levels of nested attributes.
- Only the attributes of the current entity. User can configure to fetch other
- attributes of the nested entities by specifying C(nested_attributes).
- type: bool
- version_added: "2.3"
- nested_attributes:
- description:
- - Specifies list of the attributes which should be fetched from the API.
- - This parameter apply only when C(fetch_nested) is I(true).
- type: list
- version_added: "2.3"
- auth:
- description:
- - "Dictionary with values needed to create HTTP/HTTPS connection to oVirt:"
- - C(username)[I(required)] - The name of the user, something like I(admin@internal).
- Default value is set by I(OVIRT_USERNAME) environment variable.
- - "C(password)[I(required)] - The password of the user. Default value is set by I(OVIRT_PASSWORD) environment variable."
- - "C(url)- A string containing the API URL of the server, usually
- something like `I(https://server.example.com/ovirt-engine/api)`. Default value is set by I(OVIRT_URL) environment variable.
- Either C(url) or C(hostname) is required."
- - "C(hostname) - A string containing the hostname of the server, usually
- something like `I(server.example.com)`. Default value is set by I(OVIRT_HOSTNAME) environment variable.
- Either C(url) or C(hostname) is required."
- - "C(token) - Token to be used instead of login with username/password. Default value is set by I(OVIRT_TOKEN) environment variable."
- - "C(insecure) - A boolean flag that indicates if the server TLS
- certificate and host name should be checked."
- - "C(ca_file) - A PEM file containing the trusted CA certificates. The
- certificate presented by the server will be verified using these CA
- certificates. If `C(ca_file)` parameter is not set, system wide
- CA certificate store is used. Default value is set by I(OVIRT_CAFILE) environment variable."
- - "C(kerberos) - A boolean flag indicating if Kerberos authentication
- should be used instead of the default basic authentication."
- - "C(headers) - Dictionary of HTTP headers to be added to each API call."
- type: dict
- required: true
-requirements:
- - python >= 2.7
- - ovirt-engine-sdk-python >= 4.3.0
-notes:
- - "In order to use this module you have to install oVirt Python SDK.
- To ensure it's installed with correct version you can create the following task:
- pip: name=ovirt-engine-sdk-python version=4.3.0"
-'''
diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt
index 596b11fd39..700646dc5c 100644
--- a/test/sanity/ignore.txt
+++ b/test/sanity/ignore.txt
@@ -94,8 +94,6 @@ lib/ansible/module_utils/network/skydive/api.py future-import-boilerplate
lib/ansible/module_utils/network/skydive/api.py metaclass-boilerplate
lib/ansible/module_utils/network/vyos/vyos.py future-import-boilerplate
lib/ansible/module_utils/network/vyos/vyos.py metaclass-boilerplate
-lib/ansible/module_utils/ovirt.py future-import-boilerplate
-lib/ansible/module_utils/ovirt.py metaclass-boilerplate
lib/ansible/module_utils/parsing/convert_bool.py future-import-boilerplate
lib/ansible/module_utils/parsing/convert_bool.py metaclass-boilerplate
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.ArgvParser.psm1 pslint:PSUseApprovedVerbs
@@ -1016,256 +1014,6 @@ lib/ansible/modules/cloud/google/gcp_tpu_node_info.py validate-modules:parameter
lib/ansible/modules/cloud/hcloud/hcloud_network_info.py validate-modules:return-syntax-error
lib/ansible/modules/cloud/hcloud/hcloud_server.py validate-modules:parameter-list-no-elements
lib/ansible/modules/cloud/hcloud/hcloud_server_network.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py validate-modules:doc-required-mismatch
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_group.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py validate-modules:no-default-for-required-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_affinity_label_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_api_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py validate-modules:doc-default-does-not-match-spec
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py validate-modules:invalid-ansiblemodule-schema
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_auth.py validate-modules:undocumented-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py validate-modules:doc-choices-do-not-match-spec
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py validate-modules:no-default-for-required-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_cluster.py validate-modules:undocumented-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_cluster_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py validate-modules:no-default-for-required-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_datacenter_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py validate-modules:doc-choices-do-not-match-spec
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py validate-modules:doc-default-does-not-match-spec
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_disk.py validate-modules:undocumented-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_disk_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_event.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_event_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:doc-default-does-not-match-spec
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:doc-required-mismatch
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:no-default-for-required-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider.py validate-modules:undocumented-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py validate-modules:no-default-for-required-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_external_provider_info.py validate-modules:undocumented-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_group.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_group.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_group.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_group.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_group_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_group_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_group_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_group_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_host.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_host.py validate-modules:implied-parameter-type-mismatch
-lib/ansible/modules/cloud/ovirt/ovirt_host.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_host.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_host_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_host_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_host_network.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_network.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_network.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_host_network.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_host_network.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py validate-modules:no-default-for-required-parameter
-lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_host_pm.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_host_storage_info.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_instance_type.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_job.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_job.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_job.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_job.py validate-modules:doc-required-mismatch
-lib/ansible/modules/cloud/ovirt/ovirt_job.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_mac_pool.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_network.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_network.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_network.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_network.py validate-modules:doc-required-mismatch
-lib/ansible/modules/cloud/ovirt/ovirt_network.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_network.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_network_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_network_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_network_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_network_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_nic.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_nic.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_nic.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_nic.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_nic.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_nic_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_permission.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_permission.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_permission.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_permission.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_permission_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_quota.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_quota.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_quota.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_quota.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_quota.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_quota_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_role.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_role.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_role.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_role.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_role.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py validate-modules:doc-required-mismatch
-lib/ansible/modules/cloud/ovirt/ovirt_scheduling_policy_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_snapshot_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_storage_connection.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_storage_domain_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_storage_template_info.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_storage_vm_info.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_tag.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_tag.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_tag.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_tag.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_tag.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_tag_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_template.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_template.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_template.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_template.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_template.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_template_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_template_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_template_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_template_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_user.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_user.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_user.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_user.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_user_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_user_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_user_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_user_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_vm.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vm.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vm.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_vm.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_vm.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_vm_info.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py validate-modules:doc-missing-type
-lib/ansible/modules/cloud/ovirt/ovirt_vmpool_info.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py future-import-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py metaclass-boilerplate
-lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/cloud/ovirt/ovirt_vnic_profile_info.py validate-modules:parameter-list-no-elements
lib/ansible/modules/commands/command.py validate-modules:doc-missing-type
lib/ansible/modules/commands/command.py validate-modules:nonexistent-parameter-documented
lib/ansible/modules/commands/command.py validate-modules:parameter-list-no-elements
@@ -1667,10 +1415,6 @@ lib/ansible/plugins/doc_fragments/hcloud.py future-import-boilerplate
lib/ansible/plugins/doc_fragments/hcloud.py metaclass-boilerplate
lib/ansible/plugins/doc_fragments/inventory_cache.py future-import-boilerplate
lib/ansible/plugins/doc_fragments/inventory_cache.py metaclass-boilerplate
-lib/ansible/plugins/doc_fragments/ovirt.py future-import-boilerplate
-lib/ansible/plugins/doc_fragments/ovirt.py metaclass-boilerplate
-lib/ansible/plugins/doc_fragments/ovirt_info.py future-import-boilerplate
-lib/ansible/plugins/doc_fragments/ovirt_info.py metaclass-boilerplate
lib/ansible/plugins/doc_fragments/return_common.py future-import-boilerplate
lib/ansible/plugins/doc_fragments/return_common.py metaclass-boilerplate
lib/ansible/plugins/doc_fragments/shell_common.py future-import-boilerplate