diff --git a/changelogs/fragments/require-fqcn-redirects.yml b/changelogs/fragments/require-fqcn-redirects.yml new file mode 100644 index 00000000000..9297679dae2 --- /dev/null +++ b/changelogs/fragments/require-fqcn-redirects.yml @@ -0,0 +1,2 @@ +bugfixes: + - Error for collection redirects that do not use fully qualified collection names, as the redirect would be determined by the ``collections`` keyword. diff --git a/lib/ansible/plugins/loader.py b/lib/ansible/plugins/loader.py index 2e343d0b2e6..f61e42a0a88 100644 --- a/lib/ansible/plugins/loader.py +++ b/lib/ansible/plugins/loader.py @@ -502,6 +502,13 @@ class PluginLoader: redirect = routing_metadata.get('redirect', None) if redirect: + # Prevent mystery redirects that would be determined by the collections keyword + if not AnsibleCollectionRef.is_valid_fqcr(redirect): + raise AnsibleError( + f"Collection {acr.collection} contains invalid redirect for {fq_name}: {redirect}. " + "Redirects must use fully qualified collection names." + ) + # FIXME: remove once this is covered in debug or whatever display.vv("redirecting (type: {0}) {1} to {2}".format(plugin_type, fq_name, redirect)) # The name doing the redirection is added at the beginning of _resolve_plugin_step, @@ -1171,6 +1178,12 @@ class Jinja2Loader(PluginLoader): # check redirects redirect = routing_entry.get('redirect', None) if redirect: + if not AnsibleCollectionRef.is_valid_fqcr(redirect): + raise AnsibleError( + f"Collection {acr.collection} contains invalid redirect for {acr.collection}.{acr.resource}: {redirect}. " + "Redirects must use fully qualified collection names." + ) + next_key, leaf_key = get_fqcr_and_name(redirect, collection=acr.collection) display.vvv('redirecting (type: {0}) {1}.{2} to {3}'.format(self.type, acr.collection, acr.resource, next_key)) key = next_key diff --git a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testredirect/meta/runtime.yml b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testredirect/meta/runtime.yml index 2dcf456e17f..bb4bd6d580f 100644 --- a/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testredirect/meta/runtime.yml +++ b/test/integration/targets/collections/collection_root_user/ansible_collections/testns/testredirect/meta/runtime.yml @@ -8,7 +8,7 @@ plugin_routing: deprecation: warning_text: deprecation1 redirect_filter1: - redirect: redirect_filter2 + redirect: testns.testredirect.redirect_filter2 deprecation: warning_text: deprecation2 redirect_filter2: @@ -16,6 +16,8 @@ plugin_routing: deprecation: warning_text: deprecation3 dead_end: - redirect: bad_redirect + redirect: testns.testredirect.bad_redirect recursive_redirect: - redirect: recursive_redirect + redirect: testns.testredirect.recursive_redirect + invalid_redirect: + redirect: contextual_redirect diff --git a/test/integration/targets/collections/test_collection_meta.yml b/test/integration/targets/collections/test_collection_meta.yml index db1b1bbe2ab..e4c4d30d384 100644 --- a/test/integration/targets/collections/test_collection_meta.yml +++ b/test/integration/targets/collections/test_collection_meta.yml @@ -40,6 +40,16 @@ that: - redirect_failure is failed - '"recursive collection redirect found for ''testns.testredirect.recursive_redirect''" in redirect_failure.msg' + # invalid filter redirect + - debug: msg="{{ 'data' | testns.testredirect.invalid_redirect }}" + ignore_errors: yes + register: redirect_failure + - assert: + that: + - redirect_failure is failed + - error in redirect_failure.msg + vars: + error: "Collection testns.testredirect contains invalid redirect for testns.testredirect.invalid_redirect: contextual_redirect" # legacy filter should mask redirected - assert: that: ('' | formerly_core_masked_filter) == 'hello from overridden formerly_core_masked_filter'