1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/inventory/gitlab_runners.py
Felix Fontein 7fd37ea247
inventory plugins: make wrapping variables as unsafe smarter to avoid triggering an AWX bug (#8225)
Make wrapping variables as unsafe smarter to avoid triggering an AWX bug.
2024-04-20 09:39:42 +02:00

140 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (c) 2018, Stefan Heitmueller <stefan.heitmueller@gmx.com>
# Copyright (c) 2018 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
name: gitlab_runners
author:
- Stefan Heitmüller (@morph027) <stefan.heitmueller@gmx.com>
short_description: Ansible dynamic inventory plugin for GitLab runners.
requirements:
- python-gitlab > 1.8.0
extends_documentation_fragment:
- constructed
description:
- Reads inventories from the GitLab API.
- Uses a YAML configuration file gitlab_runners.[yml|yaml].
options:
plugin:
description: The name of this plugin, it should always be set to 'gitlab_runners' for this plugin to recognize it as it's own.
type: str
required: true
choices:
- gitlab_runners
- community.general.gitlab_runners
server_url:
description: The URL of the GitLab server, with protocol (i.e. http or https).
env:
- name: GITLAB_SERVER_URL
version_added: 1.0.0
type: str
required: true
api_token:
description: GitLab token for logging in.
env:
- name: GITLAB_API_TOKEN
version_added: 1.0.0
type: str
aliases:
- private_token
- access_token
filter:
description: filter runners from GitLab API
env:
- name: GITLAB_FILTER
version_added: 1.0.0
type: str
choices: ['active', 'paused', 'online', 'specific', 'shared']
verbose_output:
description: Toggle to (not) include all available nodes metadata
type: bool
default: true
'''
EXAMPLES = '''
# gitlab_runners.yml
plugin: community.general.gitlab_runners
host: https://gitlab.com
# Example using constructed features to create groups and set ansible_host
plugin: community.general.gitlab_runners
host: https://gitlab.com
strict: false
keyed_groups:
# add e.g. amd64 hosts to an arch_amd64 group
- prefix: arch
key: 'architecture'
# add e.g. linux hosts to an os_linux group
- prefix: os
key: 'platform'
# create a group per runner tag
# e.g. a runner tagged w/ "production" ends up in group "label_production"
# hint: labels containing special characters will be converted to safe names
- key: 'tag_list'
prefix: tag
'''
from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.common.text.converters import to_native
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
try:
import gitlab
HAS_GITLAB = True
except ImportError:
HAS_GITLAB = False
class InventoryModule(BaseInventoryPlugin, Constructable):
''' Host inventory parser for ansible using GitLab API as source. '''
NAME = 'community.general.gitlab_runners'
def _populate(self):
gl = gitlab.Gitlab(self.get_option('server_url'), private_token=self.get_option('api_token'))
self.inventory.add_group('gitlab_runners')
try:
if self.get_option('filter'):
runners = gl.runners.all(scope=self.get_option('filter'))
else:
runners = gl.runners.all()
for runner in runners:
host = make_unsafe(str(runner['id']))
ip_address = runner['ip_address']
host_attrs = make_unsafe(vars(gl.runners.get(runner['id']))['_attrs'])
self.inventory.add_host(host, group='gitlab_runners')
self.inventory.set_variable(host, 'ansible_host', make_unsafe(ip_address))
if self.get_option('verbose_output', True):
self.inventory.set_variable(host, 'gitlab_runner_attributes', host_attrs)
# Use constructed if applicable
strict = self.get_option('strict')
# Composed variables
self._set_composite_vars(self.get_option('compose'), host_attrs, host, strict=strict)
# Complex groups based on jinja2 conditionals, hosts that meet the conditional are added to group
self._add_host_to_composed_groups(self.get_option('groups'), host_attrs, host, strict=strict)
# Create groups based on variable values and add the corresponding hosts to it
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), host_attrs, host, strict=strict)
except Exception as e:
raise AnsibleParserError('Unable to fetch hosts from GitLab API, this was the original exception: %s' % to_native(e))
def verify_file(self, path):
"""Return the possibly of a file being consumable by this plugin."""
return (
super(InventoryModule, self).verify_file(path) and
path.endswith(("gitlab_runners.yaml", "gitlab_runners.yml")))
def parse(self, inventory, loader, path, cache=True):
if not HAS_GITLAB:
raise AnsibleError('The GitLab runners dynamic inventory plugin requires python-gitlab: https://python-gitlab.readthedocs.io/en/stable/')
super(InventoryModule, self).parse(inventory, loader, path, cache)
self._read_config_data(path)
self._populate()