You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ansible/lib/ansible/modules/cloud/ovirt
Ondra Machacek 8940da9b46 ovirt_host: add activate parameter (#54594) 5 years ago
..
README.rst Fix broken links. (#42323) 6 years ago
__init__.py Relocating extras into lib/ansible/modules/ after merge 8 years ago
ovirt_affinity_group.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_affinity_label.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_affinity_label_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_api_facts.py Convert to reduced list of known types (#50010) 6 years ago
ovirt_auth.py ovirt: Require SDK v4.3.0 (#54385) 5 years ago
ovirt_cluster.py Ovirt add docs suboptions (#54639) 5 years ago
ovirt_cluster_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_datacenter.py E325 Removal - Part II (#49196) 6 years ago
ovirt_datacenter_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_disk.py ovirt_disk: Support Hosted Engine content types (#54328) 5 years ago
ovirt_disk_facts.py BOTMETA.yml and module metadata: fix case authors (#46051) 6 years ago
ovirt_event.py Adding ovirt_event Module (#51760) (#52982) 5 years ago
ovirt_event_facts.py Adding ovirt_event_facts Module (#51760) (#52984) 5 years ago
ovirt_external_provider.py Convert to reduced list of known types (#50010) 6 years ago
ovirt_external_provider_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_group.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_group_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_host.py ovirt_host: add activate parameter (#54594) 5 years ago
ovirt_host_facts.py ovirt hosts facts add cluster version filtration (#48664) 6 years ago
ovirt_host_network.py ovirt: default save true in setup host networks (#49983) 5 years ago
ovirt_host_pm.py E325 Removal - Part II (#49196) 6 years ago
ovirt_host_storage_facts.py ovirt: minor typo fixes in documentation (#44345) 6 years ago
ovirt_mac_pool.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_network.py Ovirt add docs suboptions (#54639) 5 years ago
ovirt_network_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_nic.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_nic_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_permission.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_permission_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_quota.py Ovirt add docs suboptions (#54639) 5 years ago
ovirt_quota_facts.py Bulk module author 2 (#48955) 6 years ago
ovirt_scheduling_policy_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_snapshot.py add to ovirt snapshot download and upload disk (#46696) 6 years ago
ovirt_snapshot_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_storage_connection.py ovirt_storage_connection: Fix issue in detaching the connection (#50005) 6 years ago
ovirt_storage_domain.py Ovirt add docs suboptions (#54639) 5 years ago
ovirt_storage_domain_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_storage_template_facts.py Bulk module author 2 (#48955) 6 years ago
ovirt_storage_vm_facts.py Bulk module author 2 (#48955) 6 years ago
ovirt_tag.py Fix minor typos (#47381) 6 years ago
ovirt_tag_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_template.py ovirt add template version (#54675) 5 years ago
ovirt_template_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_user.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_user_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_vm.py Ovirt add docs suboptions (#54639) 5 years ago
ovirt_vm_facts.py Add next_run parameter to ovirt_vms_facts (#48347) 6 years ago
ovirt_vmpool.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_vmpool_facts.py [ovirt] remove 2.8 deprecations (#45506) 6 years ago
ovirt_vnic_profile.py Ovirt add docs suboptions (#54639) 5 years ago

README.rst

oVirt Ansible Modules
=====================

This is a set of modules for interacting with oVirt/RHV. This document
serves as developer coding guidelines for creating oVIRT/RHV modules.

Naming
------

-  All modules should start with an ``ovirt_`` prefix.
-  All modules should be named after the resource it manages in singular
   form.
-  All modules that gather facts should have a ``_facts``
   suffix.

Interface
---------

-  Every module should return the ID of the resource it manages.
-  Every module should return the dictionary of the resource it manages.
-  Never change the name of the parameter, as we guarantee backward
   compatibility. Use aliases instead.
-  If a parameter can't achieve idempotency for any reason, please
   document it.

Interoperability
----------------

-  All modules should work against all minor versions of
   version 4 of the API. Version 3 of the API is not supported.

Libraries
---------

-  All modules should use ``ovirt_full_argument_spec`` or
   ``ovirt_facts_full_argument_spec`` to pick up the standard input (such
   as auth and ``fetch_nested``).
-  All modules should use ``extends_documentation_fragment``: ovirt to go
   along with ``ovirt_full_argument_spec``.
-  All facts modules should use ``extends_documentation_fragment``:
   ``ovirt_facts`` to go along with ``ovirt_facts_full_argument_spec``.
-  Functions that are common to all modules should be implemeneted in the 
   ``module_utils/ovirt.py`` file, so they can be reused.
-  Python SDK version 4 must be used.

New module development
----------------------

Please read 
`link <https://docs.ansible.com/ansible/devel/dev_guide/developing_modules.html>`__,
first to know what common properties, functions and features every module must
have.

In order to achieve idempotency of oVirt entity attributes, a helper class
was created. The first thing you need to do is to extend this class and override a few
methods:

.. code:: python

    try:
        import ovirtsdk4.types as otypes
    except ImportError:
        pass

    from ansible.module_utils.ovirt import (
        BaseModule,
        equal
    )

    class ClustersModule(BaseModule):

        # The build method builds the entity we want to create.
        # Always be sure to build only the parameters the user specified
        # in their yaml file, so we don't change the values which we shouldn't
        # change. If you set the parameter to None, nothing will be changed.
        def build_entity(self):
            return otypes.Cluster(
                name=self.param('name'),
                comment=self.param('comment'),
                description=self.param('description'),
            )

        # The update_check method checks if the update is needed to be done on
        # the entity. The equal method doesn't check the values which are None,
        # which means it doesn't check the values which user didn't set in yaml.
        # All other values are checked and if there is found some mismatch,
        # the update method is run on the entity, the entity is build by
        # 'build_entity' method. You don't have to care about calling the update,
        # it's called behind the scene by the 'BaseModule' class.
        def update_check(self, entity):
            return (
                equal(self.param('comment'), entity.comment)
                and equal(self.param('description'), entity.description)
            )

The code above handle the check if the entity should be updated, so we
don't update the entity if not needed and also it construct the needed
entity of the SDK.

.. code:: python

    from ansible.module_utils.basic import AnsibleModule
    from ansible.module_utils.ovirt import (
        check_sdk,
        create_connection,
        ovirt_full_argument_spec,
    )

    # This module will support two states of the cluster,
    # either it will be present or absent. The user can
    # specify three parameters: name, comment and description,
    # The 'ovirt_full_argument_spec' function, will merge the
    # parameters created here with some common one like 'auth':
    argument_spec = ovirt_full_argument_spec(
        state=dict(
            choices=['present', 'absent'],
            default='present',
        ),
        name=dict(default=None, required=True),
        description=dict(default=None),
        comment=dict(default=None),
    )

    # Create the Ansible module, please always implement the
    # feautre called 'check_mode', for 'create', 'update' and
    # 'delete' operations it's implemented by default in BaseModule:
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )

    # Check if the user has Python SDK installed:
    check_sdk(module)

    try:
        auth = module.params.pop('auth')
        
        # Create the connection to the oVirt engine:
        connection = create_connection(auth)

        # Create the service which manages the entity:
        clusters_service = connection.system_service().clusters_service()

        # Create the module which will handle create, update and delete flow:
        clusters_module = ClustersModule(
            connection=connection,
            module=module,
            service=clusters_service,
        )

        # Check the state and call the appropriate method:
        state = module.params['state']
        if state == 'present':
            ret = clusters_module.create()
        elif state == 'absent':
            ret = clusters_module.remove()

        # The return value of the 'create' and 'remove' method is dictionary
        # with the 'id' of the entity we manage and the type of the entity
        # with filled in attributes of the entity. The 'change' status is
        # also returned by those methods:
        module.exit_json(**ret)
    except Exception as e:
        # Modules can't raises exception, it always must exit with
        # 'module.fail_json' in case of exception. Always use
        # 'exception=traceback.format_exc' for debugging purposes:
        module.fail_json(msg=str(e), exception=traceback.format_exc())
    finally:
        # Logout only in case the user passed the 'token' in 'auth'
        # parameter:
        connection.close(logout=auth.get('token') is None)

If your module must support action handling (for example, 
virtual machine start) you must ensure that you handle the states of the
virtual machine correctly, and document the behavior of the
module:

.. code:: python

        if state == 'running':
            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=use_cloud_init,
                use_sysprep=use_sysprep,
                # ...
            )

As you can see from the preceding example, the ``action`` method accepts the ``action_condition`` and
``wait_condition``, which are methods which accept the virtual machine
object as a parameter, so you can check whether the virtual
machine is in a proper state before the action. The rest of the
parameters are for the ``start`` action. You may also handle pre-
or post- action tasks by defining ``pre_action`` and ``post_action``
parameters.

Testing
-------

-  Integration testing is currently done in oVirt's CI system
   `here <http://jenkins.ovirt.org/view/All/job/ovirt-system-tests_ansible-suite-master/>`__
   and
   `here <https://github.com/oVirt/ovirt-system-tests/tree/master/ansible-suite-master/>`__.
-  Please consider using these integrationtests if you create a new module or add a new feature to an existing
   module.