mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
template add cloud init (#55379)
* template add cloud init * template add cloud init persist doc * remove duplicate version * ovirt_template add sysprep * update ovirt_template docs * update ovirt_template examples * update ovirt_template docs - pep8 * template remove cloud init persist
This commit is contained in:
parent
f5b3983aa8
commit
748af9db74
1 changed files with 369 additions and 0 deletions
|
@ -189,6 +189,176 @@ options:
|
|||
- 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
|
||||
'''
|
||||
|
||||
|
@ -300,6 +470,62 @@ EXAMPLES = '''
|
|||
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 = '''
|
||||
|
@ -341,6 +567,10 @@ from ansible.module_utils.ovirt import (
|
|||
|
||||
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'],
|
||||
|
@ -358,26 +588,44 @@ class TemplatesModule(BaseModule):
|
|||
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):
|
||||
|
@ -388,12 +636,123 @@ class TemplatesModule(BaseModule):
|
|||
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
|
||||
|
@ -524,8 +883,12 @@ def main():
|
|||
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'),
|
||||
|
@ -534,6 +897,8 @@ def main():
|
|||
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),
|
||||
|
@ -547,6 +912,10 @@ def main():
|
|||
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,
|
||||
|
|
Loading…
Reference in a new issue