Add a named parameter to the filter to_uuid (#64057)

Let the caller choose a namespace for `to_uuid` and document the
behaviour of both the default case, and the new explicit case.

This PR does not change the existing behaviour of the `to_uuid` UUIDv5
filter.
This commit is contained in:
Pierre Prinetti 2019-11-01 18:11:34 +01:00 committed by Sam Doran
parent 7b7f15cb3a
commit 2444fae208
4 changed files with 62 additions and 4 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- to_uuid - add a named parameter to let the user optionally set a custom namespace

View file

@ -1279,9 +1279,17 @@ As of version 2.6, you can define the type of encoding to use, the default is ``
.. versionadded:: 2.6
To create a UUID from a string (new in version 1.9)::
To create a namespaced UUIDv5::
{{ hostname | to_uuid }}
{{ string | to_uuid(namespace='11111111-2222-3333-4444-555555555555') }}
.. versionadded:: 2.10
To create a namespaced UUIDv5 using the default Ansible namespace '361E6D51-FAEC-444A-9079-341386DA8E2E'::
{{ string | to_uuid }}
.. versionadded:: 1.9
To cast values as certain types, such as when you input a string as "True" from a vars_prompt and the system
doesn't know it is a boolean value::

View file

@ -276,8 +276,15 @@ def get_encrypted_password(password, hashtype='sha512', salt=None, salt_size=Non
reraise(AnsibleFilterError, AnsibleFilterError(to_native(e), orig_exc=e), sys.exc_info()[2])
def to_uuid(string):
return str(uuid.uuid5(UUID_NAMESPACE_ANSIBLE, str(string)))
def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
uuid_namespace = namespace
if not isinstance(uuid_namespace, uuid.UUID):
try:
uuid_namespace = uuid.UUID(namespace)
except (AttributeError, ValueError) as e:
raise AnsibleFilterError("Invalid value '%s' for 'namespace': %s" % (to_native(namespace), to_native(e)))
# uuid.uuid5() requires bytes on Python 2 and bytes or text or Python 3
return to_text(uuid.uuid5(uuid_namespace, to_native(string, errors='surrogate_or_strict')))
def mandatory(a, msg=None):

View file

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
from ansible.module_utils._text import to_native
from ansible.plugins.filter.core import to_uuid
from ansible.errors import AnsibleFilterError
UUID_DEFAULT_NAMESPACE_TEST_CASES = (
('example.com', 'ae780c3a-a3ab-53c2-bfb4-098da300b3fe'),
('test.example', '8e437a35-c7c5-50ea-867c-5c254848dbc2'),
('café.example', '8a99d6b1-fb8f-5f78-af86-879768589f56'),
)
UUID_TEST_CASES = (
('361E6D51-FAEC-444A-9079-341386DA8E2E', 'example.com', 'ae780c3a-a3ab-53c2-bfb4-098da300b3fe'),
('361E6D51-FAEC-444A-9079-341386DA8E2E', 'test.example', '8e437a35-c7c5-50ea-867c-5c254848dbc2'),
('11111111-2222-3333-4444-555555555555', 'example.com', 'e776faa5-5299-55dc-9057-7a00e6be2364'),
)
@pytest.mark.parametrize('value, expected', UUID_DEFAULT_NAMESPACE_TEST_CASES)
def test_to_uuid_default_namespace(value, expected):
assert expected == to_uuid(value)
@pytest.mark.parametrize('namespace, value, expected', UUID_TEST_CASES)
def test_to_uuid(namespace, value, expected):
assert expected == to_uuid(value, namespace=namespace)
def test_to_uuid_invalid_namespace():
with pytest.raises(AnsibleFilterError) as e:
to_uuid('example.com', namespace='11111111-2222-3333-4444-555555555')
assert 'Invalid value' in to_native(e.value)