From 87d52e0ce02bfa5b7db8e98cfcdda4cd494b8791 Mon Sep 17 00:00:00 2001 From: Sloane Hertel <19572925+s-hertel@users.noreply.github.com> Date: Tue, 29 Mar 2022 11:03:43 -0400 Subject: [PATCH] Only require a keyring if collections with signatures will be installed (#77355) Fixes #77349 --- lib/ansible/cli/galaxy.py | 8 ++++-- .../dependency_resolution/dataclasses.py | 4 +-- .../tasks/install.yml | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index 6118efee7c7..8067dd9bb77 100755 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -667,7 +667,7 @@ class GalaxyCLI(CLI): def _get_default_collection_path(self): return C.COLLECTIONS_PATHS[0] - def _parse_requirements_file(self, requirements_file, allow_old_format=True, artifacts_manager=None): + def _parse_requirements_file(self, requirements_file, allow_old_format=True, artifacts_manager=None, validate_signature_options=True): """ Parses an Ansible requirement.yml file and returns all the roles and/or collections defined in it. There are 2 requirements file format: @@ -761,6 +761,7 @@ class GalaxyCLI(CLI): Requirement.from_requirement_dict( self._init_coll_req_dict(collection_req), artifacts_manager, + validate_signature_options, ) for collection_req in file_requirements.get('collections') or [] ] @@ -1256,15 +1257,18 @@ class GalaxyCLI(CLI): if not (requirements_file.endswith('.yaml') or requirements_file.endswith('.yml')): raise AnsibleError("Invalid role requirements file, it must end with a .yml or .yaml extension") + galaxy_args = self._raw_args + will_install_collections = self._implicit_role and '-p' not in galaxy_args and '--roles-path' not in galaxy_args + requirements = self._parse_requirements_file( requirements_file, artifacts_manager=artifacts_manager, + validate_signature_options=will_install_collections, ) role_requirements = requirements['roles'] # We can only install collections and roles at the same time if the type wasn't specified and the -p # argument was not used. If collections are present in the requirements then at least display a msg. - galaxy_args = self._raw_args if requirements['collections'] and (not self._implicit_role or '-p' in galaxy_args or '--roles-path' in galaxy_args): diff --git a/lib/ansible/galaxy/dependency_resolution/dataclasses.py b/lib/ansible/galaxy/dependency_resolution/dataclasses.py index 3caa1a5ea90..372aa7befbb 100644 --- a/lib/ansible/galaxy/dependency_resolution/dataclasses.py +++ b/lib/ansible/galaxy/dependency_resolution/dataclasses.py @@ -264,7 +264,7 @@ class _ComputedReqKindsMixin: return cls.from_requirement_dict(req, artifacts_manager) @classmethod - def from_requirement_dict(cls, collection_req, art_mgr): + def from_requirement_dict(cls, collection_req, art_mgr, validate_signature_options=True): req_name = collection_req.get('name', None) req_version = collection_req.get('version', '*') req_type = collection_req.get('type') @@ -272,7 +272,7 @@ class _ComputedReqKindsMixin: req_source = collection_req.get('source', None) req_signature_sources = collection_req.get('signatures', None) if req_signature_sources is not None: - if art_mgr.keyring is None: + if validate_signature_options and art_mgr.keyring is None: raise AnsibleError( f"Signatures were provided to verify {req_name} but no keyring was configured." ) diff --git a/test/integration/targets/ansible-galaxy-collection/tasks/install.yml b/test/integration/targets/ansible-galaxy-collection/tasks/install.yml index d345031b6af..9959dc60d47 100644 --- a/test/integration/targets/ansible-galaxy-collection/tasks/install.yml +++ b/test/integration/targets/ansible-galaxy-collection/tasks/install.yml @@ -453,6 +453,33 @@ not_mine: "file://{{ gpg_homedir }}/namespace1-name1-1.0.0-MANIFEST.json.asc" also_not_mine: "file://{{ gpg_homedir }}/namespace1-name1-1.0.9-MANIFEST.json.asc" +- name: installing only roles does not fail if keyring for collections is not provided + command: ansible-galaxy role install -r {{ galaxy_dir }}/ansible_collections/requirements.yaml + register: roles_only + +- assert: + that: + - roles_only is success + +- name: installing only roles implicitly does not fail if keyring for collections is not provided + # if -p/--roles-path are specified, only roles are installed + command: ansible-galaxy install -r {{ galaxy_dir }}/ansible_collections/requirements.yaml }} -p {{ galaxy_dir }} + register: roles_only + +- assert: + that: + - roles_only is success + +- name: installing roles and collections requires keyring if collections have signatures + command: ansible-galaxy install -r {{ galaxy_dir }}/ansible_collections/requirements.yaml }} + ignore_errors: yes + register: collections_and_roles + +- assert: + that: + - collections_and_roles is failed + - "'no keyring was configured' in collections_and_roles.stderr" + - name: install collection with mutually exclusive options command: ansible-galaxy collection install -r {{ req_file }} -s {{ test_name }} {{ cli_signature }} vars: