Allow tags to be templated from a variable (#49833)

* Allow tags to be templated from a variable. Fixes #49825

* Restore _load_tags to ensure we do csv tag splitting

* Add tests for csv tags and templated tags

* evaluate_tags doesn't need to accept strings, because _load_tags handles this
This commit is contained in:
Matt Martz 2018-12-17 15:40:26 -06:00 committed by GitHub
parent a0d71e7735
commit 7eb1ab45a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 17 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- tags - allow tags to be specified by a variable (https://github.com/ansible/ansible/issues/49825)

View file

@ -19,8 +19,6 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import itertools
from ansible.errors import AnsibleError
from ansible.module_utils.six import string_types
from ansible.playbook.attribute import FieldAttribute
@ -32,9 +30,6 @@ class Taggable:
untagged = frozenset(['untagged'])
_tags = FieldAttribute(isa='list', default=list, listof=(string_types, int), extend=True)
def __init__(self):
super(Taggable, self).__init__()
def _load_tags(self, attr, ds):
if isinstance(ds, list):
return ds
@ -54,13 +49,14 @@ class Taggable:
templar = Templar(loader=self._loader, variables=all_vars)
tags = templar.template(self.tags)
if not isinstance(tags, list):
if tags.find(',') != -1:
tags = set(tags.split(','))
_temp_tags = set()
for tag in tags:
if isinstance(tag, list):
_temp_tags.update(tag)
else:
tags = set([tags])
else:
tags = set([i for i, _ in itertools.groupby(tags)])
_temp_tags.add(tag)
tags = _temp_tags
self.tags = list(tags)
else:
# this makes isdisjoint work for untagged
tags = self.untagged

View file

@ -14,7 +14,7 @@ export LC_ALL=en_US.UTF-8
# Run everything by default
[ "$("${COMMAND[@]}" | grep -F Task_with | xargs)" = \
"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: []" ]
"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: [] Task_with_csv_tags TAGS: [tag1, tag2] Task_with_templated_tags TAGS: [tag3]" ]
# Run the exact tags, and always
[ "$("${COMMAND[@]}" --tags tag | grep -F Task_with | xargs)" = \
@ -22,11 +22,11 @@ export LC_ALL=en_US.UTF-8
# Skip one tag
[ "$("${COMMAND[@]}" --skip-tags tag | grep -F Task_with | xargs)" = \
"Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: []" ]
"Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: [] Task_with_csv_tags TAGS: [tag1, tag2] Task_with_templated_tags TAGS: [tag3]" ]
# Skip a unicode tag
[ "$("${COMMAND[@]}" --skip-tags 'くらとみ' | grep -F Task_with | xargs)" = \
"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: []" ]
"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: [] Task_with_csv_tags TAGS: [tag1, tag2] Task_with_templated_tags TAGS: [tag3]" ]
# Run just a unicode tag and always
[ "$("${COMMAND[@]}" --tags 'くらとみ' | grep -F Task_with | xargs)" = \
@ -39,3 +39,11 @@ export LC_ALL=en_US.UTF-8
# Run tag with never
[ "$("${COMMAND[@]}" --tags donever | grep -F Task_with | xargs)" = \
"Task_with_always_tag TAGS: [always] Task_with_never_tag TAGS: [donever, never]" ]
# Run csv tags
[ "$("${COMMAND[@]}" --tags tag1 | grep -F Task_with | xargs)" = \
"Task_with_always_tag TAGS: [always] Task_with_csv_tags TAGS: [tag1, tag2]" ]
# Run templated tags
[ "$("${COMMAND[@]}" --tags tag3 | grep -F Task_with | xargs)" = \
"Task_with_always_tag TAGS: [always] Task_with_templated_tags TAGS: [tag3]" ]

View file

@ -3,6 +3,9 @@
hosts: localhost
gather_facts: False
connection: local
vars:
the_tags:
- tag3
tasks:
- name: Task_with_tag
debug: msg=
@ -23,3 +26,9 @@
- name: Task_with_never_tag
debug: msg=NEVER
tags: ['never', 'donever']
- name: Task_with_csv_tags
debug: msg=csv
tags: tag1,tag2
- name: Task_with_templated_tags
debug: msg=templated
tags: "{{ the_tags }}"

View file

@ -98,8 +98,5 @@ class TestTaggable(unittest.TestCase):
def test_evaluate_tags_accepts_lists(self):
self.assert_evaluate_equal(True, ['tag1', 'tag2'], ['tag2'], [])
def test_evaluate_tags_accepts_strings(self):
self.assert_evaluate_equal(True, 'tag1,tag2', ['tag2'], [])
def test_evaluate_tags_with_repeated_tags(self):
self.assert_evaluate_equal(False, ['tag', 'tag'], [], ['tag'])