From 0076adb1a6f89a6c42e0b6a0c1eec2cb4bb0f1d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Piotrowski?= Date: Thu, 7 Dec 2017 14:09:55 +0100 Subject: [PATCH] plugins: add auto_tags plugin --- .gitignore | 1 + ansible.cfg | 1 + plugins/callback/auto_tags.py | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 plugins/callback/auto_tags.py diff --git a/.gitignore b/.gitignore index a8b42eb6..7d07d7f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.retry +*.pyc diff --git a/ansible.cfg b/ansible.cfg index 83a149e0..619aeb7b 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -7,6 +7,7 @@ nocows = 1 roles_path = roles vault_password_file = misc/get-vault-pass.sh retry_files_enabled = False +callback_plugins = plugins/callback callback_whitelist = profile_tasks [ssh_connection] diff --git a/plugins/callback/auto_tags.py b/plugins/callback/auto_tags.py new file mode 100644 index 00000000..88652092 --- /dev/null +++ b/plugins/callback/auto_tags.py @@ -0,0 +1,50 @@ +""" +Source: https://gist.github.com/rkrzr/f5387167fa7b4869e2dca8b713879562 + +This module implements an Ansible plugin that is triggered at the start of a playbook. + +The plugin dynamically generates a tag for each role. Each tag has the same name as its role. +The advantage of this is that it saves you some boilerplate, because you don't have to wrap +all tasks of a role in an additional block and assign a tag to that. +Additionally, it works automatically when you add new roles to your playbook. + +Usage is exactly the same as without this plugin: + +ansible-playbook --tags=some_tag provision.yml + +Here, the "some_tag" tag was generated dynamically (assuming there is a "some_tag" role). + +Installation: +1. Place this file in `plugins/callbacks/auto_tags.py` (relative to your playbook root) +2. Add the following two lines to your `ansible.cfg` file: + +callback_plugins = plugins/callbacks +callback_whitelist = auto_tags +""" +from __future__ import print_function +from ansible.plugins.callback import CallbackBase + + +class CallbackModule(CallbackBase): + """ + Ansible supports several types of plugins. We are using the *callback* type here, since + it seemed the best choice for our use case, because it allows you to hook into the start + of a playbook. + """ + def v2_playbook_on_start(self, playbook): + """ + Dynamically add a tag of the same name to each role. + Note: Plays, roles, task_blocks and tasks can have tags. + """ + plays = playbook.get_plays() + + # Note: Although identical roles are shared between plays we cannot deduplicate them, + # since Ansible treats them as different objects internally + roles = [role for play in plays for role in play.get_roles()] + + # Note: Tags for roles are set dynamically in `_load_role_data` instead of in __init__ + # I don't know why they do that. + for role in roles: + role_name = role._role_name + if role_name not in role.tags: + role.tags += [role_name]