mirror of https://github.com/ansible/ansible.git
Add kubevirt_template module (#52528)
* Apply suggestions from code review Co-Authored-By: machacekondra <machacek.ondra@gmail.com>pull/53130/head
parent
42ae6cdb95
commit
84cc5202db
@ -0,0 +1,359 @@
|
|||||||
|
#!/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: kubevirt_template
|
||||||
|
|
||||||
|
short_description: Manage KubeVirt templates
|
||||||
|
|
||||||
|
description:
|
||||||
|
- Use Openshift Python SDK to manage the state of KubeVirt templates.
|
||||||
|
|
||||||
|
version_added: "2.8"
|
||||||
|
|
||||||
|
author: KubeVirt Team (@kubevirt)
|
||||||
|
|
||||||
|
options:
|
||||||
|
objects:
|
||||||
|
description:
|
||||||
|
- List of any valid API objects, such as a I(DeploymentConfig), I(Service), etc. The object
|
||||||
|
will be created exactly as defined here, with any parameter values substituted in prior to creation.
|
||||||
|
The definition of these objects can reference parameters defined earlier.
|
||||||
|
- As part of the the list user can pass also I(VirtualMachine) kind. When passing I(VirtualMachine)
|
||||||
|
user must use Ansible structure of the parameters not the Kubernetes API structure. For more information
|
||||||
|
please take a look at M(kubevirt_vm) module and at EXAMPLES section, where you can see example.
|
||||||
|
type: list
|
||||||
|
display_name:
|
||||||
|
description:
|
||||||
|
- "A brief, user-friendly name, which can be employed by user interfaces."
|
||||||
|
type: str
|
||||||
|
description:
|
||||||
|
description:
|
||||||
|
- A description of the template.
|
||||||
|
- Include enough detail that the user will understand what is being deployed...
|
||||||
|
and any caveats they need to know before deploying. It should also provide links to additional information,
|
||||||
|
such as a README file."
|
||||||
|
type: str
|
||||||
|
long_description:
|
||||||
|
description:
|
||||||
|
- "Additional template description. This may be displayed by the service catalog, for example."
|
||||||
|
type: str
|
||||||
|
provider_display_name:
|
||||||
|
description:
|
||||||
|
- "The name of the person or organization providing the template."
|
||||||
|
type: str
|
||||||
|
documentation_url:
|
||||||
|
description:
|
||||||
|
- "A URL referencing further documentation for the template."
|
||||||
|
type: str
|
||||||
|
support_url:
|
||||||
|
description:
|
||||||
|
- "A URL where support can be obtained for the template."
|
||||||
|
type: str
|
||||||
|
editable:
|
||||||
|
description:
|
||||||
|
- "Extension for hinting at which elements should be considered editable.
|
||||||
|
List of jsonpath selectors. The jsonpath root is the objects: element of the template."
|
||||||
|
- This is parameter can be used only when kubevirt addon is installed on your openshift cluster.
|
||||||
|
type: list
|
||||||
|
default_disk:
|
||||||
|
description:
|
||||||
|
- "The goal of default disk is to define what kind of disk is supported by the OS mainly in
|
||||||
|
terms of bus (ide, scsi, sata, virtio, ...)"
|
||||||
|
- The C(default_disk) parameter define configuration overlay for disks that will be applied on top of disks
|
||||||
|
during virtual machine creation to define global compatibility and/or performance defaults defined here.
|
||||||
|
- This is parameter can be used only when kubevirt addon is installed on your openshift cluster.
|
||||||
|
type: dict
|
||||||
|
default_volume:
|
||||||
|
description:
|
||||||
|
- "The goal of default volume is to be able to configure mostly performance parameters like
|
||||||
|
caches if those are exposed by the underlying volume implementation."
|
||||||
|
- The C(default_volume) parameter define configuration overlay for volumes that will be applied on top of volumes
|
||||||
|
during virtual machine creation to define global compatibility and/or performance defaults defined here.
|
||||||
|
- This is parameter can be used only when kubevirt addon is installed on your openshift cluster.
|
||||||
|
type: dict
|
||||||
|
default_nic:
|
||||||
|
description:
|
||||||
|
- "The goal of default network is similar to I(default_disk) and should be used as a template
|
||||||
|
to ensure OS compatibility and performance."
|
||||||
|
- The C(default_nic) parameter define configuration overlay for nic that will be applied on top of nics
|
||||||
|
during virtual machine creation to define global compatibility and/or performance defaults defined here.
|
||||||
|
- This is parameter can be used only when kubevirt addon is installed on your openshift cluster.
|
||||||
|
type: dict
|
||||||
|
default_network:
|
||||||
|
description:
|
||||||
|
- "The goal of default network is similar to I(default_volume) and should be used as a template
|
||||||
|
that specifies performance and connection parameters (L2 bridge for example)"
|
||||||
|
- The C(default_network) parameter define configuration overlay for networks that will be applied on top of networks
|
||||||
|
during virtual machine creation to define global compatibility and/or performance defaults defined here.
|
||||||
|
- This is parameter can be used only when kubevirt addon is installed on your openshift cluster.
|
||||||
|
type: dict
|
||||||
|
icon_class:
|
||||||
|
description:
|
||||||
|
- "An icon to be displayed with your template in the web console. Choose from our existing logo
|
||||||
|
icons when possible. You can also use icons from FontAwesome. Alternatively, provide icons through
|
||||||
|
CSS customizations that can be added to an OpenShift Container Platform cluster that uses your template.
|
||||||
|
You must specify an icon class that exists, or it will prevent falling back to the generic icon."
|
||||||
|
type: str
|
||||||
|
parameters:
|
||||||
|
description:
|
||||||
|
- "Parameters allow a value to be supplied by the user or generated when the template is instantiated.
|
||||||
|
Then, that value is substituted wherever the parameter is referenced. References can be defined in any
|
||||||
|
field in the objects list field. This is useful for generating random passwords or allowing the user to
|
||||||
|
supply a host name or other user-specific value that is required to customize the template."
|
||||||
|
- "More information can be foud at: U(https://docs.openshift.com/container-platform/3.6/dev_guide/templates.html#writing-parameters)"
|
||||||
|
type: list
|
||||||
|
version:
|
||||||
|
description:
|
||||||
|
- Template structure version.
|
||||||
|
- This is parameter can be used only when kubevirt addon is installed on your openshift cluster.
|
||||||
|
type: str
|
||||||
|
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- k8s_auth_options
|
||||||
|
- k8s_resource_options
|
||||||
|
- k8s_state_options
|
||||||
|
- k8s_name_options
|
||||||
|
|
||||||
|
requirements:
|
||||||
|
- python >= 2.7
|
||||||
|
- openshift >= 0.8.2
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
- name: Create template 'mytemplate'
|
||||||
|
kubevirt_template:
|
||||||
|
state: present
|
||||||
|
name: myvmtemplate
|
||||||
|
namespace: templates
|
||||||
|
display_name: Generic cirros template
|
||||||
|
description: Basic cirros template
|
||||||
|
long_description: Verbose description of cirros template
|
||||||
|
provider_display_name: Just Be Cool, Inc.
|
||||||
|
documentation_url: http://theverycoolcompany.com
|
||||||
|
support_url: http://support.theverycoolcompany.com
|
||||||
|
icon_class: icon-linux
|
||||||
|
default_disk:
|
||||||
|
disk:
|
||||||
|
bus: virtio
|
||||||
|
default_nic:
|
||||||
|
model: virtio
|
||||||
|
default_network:
|
||||||
|
resource:
|
||||||
|
resourceName: bridge.network.kubevirt.io/cnvmgmt
|
||||||
|
default_volume:
|
||||||
|
containerDisk:
|
||||||
|
image: kubevirt/cirros-container-disk-demo:latest
|
||||||
|
objects:
|
||||||
|
- name: ${NAME}
|
||||||
|
kind: VirtualMachine
|
||||||
|
memory: ${MEMORY_SIZE}Mi
|
||||||
|
state: present
|
||||||
|
namespace: vms
|
||||||
|
parameters:
|
||||||
|
- name: NAME
|
||||||
|
description: VM name
|
||||||
|
generate: expression
|
||||||
|
from: 'vm-[A-Za-z0-9]{8}'
|
||||||
|
- name: MEMORY_SIZE
|
||||||
|
description: Memory size
|
||||||
|
value: 1Gi
|
||||||
|
|
||||||
|
- name: Remove template 'myvmtemplate'
|
||||||
|
kubevirt_template:
|
||||||
|
state: absent
|
||||||
|
name: myvmtemplate
|
||||||
|
namespace: templates
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
kubevirt_template:
|
||||||
|
description:
|
||||||
|
- The template dictionary specification returned by the API.
|
||||||
|
returned: success
|
||||||
|
type: complex
|
||||||
|
contains: {}
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
from ansible.module_utils.k8s.common import AUTH_ARG_SPEC, COMMON_ARG_SPEC
|
||||||
|
|
||||||
|
from ansible.module_utils.kubevirt import (
|
||||||
|
virtdict,
|
||||||
|
KubeVirtRawModule,
|
||||||
|
MAX_SUPPORTED_API_VERSION
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
TEMPLATE_ARG_SPEC = {
|
||||||
|
'state': {
|
||||||
|
'type': 'str',
|
||||||
|
'choices': [
|
||||||
|
'present', 'absent'
|
||||||
|
],
|
||||||
|
'default': 'present'
|
||||||
|
},
|
||||||
|
'objects': {
|
||||||
|
'type': 'list',
|
||||||
|
},
|
||||||
|
'display_name': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'description': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'long_description': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'provider_display_name': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'documentation_url': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'support_url': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'icon_class': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'version': {
|
||||||
|
'type': 'str',
|
||||||
|
},
|
||||||
|
'editable': {
|
||||||
|
'type': 'list',
|
||||||
|
},
|
||||||
|
'default_disk': {
|
||||||
|
'type': 'dict',
|
||||||
|
},
|
||||||
|
'default_volume': {
|
||||||
|
'type': 'dict',
|
||||||
|
},
|
||||||
|
'default_network': {
|
||||||
|
'type': 'dict',
|
||||||
|
},
|
||||||
|
'default_nic': {
|
||||||
|
'type': 'dict',
|
||||||
|
},
|
||||||
|
'parameters': {
|
||||||
|
'type': 'list',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class KubeVirtVMTemplate(KubeVirtRawModule):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def argspec(self):
|
||||||
|
""" argspec property builder """
|
||||||
|
argument_spec = copy.deepcopy(COMMON_ARG_SPEC)
|
||||||
|
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
|
||||||
|
argument_spec.update(TEMPLATE_ARG_SPEC)
|
||||||
|
return argument_spec
|
||||||
|
|
||||||
|
def execute_module(self):
|
||||||
|
# Parse parameters specific for this module:
|
||||||
|
definition = virtdict()
|
||||||
|
|
||||||
|
# Execute the CRUD of VM template:
|
||||||
|
kind = 'Template'
|
||||||
|
|
||||||
|
# Fill in template parameters:
|
||||||
|
definition['parameters'] = self.params.get('parameters')
|
||||||
|
|
||||||
|
# Fill in Openshift/Kubevirt template annotations:
|
||||||
|
annotations = definition['metadata']['annotations']
|
||||||
|
if self.params.get('display_name'):
|
||||||
|
annotations['openshift.io/display-name'] = self.params.get('display_name')
|
||||||
|
if self.params.get('description'):
|
||||||
|
annotations['description'] = self.params.get('description')
|
||||||
|
if self.params.get('long_description'):
|
||||||
|
annotations['openshift.io/long-description'] = self.params.get('long_description')
|
||||||
|
if self.params.get('provider_display_name'):
|
||||||
|
annotations['openshift.io/provider-display-name'] = self.params.get('provider_display_name')
|
||||||
|
if self.params.get('documentation_url'):
|
||||||
|
annotations['openshift.io/documentation-url'] = self.params.get('documentation_url')
|
||||||
|
if self.params.get('support_url'):
|
||||||
|
annotations['openshift.io/support-url'] = self.params.get('support_url')
|
||||||
|
if self.params.get('icon_class'):
|
||||||
|
annotations['iconClass'] = self.params.get('icon_class')
|
||||||
|
if self.params.get('version'):
|
||||||
|
annotations['template.cnv.io/version'] = self.params.get('version')
|
||||||
|
|
||||||
|
# TODO: Make it more Ansiblish, so user don't have to specify API JSON path, but rather Ansible params:
|
||||||
|
if self.params.get('editable'):
|
||||||
|
annotations['template.cnv.io/editable'] = self.params.get('editable')
|
||||||
|
|
||||||
|
# Set defaults annotations:
|
||||||
|
if self.params.get('default_disk'):
|
||||||
|
annotations['defaults.template.cnv.io/disk'] = self.params.get('default_disk').get('name')
|
||||||
|
if self.params.get('default_volume'):
|
||||||
|
annotations['defaults.template.cnv.io/volume'] = self.params.get('default_volume').get('name')
|
||||||
|
if self.params.get('default_nic'):
|
||||||
|
annotations['defaults.template.cnv.io/nic'] = self.params.get('default_nic').get('name')
|
||||||
|
if self.params.get('default_network'):
|
||||||
|
annotations['defaults.template.cnv.io/network'] = self.params.get('default_network').get('name')
|
||||||
|
|
||||||
|
# Proccess objects:
|
||||||
|
self.client = self.get_api_client()
|
||||||
|
definition['objects'] = []
|
||||||
|
objects = self.params.get('objects') or []
|
||||||
|
for obj in objects:
|
||||||
|
if obj['kind'] != 'VirtualMachine':
|
||||||
|
definition['objects'].append(obj)
|
||||||
|
else:
|
||||||
|
vm_definition = virtdict()
|
||||||
|
|
||||||
|
# Set VM defaults:
|
||||||
|
if self.params.get('default_disk'):
|
||||||
|
vm_definition['spec']['template']['spec']['domain']['devices']['disks'] = [self.params.get('default_disk')]
|
||||||
|
if self.params.get('default_volume'):
|
||||||
|
vm_definition['spec']['template']['spec']['volumes'] = [self.params.get('default_volume')]
|
||||||
|
if self.params.get('default_nic'):
|
||||||
|
vm_definition['spec']['template']['spec']['domain']['devices']['interfaces'] = [self.params.get('default_nic')]
|
||||||
|
if self.params.get('default_network'):
|
||||||
|
vm_definition['spec']['template']['spec']['networks'] = [self.params.get('default_network')]
|
||||||
|
|
||||||
|
# Set kubevirt API version:
|
||||||
|
vm_definition['apiVersion'] = MAX_SUPPORTED_API_VERSION
|
||||||
|
|
||||||
|
# Contruct k8s vm API object:
|
||||||
|
vm_template = vm_definition['spec']['template']
|
||||||
|
dummy, vm_def = self.construct_vm_template_definition('VirtualMachine', vm_definition, vm_template, obj)
|
||||||
|
|
||||||
|
definition['objects'].append(vm_def)
|
||||||
|
result = self.execute_crud(kind, definition)
|
||||||
|
|
||||||
|
# Return from the module:
|
||||||
|
self.exit_json(**{
|
||||||
|
'changed': result['changed'],
|
||||||
|
'kubevirt_template': result.pop('result'),
|
||||||
|
'result': result,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
module = KubeVirtVMTemplate()
|
||||||
|
try:
|
||||||
|
module.execute_module()
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg=str(e), exception=traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue