Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ovirt dynamic plugin improvements #3

Merged
merged 4 commits into from
Mar 10, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 46 additions & 52 deletions plugins/inventory/ovirt.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
Expand All @@ -9,6 +10,7 @@
name: ovirt
plugin_type: inventory
short_description: oVirt inventory source
version_added: "1.0.0"
author: Bram Verschueren (@bverschueren)
requirements:
- ovirt-engine-sdk-python >= 4.2.4
Expand Down Expand Up @@ -39,37 +41,45 @@
env:
- name: OVIRT_PASSWORD
ovirt_cafile:
description: path to ovirt-engine CA file.
description: path to ovirt-engine CA file. If C(ovirt_cafile) parameter is not set and C(ovirt_insecure) is not True, system wide CA certificate store\
is used.
required: False
ovirt_insecure:
description: A boolean flag that indicates if the server TLS certificate and host name should be checked.
required: False
default: False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't default value None?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connection expects a boolean for insecure.
As discussed in the original PR (ansible/ansible#49085 (comment)), this differs in the way insecure is handled in the other modules (e.g. ovirt_auth.py) where the value toggles to True in case insecure is None (default) and no CA is provided. I'd prefer to default to False - and possibly fail in the sdk - in case no CA is given and system CA's cannot verify a server.

ovirt_query_filter:
required: false
required: False
description: dictionary of filter key-values to query VM's. See U(https://ovirt.github.io/ovirt-engine-sdk/master/services.m.html#ovirtsdk4\
.services.VmsService.list) for filter parameters.
ovirt_hostname_preference:
required: false
required: False
description: list of options that describe the ordering for which hostnames should be assigned. See U(https://ovirt.github.io/ovirt-engin\
e-api-model/master/#types/vm) for available attributes.
default: ['fqdn', 'name']
type: list
'''

EXAMPLES = '''
# Sample content of ovirt.yml
# plugin: ovirt
# ovirt_url: http://localhost/ovirt-engine/api
# ovirt_username: ansible-tester
# ovirt_password: secure
# ovirt_query_filter:
# search: 'name=myvm AND cluster=mycluster'
# case_sensitive: no
# max: 15
# keyed_groups:
# - key: cluster
# prefix: 'cluster'
# groups:
# dev: "'dev' in tags"
# compose:
# ansible_host: devices["eth0"][0]
# Ensure the CA is available:
# $ wget "https://engine/ovirt-engine/services/pki-resource?resource=ca-certificate&format=X509-PEM-CA" -O /path/to/ca.pem
# Sample content of ovirt.yml:
plugin: ovirt
ovirt_url: https://engine/ovirt-engine/api
ovirt_cafile: /path/to/ca.pem
ovirt_username: ansible-tester
ovirt_password: secure
ovirt_query_filter:
search: 'name=myvm AND cluster=mycluster'
case_sensitive: no
max: 15
keyed_groups:
- key: cluster
prefix: 'cluster'
groups:
dev: "'dev' in tags"
compose:
ansible_host: devices["eth0"][0]
'''

import sys
Expand All @@ -88,33 +98,16 @@

class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):

NAME = 'ovirt'

def __init__(self):

super(InventoryModule, self).__init__()
self.connection = None

def _get_connection(self):
if self.connection is None:
self.connection = sdk.Connection(
url=self.ovirt_engine_url,
username=self.ovirt_engine_user,
password=self.ovirt_engine_password,
ca_file=self.ovirt_engine_cafile
)
return self.connection
NAME = 'ovirt.ovirt_collection.ovirt'

def _get_dict_of_struct(self, vm):
''' Transform SDK Vm Struct type to Python dictionary.
:param vm: host struct of which to create dict
:return dict of vm struct type
'''

connection = self._get_connection()

vms_service = connection.system_service().vms_service()
clusters_service = connection.system_service().clusters_service()
vms_service = self.connection.system_service().vms_service()
clusters_service = self.connection.system_service().clusters_service()
vm_service = vms_service.vm_service(vm.id)
devices = vm_service.reported_devices_service().list()
tags = vm_service.tags_service().list()
Expand All @@ -127,21 +120,21 @@ def _get_dict_of_struct(self, vm):
return {
'id': vm.id,
'name': vm.name,
'host': connection.follow_link(vm.host).name if vm.host else None,
'cluster': connection.follow_link(vm.cluster).name,
'host': self.connection.follow_link(vm.host).name if vm.host else None,
'cluster': self.connection.follow_link(vm.cluster).name,
'status': str(vm.status),
'description': vm.description,
'fqdn': vm.fqdn,
'os_type': vm.os.type,
'template': connection.follow_link(vm.template).name,
'template': self.connection.follow_link(vm.template).name,
'tags': [tag.name for tag in tags],
'affinity_labels': [label.name for label in labels],
'affinity_groups': [
group.name for group in groups
if vm.name in [vm.name for vm in connection.follow_link(group.vms)]
if vm.name in [vm.name for vm in self.connection.follow_link(group.vms)]
],
'statistics': dict(
(stat.name, stat.values[0].datum) for stat in stats
(stat.name, stat.values[0].datum if stat.values else None) for stat in stats
),
'devices': dict(
(device.name, [ip.address for ip in device.ips]) for device in devices if device.ips
Expand All @@ -160,13 +153,11 @@ def _get_hosts(self, query_filter=None):
:param filter: dictionary of vm filter parameter/values
:return list of oVirt vm structs
'''
connection = self._get_connection()

vms_service = connection.system_service().vms_service()
vms_service = self.connection.system_service().vms_service()
if query_filter is not None:
return vms_service.list(**query_filter)
else:
return vms_service.list()
return vms_service.list()

def _get_query_options(self, param_dict):
''' Get filter parameters and cast these to comply with sdk VmsService.list param types
Expand Down Expand Up @@ -245,10 +236,13 @@ def parse(self, inventory, loader, path, cache=True):

config = self._read_config_data(path)

self.ovirt_engine_url = self.get_option('ovirt_url')
self.ovirt_engine_user = self.get_option('ovirt_username')
self.ovirt_engine_password = self.get_option('ovirt_password')
self.ovirt_engine_cafile = self.get_option('ovirt_cafile')
self.connection = sdk.Connection(
url=self.get_option('ovirt_url'),
username=self.get_option('ovirt_username'),
password=self.get_option('ovirt_password'),
ca_file=self.get_option('ovirt_cafile'),
insecure=self.get_option('ovirt_insecure'),
)

query_filter = self._get_query_options(self.get_option('ovirt_query_filter', None))

Expand Down