[oVirt] Update/Add functionalities for import storage domain (#26568)
* ovirt_templates: Update the argument spec of templates. Add id of template since it is needed for register. * ovirt_vms: Register unregistered VM. Use register of VM with id instead of name since an unregitered entity can be registered also without name attribute. * ovirt_hosts: Add iscsidiscover to ovirt_hosts Adding functionality of iscsidiscover to be used to discover iscsi targets. * ovirt_storage_domains: Add support for import block storage domain. * Add functionality of partial import to unregistered VMs. * Add functionality of partial import to unregistered Templates. * ovirt_hosts: Add iscsilogin to ovirt hosts. Add functionality of iscsi login to ovirt hosts to be used to connect to iscsi targets and to be able to import iSCSI storage domain eventually. * Add ovirt_storage_templates_facts Adding fact module for storage templates. The module should help with registering unregistered templates. * Add ovirt_storage_vms_facts Adding fact module for storage VMs. The module should help with registering unregistered VMs.
This commit is contained in:
parent
2f3d9566f9
commit
07feec30d3
7 changed files with 458 additions and 40 deletions
|
@ -746,6 +746,17 @@ class BaseModule(object):
|
|||
'diff': self._diff,
|
||||
}
|
||||
|
||||
def wait_for_import(self):
|
||||
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:
|
||||
return entity
|
||||
time.sleep(poll_interval)
|
||||
|
||||
def search_entity(self, search_params=None):
|
||||
"""
|
||||
Always first try to search by `ID`, if ID isn't specified,
|
||||
|
@ -755,10 +766,10 @@ class BaseModule(object):
|
|||
entity = None
|
||||
|
||||
if 'id' in self._module.params and self._module.params['id'] is not None:
|
||||
entity = search_by_attributes(self._service, id=self._module.params['id'])
|
||||
entity = get_entity(self._service.service(self._module.params['id']))
|
||||
elif search_params is not None:
|
||||
entity = search_by_attributes(self._service, **search_params)
|
||||
elif 'name' in self._module.params and self._module.params['name'] is not None:
|
||||
elif self._module.params.get('name') is not None:
|
||||
entity = search_by_attributes(self._service, name=self._module.params['name'])
|
||||
|
||||
return entity
|
||||
|
|
|
@ -40,9 +40,10 @@ options:
|
|||
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'
|
||||
'restarted', 'stopped', 'reinstalled', 'iscsidiscover', 'iscsilogin'
|
||||
]
|
||||
default: present
|
||||
comment:
|
||||
|
@ -108,6 +109,13 @@ options:
|
|||
- "Enable or disable power management of the host."
|
||||
- "For more comprehensive setup of PM use C(ovirt_host_pm) module."
|
||||
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"
|
||||
version_added: "2.4"
|
||||
extends_documentation_fragment: ovirt
|
||||
'''
|
||||
|
||||
|
@ -158,6 +166,29 @@ EXAMPLES = '''
|
|||
state: upgraded
|
||||
name: myhost
|
||||
|
||||
# discover iscsi targets
|
||||
- ovirt_hosts:
|
||||
state: iscsidiscover
|
||||
name: myhost
|
||||
iscsi:
|
||||
username: iscsi_user
|
||||
password: secret
|
||||
address: 10.34.61.145
|
||||
port: 3260
|
||||
|
||||
|
||||
# login to iscsi targets
|
||||
- ovirt_hosts:
|
||||
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_hosts:
|
||||
state: reinstalled
|
||||
|
@ -182,6 +213,10 @@ host:
|
|||
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
|
||||
|
@ -200,6 +235,7 @@ from ansible.module_utils.ovirt import (
|
|||
check_sdk,
|
||||
create_connection,
|
||||
equal,
|
||||
get_id_by_name,
|
||||
ovirt_full_argument_spec,
|
||||
wait,
|
||||
)
|
||||
|
@ -327,7 +363,7 @@ def main():
|
|||
state=dict(
|
||||
choices=[
|
||||
'present', 'absent', 'maintenance', 'upgraded', 'started',
|
||||
'restarted', 'stopped', 'reinstalled',
|
||||
'restarted', 'stopped', 'reinstalled', 'iscsidiscover', 'iscsilogin'
|
||||
],
|
||||
default='present',
|
||||
),
|
||||
|
@ -346,10 +382,15 @@ def main():
|
|||
kernel_params=dict(default=None, type='list'),
|
||||
hosted_engine=dict(default=None, choices=['deploy', 'undeploy']),
|
||||
power_management_enabled=dict(default=None, type='bool'),
|
||||
iscsi=dict(default=None, type='dict'),
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
required_if=[
|
||||
['state', 'iscsidiscover', ['iscsi']],
|
||||
['state', 'iscsilogin', ['iscsi']]
|
||||
]
|
||||
)
|
||||
check_sdk(module)
|
||||
|
||||
|
@ -396,6 +437,33 @@ def main():
|
|||
post_action=lambda h: time.sleep(module.params['poll_interval']),
|
||||
fail_condition=failed_state,
|
||||
)
|
||||
elif state == 'iscsidiscover':
|
||||
host_id = get_id_by_name(hosts_service, module.params['name'])
|
||||
iscsi_targets = hosts_service.service(host_id).iscsi_discover(
|
||||
iscsi=otypes.IscsiDetails(
|
||||
port=int(module.params['iscsi']['port']) if module.params['iscsi']['port'].isdigit() else None,
|
||||
username=module.params['iscsi']['username'],
|
||||
password=module.params['iscsi']['password'],
|
||||
address=module.params['iscsi']['address'],
|
||||
),
|
||||
)
|
||||
ret = {
|
||||
'changed': False,
|
||||
'id': host_id,
|
||||
'iscsi_targets': iscsi_targets,
|
||||
}
|
||||
elif state == 'iscsilogin':
|
||||
host_id = get_id_by_name(hosts_service, module.params['name'])
|
||||
ret = hosts_module.action(
|
||||
action='iscsi_login',
|
||||
iscsi=otypes.IscsiDetails(
|
||||
port=int(module.params['iscsi']['port']) if module.params['iscsi']['port'].isdigit() else None,
|
||||
username=module.params['iscsi']['username'],
|
||||
password=module.params['iscsi']['password'],
|
||||
address=module.params['iscsi']['address'],
|
||||
target=module.params['iscsi']['target'],
|
||||
),
|
||||
)
|
||||
elif state == 'started':
|
||||
ret = hosts_module.action(
|
||||
action='fence',
|
||||
|
|
|
@ -33,12 +33,17 @@ 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."
|
||||
state:
|
||||
description:
|
||||
- "Should the storage domain be present/absent/maintenance/unattached"
|
||||
- "Should the storage domain be present/absent/maintenance/unattached/imported"
|
||||
- "I(imported) is supported since version 2.4."
|
||||
choices: ['present', 'absent', 'maintenance', 'unattached']
|
||||
default: present
|
||||
description:
|
||||
|
@ -256,6 +261,8 @@ class StorageDomainModule(BaseModule):
|
|||
name=self._module.params['name'],
|
||||
description=self._module.params['description'],
|
||||
comment=self._module.params['comment'],
|
||||
import_=True if (self._module.params['state'] == 'imported' and storage_type in ['iscsi', 'fcp']) else None,
|
||||
id=self._module.params['id'] if (self._module.params['state'] == 'imported' and storage_type in ['iscsi', 'fcp']) else None,
|
||||
type=otypes.StorageDomainType(
|
||||
self._module.params['domain_function']
|
||||
),
|
||||
|
@ -423,9 +430,10 @@ def control_state(sd_module):
|
|||
def main():
|
||||
argument_spec = ovirt_full_argument_spec(
|
||||
state=dict(
|
||||
choices=['present', 'absent', 'maintenance', 'unattached'],
|
||||
choices=['present', 'absent', 'maintenance', 'unattached', 'imported'],
|
||||
default='present',
|
||||
),
|
||||
id=dict(default=None),
|
||||
name=dict(required=True),
|
||||
description=dict(default=None),
|
||||
comment=dict(default=None),
|
||||
|
@ -465,7 +473,7 @@ def main():
|
|||
format=module.params['format'],
|
||||
host=module.params['host'],
|
||||
)
|
||||
elif state == 'present':
|
||||
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(
|
||||
|
|
123
lib/ansible/modules/cloud/ovirt/ovirt_storage_templates_facts.py
Normal file
123
lib/ansible/modules/cloud/ovirt/ovirt_storage_templates_facts.py
Normal file
|
@ -0,0 +1,123 @@
|
|||
#!/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_templates_facts
|
||||
short_description: Retrieve facts about one or more oVirt/RHV templates relate to a storage domain.
|
||||
author: "Maor Lipchuk"
|
||||
version_added: "2.4"
|
||||
description:
|
||||
- "Retrieve facts about one or more oVirt/RHV templates relate to a storage domain."
|
||||
notes:
|
||||
- "This module creates a new top-level C(ovirt_storage_templates) fact, which
|
||||
contains a list of templates."
|
||||
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."
|
||||
|
||||
extends_documentation_fragment: ovirt_facts
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Examples don't contain auth parameter for simplicity,
|
||||
# look at ovirt_auth module to see how to reuse authentication:
|
||||
|
||||
# Gather facts about all Templates which relate to a storage domain and
|
||||
# are unregistered:
|
||||
- ovirt_storage_templates_facts:
|
||||
unregistered=True
|
||||
- debug:
|
||||
var: ovirt_storage_templates
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
ovirt_storage_templates:
|
||||
description: "List of dictionaries describing the Templates. Template attribues 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_facts_full_argument_spec,
|
||||
get_id_by_name
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = ovirt_facts_full_argument_spec(
|
||||
all_content=dict(default=False, type='bool'),
|
||||
case_sensitive=dict(default=True, type='bool'),
|
||||
storage_domain=dict(default=None),
|
||||
max=dict(default=None, type='int'),
|
||||
unregistered=dict(default=False, type='bool'),
|
||||
)
|
||||
module = AnsibleModule(argument_spec)
|
||||
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 the unregistered Template we want to register:
|
||||
if module.params.get('unregistered'):
|
||||
templates = templates_service.list(unregistered=True)
|
||||
else:
|
||||
templates = templates_service.list()
|
||||
module.exit_json(
|
||||
changed=False,
|
||||
ansible_facts=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
|
||||
],
|
||||
),
|
||||
)
|
||||
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()
|
122
lib/ansible/modules/cloud/ovirt/ovirt_storage_vms_facts.py
Normal file
122
lib/ansible/modules/cloud/ovirt/ovirt_storage_vms_facts.py
Normal file
|
@ -0,0 +1,122 @@
|
|||
#!/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_vms_facts
|
||||
short_description: Retrieve facts about one or more oVirt/RHV virtual machines relate to a storage domain.
|
||||
author: "Maor Lipchuk"
|
||||
version_added: "2.4"
|
||||
description:
|
||||
- "Retrieve facts about one or more oVirt/RHV virtual machines relate to a storage domain."
|
||||
notes:
|
||||
- "This module creates a new top-level C(ovirt_storage_vms) fact, which
|
||||
contains a list of virtual machines."
|
||||
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."
|
||||
extends_documentation_fragment: ovirt_facts
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Examples don't contain auth parameter for simplicity,
|
||||
# look at ovirt_auth module to see how to reuse authentication:
|
||||
|
||||
# Gather facts about all VMs which relate to a storage domain and
|
||||
# are unregistered:
|
||||
- ovirt_vms_facts:
|
||||
unregistered=True
|
||||
- debug:
|
||||
var: ovirt_storage_vms
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
ovirt_storage_vms:
|
||||
description: "List of dictionaries describing the VMs. VM attribues 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_facts_full_argument_spec,
|
||||
get_id_by_name
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = ovirt_facts_full_argument_spec(
|
||||
all_content=dict(default=False, type='bool'),
|
||||
case_sensitive=dict(default=True, type='bool'),
|
||||
storage_domain=dict(default=None),
|
||||
max=dict(default=None, type='int'),
|
||||
unregistered=dict(default=False, type='bool'),
|
||||
)
|
||||
module = AnsibleModule(argument_spec)
|
||||
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 the unregistered VM we want to register:
|
||||
if module.params.get('unregistered'):
|
||||
vms = vms_service.list(unregistered=True)
|
||||
else:
|
||||
vms = vms_service.list()
|
||||
module.exit_json(
|
||||
changed=False,
|
||||
ansible_facts=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
|
||||
],
|
||||
),
|
||||
)
|
||||
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()
|
|
@ -36,13 +36,16 @@ options:
|
|||
name:
|
||||
description:
|
||||
- "Name of the template to manage."
|
||||
required: true
|
||||
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 then we fail
|
||||
to register the unregistered template."
|
||||
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:
|
||||
|
@ -57,6 +60,10 @@ options:
|
|||
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."
|
||||
version_added: "2.4"
|
||||
exclusive:
|
||||
description:
|
||||
- "When C(state) is I(exported) this parameter indicates if the existing templates with the
|
||||
|
@ -120,9 +127,24 @@ EXAMPLES = '''
|
|||
# Register template
|
||||
- ovirt_templates:
|
||||
state: registered
|
||||
name: mytemplate
|
||||
storage_domain: mystorage
|
||||
cluster: mycluster
|
||||
name: mytemplate
|
||||
|
||||
# Register template using id
|
||||
- ovirt_templates:
|
||||
state: registered
|
||||
storage_domain: mystorage
|
||||
cluster: mycluster
|
||||
id: 1111-1111-1111-1111
|
||||
|
||||
# Register template, allowing partial import
|
||||
- ovirt_templates:
|
||||
state: registered
|
||||
storage_domain: mystorage
|
||||
allow_partial_import: "True"
|
||||
cluster: mycluster
|
||||
id: 1111-1111-1111-1111
|
||||
|
||||
# Import image from Glance s a template
|
||||
- ovirt_templates:
|
||||
|
@ -216,28 +238,18 @@ class TemplatesModule(BaseModule):
|
|||
self._service = self._connection.system_service().templates_service()
|
||||
|
||||
|
||||
def wait_for_import(module, templates_service):
|
||||
if module.params['wait']:
|
||||
start = time.time()
|
||||
timeout = module.params['timeout']
|
||||
poll_interval = module.params['poll_interval']
|
||||
while time.time() < start + timeout:
|
||||
template = search_by_name(templates_service, module.params['name'])
|
||||
if template:
|
||||
return template
|
||||
time.sleep(poll_interval)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = ovirt_full_argument_spec(
|
||||
state=dict(
|
||||
choices=['present', 'absent', 'exported', 'imported', 'registered'],
|
||||
default='present',
|
||||
),
|
||||
name=dict(default=None, required=True),
|
||||
id=dict(default=None),
|
||||
name=dict(default=None),
|
||||
vm=dict(default=None),
|
||||
description=dict(default=None),
|
||||
cluster=dict(default=None),
|
||||
allow_partial_import=dict(default=None, type='bool'),
|
||||
cpu_profile=dict(default=None),
|
||||
disks=dict(default=[], type='list'),
|
||||
clone_permissions=dict(type='bool'),
|
||||
|
@ -251,6 +263,7 @@ def main():
|
|||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
required_one_of=[['id', 'name']],
|
||||
)
|
||||
check_sdk(module)
|
||||
|
||||
|
@ -328,7 +341,7 @@ def main():
|
|||
) if module.params['cluster'] else None,
|
||||
**kwargs
|
||||
)
|
||||
template = wait_for_import(module, templates_service)
|
||||
template = templates_module.wait_for_import()
|
||||
ret = {
|
||||
'changed': True,
|
||||
'id': template.id,
|
||||
|
@ -344,32 +357,32 @@ def main():
|
|||
# Find the unregistered Template we want to register:
|
||||
templates = templates_service.list(unregistered=True)
|
||||
template = next(
|
||||
(t for t in templates if t.name == module.params['name']),
|
||||
(t for t in templates if (t.id == module.params['id'] or t.name == module.params['name'])),
|
||||
None
|
||||
)
|
||||
changed = False
|
||||
if template is None:
|
||||
# Test if template is registered:
|
||||
template = templates_module.search_entity()
|
||||
if template is None:
|
||||
raise ValueError(
|
||||
"Template with name '%s' wasn't found." % module.params['name']
|
||||
"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)
|
||||
# Register the template into the system:
|
||||
template_service.register(
|
||||
allow_partial_import=module.params['allow_partial_import'],
|
||||
cluster=otypes.Cluster(
|
||||
name=module.params['cluster']
|
||||
) if module.params['cluster'] else None,
|
||||
template=otypes.Template(
|
||||
name=module.params['name'],
|
||||
),
|
||||
) if module.params['cluster'] else None
|
||||
)
|
||||
if module.params['wait']:
|
||||
template = wait_for_import(module, templates_service)
|
||||
|
||||
if module.params['wait']:
|
||||
template = templates_module.wait_for_import()
|
||||
else:
|
||||
# Fetch template to initialize return.
|
||||
template = template_service.get()
|
||||
ret = {
|
||||
'changed': changed,
|
||||
'id': template.id,
|
||||
|
|
|
@ -43,15 +43,23 @@ options:
|
|||
- "ID of the Virtual Machine to manage."
|
||||
state:
|
||||
description:
|
||||
- "Should the Virtual Machine be running/stopped/present/absent/suspended/next_run."
|
||||
- "Should the Virtual Machine be running/stopped/present/absent/suspended/next_run/registered.
|
||||
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) and I(running) are equal states."
|
||||
- "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."
|
||||
choices: ['running', 'stopped', 'present', 'absent', 'suspended', 'next_run']
|
||||
- "I(registered) is supported since 2.4"
|
||||
choices: ['running', 'stopped', 'present', 'absent', 'suspended', 'next_run', 'registered']
|
||||
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."
|
||||
version_added: "2.4"
|
||||
template:
|
||||
description:
|
||||
- "Name of the template, which should be used to create Virtual Machine. Required if creating VM."
|
||||
|
@ -354,6 +362,28 @@ ovirt_vms:
|
|||
name: myvm
|
||||
template: rhel7_template
|
||||
|
||||
# Register VM
|
||||
ovirt_vms:
|
||||
state: registered
|
||||
storage_domain: mystorage
|
||||
cluster: mycluster
|
||||
name: myvm
|
||||
|
||||
# Register VM using id
|
||||
ovirt_vms:
|
||||
state: registered
|
||||
storage_domain: mystorage
|
||||
cluster: mycluster
|
||||
id: 1111-1111-1111-1111
|
||||
|
||||
# Register VM, allowing partial import
|
||||
ovirt_vms:
|
||||
state: registered
|
||||
storage_domain: mystorage
|
||||
allow_partial_import: "True"
|
||||
cluster: mycluster
|
||||
id: 1111-1111-1111-1111
|
||||
|
||||
# Creates a stateless VM which will always use latest template version:
|
||||
ovirt_vms:
|
||||
name: myvm
|
||||
|
@ -522,7 +552,6 @@ vm:
|
|||
returned: On success if VM is found.
|
||||
type: dict
|
||||
'''
|
||||
|
||||
import traceback
|
||||
|
||||
try:
|
||||
|
@ -538,6 +567,7 @@ from ansible.module_utils.ovirt import (
|
|||
convert_to_bytes,
|
||||
create_connection,
|
||||
equal,
|
||||
get_dict_of_struct,
|
||||
get_entity,
|
||||
get_link_name,
|
||||
get_id_by_name,
|
||||
|
@ -1053,16 +1083,16 @@ def control_state(vm, vms_service, module):
|
|||
condition=lambda vm: vm.status in [otypes.VmStatus.DOWN, otypes.VmStatus.UP],
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = ovirt_full_argument_spec(
|
||||
state=dict(
|
||||
choices=['running', 'stopped', 'present', 'absent', 'suspended', 'next_run'],
|
||||
choices=['running', 'stopped', 'present', 'absent', 'suspended', 'next_run', 'registered'],
|
||||
default='present',
|
||||
),
|
||||
name=dict(default=None),
|
||||
id=dict(default=None),
|
||||
cluster=dict(default=None),
|
||||
allow_partial_import=dict(default=None, type='bool'),
|
||||
template=dict(default=None),
|
||||
template_version=dict(default=None, type='int'),
|
||||
use_latest_template_version=dict(default=None, type='bool'),
|
||||
|
@ -1119,6 +1149,7 @@ def main():
|
|||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
required_one_of=[['id', 'name']],
|
||||
)
|
||||
check_sdk(module)
|
||||
check_params(module)
|
||||
|
@ -1243,6 +1274,48 @@ def main():
|
|||
)
|
||||
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 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
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
module.exit_json(**ret)
|
||||
except Exception as e:
|
||||
|
|
Loading…
Reference in a new issue