callback: Add support for specifying default playbook labels

This allows users to set default playbooks labels without needing to
specify the 'ara_playbook_label' variable.

In practice, it can be used to set labels on playbooks without needing
to modify playbooks or the playbook vars.

Fixes: https://github.com/ansible-community/ara/issues/95
Change-Id: Ib1d3b33d1766905061e5534677764aa9c42a99b0
This commit is contained in:
David Moreau Simard 2019-11-29 12:24:46 -05:00
parent 8d9af9b8dc
commit a8b8ff5c59
5 changed files with 81 additions and 25 deletions

View File

@ -105,6 +105,15 @@ options:
ini:
- section: ara
key: api_timeout
default_labels:
description: A list of default labels that will be applied to playbooks
type: list
default: []
env:
- name: ARA_DEFAULT_LABELS
ini:
- section: ara
key: default_labels
ignored_facts:
description: List of host facts that will not be saved by ARA
type: list
@ -154,6 +163,7 @@ class CallbackModule(CallbackBase):
def set_options(self, task_keys=None, var_options=None, direct=None):
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
self.default_labels = self.get_option("default_labels")
self.ignored_facts = self.get_option("ignored_facts")
self.ignored_arguments = self.get_option("ignored_arguments")
@ -206,8 +216,20 @@ class CallbackModule(CallbackBase):
play_vars = play._variable_manager.get_vars(play=play)["vars"]
if "ara_playbook_name" in play_vars:
self._set_playbook_name(name=play_vars["ara_playbook_name"])
labels = self.default_labels
if "ara_playbook_labels" in play_vars:
self._set_playbook_labels(labels=play_vars["ara_playbook_labels"])
# ara_playbook_labels can be supplied as a list inside a playbook
# but it might also be specified as a comma separated string when
# using extra-vars
if isinstance(play_vars["ara_playbook_labels"], list):
labels.extend(play_vars["ara_playbook_labels"])
elif isinstance(play_vars["ara_playbook_labels"], str):
labels.extend(play_vars["ara_playbook_labels"].split(","))
else:
raise TypeError("ara_playbook_labels must be a list or a comma-separated string")
if labels:
self._set_playbook_labels(labels=labels)
# Record all the files involved in the play
for path in play._loader._FILE_CACHE.keys():
@ -307,7 +329,7 @@ class CallbackModule(CallbackBase):
self.playbook = self.client.patch("/api/v1/playbooks/%s" % self.playbook["id"], name=name)
def _set_playbook_labels(self, labels):
if self.playbook["labels"] != labels:
if sorted(self.playbook["labels"]) != sorted(labels):
self.playbook = self.client.patch("/api/v1/playbooks/%s" % self.playbook["id"], labels=labels)
def _get_or_create_file(self, path):

View File

@ -48,6 +48,7 @@ an ``ansible.cfg`` file:
api_username = user
api_password = password
api_timeout = 15
default_labels = dev,deploy
ignored_facts = '["ansible_env", "ansible_all_ipv4_addresses"]'
ignored_arguments = '["extra_vars", "vault_password_files"]'
@ -60,6 +61,7 @@ or as environment variables:
export ARA_API_USERNAME=user
export ARA_API_PASSWORD=password
export ARA_API_TIMEOUT=15
export ARA_DEFAULT_LABELS=dev,deploy
export ARA_IGNORED_FACTS='["ansible_env", "ansible_all_ipv4_addresses"]'
export ARA_IGNORED_ARGUMENTS='["extra_vars", "vault_password_files"]'

View File

@ -1,33 +1,22 @@
Setting playbook names and labels
=================================
Playbook names and labels
=========================
ARA provides the ability for users to specify playbook names and labels in
order to better distinguish playbooks run in different environments or purposes.
ARA allows users to specify playbook names and labels in order to better
distinguish playbooks run in different environments or for different purposes.
Names and labels are also searchable by the ARA API, allowing you to find
playbooks matching your query.
Once your playbooks have names and labels, the API allows you to easily search
for them, for example:
- ``/api/v1/playbooks?name=<playbook_name>``
- ``/api/v1/playbooks?label=<label_name>``
Names and labels are set as regular Ansible variables:
- ``ara_playbook_name``
- ``ara_playbook_labels``
These variables can be provided by your Ansible inventory, directly in your
playbook file, as extra-vars or any other way supported by Ansible.
For example, in an inventory:
.. code-block:: ini
[dev]
host1
host2
[dev:vars]
ara_playbook_name=deploy-dev
ara_playbook_labels='["deploy", "dev"]'
In a playbook:
These variables are picked up by ARA at the beginning of a play and can be
provided directly in your playbook file:
.. code-block:: yaml
@ -47,4 +36,25 @@ Or as extra-vars:
ansible-playbook -i hosts playbook.yaml \
-e ara_playbook_name=deploy-dev \
-e ara_playbook_labels='["deploy", "dev"]'
-e ara_playbook_labels=deploy,dev
Default labels
--------------
If necessary, ARA can be configured to set one or more labels on every recorded
playbook by default.
This can be done either through an ``ansible.cfg`` file like so:
.. code-block:: ini
[defaults]
# ...
[ara]
default_labels = first_label,second_label
or through the ``ARA_DEFAULT_LABELS`` environment variable:
.. code-block:: bash
export ARA_DEFAULT_LABELS=first_label,second_label

View File

@ -89,6 +89,16 @@
command: "{{ ara_api_venv_path }}/bin/python -m ara.setup.plugins"
register: ara_setup_plugins
- name: Set default labels with Zuul
set_fact:
_default_labels:
- "nodepool.provider:{{ nodepool.provider }}"
- "zuul.change:{{ zuul.change }}"
- "zuul.executor:{{ zuul.executor.hostname }}"
- "zuul.pipeline:{{ zuul.pipeline }}"
- "zuul.project:{{ zuul.project.canonical_name }}"
when: zuul is defined
# These aren't in the same task (i.e, with loop) so we can tell individual test
# runs apart easily rather than keeping all the output bundled in a single task.
# TODO: Add validation for the tests
@ -101,6 +111,7 @@
ARA_SECRET_KEY: "{{ ara_api_secret_key }}"
ARA_API_CLIENT: "{{ ara_api_client | default('offline') }}"
ARA_API_SERVER: "{{ ara_api_server | default('http://127.0.0.1:8000') }}"
ARA_DEFAULT_LABELS: "{{ _default_labels | join(', ') | default('default-label') }}"
PATH: "{{ ara_api_venv_path }}/bin:/bin:/usr/bin:/usr/local/bin"
vars:
_test_root: "{{ ara_api_source }}/tests/integration"

View File

@ -63,6 +63,16 @@
changed_when: false
register: ara_setup_plugins
- name: Set default labels with Zuul
set_fact:
_default_labels:
- "nodepool.provider:{{ nodepool.provider }}"
- "zuul.change:{{ zuul.change }}"
- "zuul.executor:{{ zuul.executor.hostname }}"
- "zuul.pipeline:{{ zuul.pipeline }}"
- "zuul.project:{{ zuul.project.canonical_name }}"
when: zuul is defined
# These aren't in the same task (i.e, with loop) so we can tell individual test
# runs apart easily rather than keeping all the output bundled in a single task.
- environment:
@ -71,6 +81,7 @@
ARA_SETTINGS: "{{ ara_api_settings }}"
ARA_API_CLIENT: "{{ ara_api_client | default('offline') }}"
ARA_API_SERVER: "{{ ara_api_server | default('http://127.0.0.1:8000') }}"
ARA_DEFAULT_LABELS: "{{ _default_labels | join(', ') | default('default-label') }}"
PATH: "{{ path_with_virtualenv | default('/usr/bin:/usr/local/bin') }}"
vars:
_test_root: "{{ ara_api_source_checkout }}/tests/integration"