mirror of
https://github.com/ansible/ansible.git
synced 2026-07-29 16:35:20 +02:00
Fix using the server's validate_certs config when downloading (#86705)
* Fix using the server's validate_certs configuration when downloading collections * Fix validate_certs for verify There is no GalaxyAPI on the collection object for verify since it wasn't created via the resolver Remove unit test - would need more convoluted monkeypatching * Simplify ConcreteArtifactsManager.save_collection_source by passing 2 arguments instead of 6 * Consolidate ConcreteArtifactsManager instance attrs _galaxy_collection_cache/_galaxy_collection_origin_cache
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
bugfixes:
|
||||
- >-
|
||||
ansible-galaxy collection - Fix using the server configuration for ``validate_certs``
|
||||
when downloading collections. (https://github.com/ansible/ansible/issues/86694)
|
||||
@@ -78,8 +78,10 @@ def with_collection_artifacts_manager(wrapped_method):
|
||||
if 'artifacts_manager' in kwargs:
|
||||
return wrapped_method(*args, **kwargs)
|
||||
|
||||
# FIXME: use validate_certs context from Galaxy servers when downloading collections
|
||||
# .get used here for when this is used in a non-CLI context
|
||||
# configures validate_certs for type 'url' only
|
||||
# type 'galaxy' inherits and overrides resolved_validate_certs
|
||||
# type 'git' recalculates resolved_validate_certs
|
||||
# NOTE: .get used here for when this is used in a non-CLI context
|
||||
artifacts_manager_kwargs = {'validate_certs': context.CLIARGS.get('resolved_validate_certs', True)}
|
||||
|
||||
keyring = context.CLIARGS.get('keyring', None)
|
||||
|
||||
@@ -31,7 +31,7 @@ if t.TYPE_CHECKING:
|
||||
from ansible import context
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.galaxy import get_collections_galaxy_meta_info
|
||||
from ansible.galaxy.api import should_retry_error
|
||||
from ansible.galaxy.api import should_retry_error, CollectionVersionMetadata, GalaxyAPI
|
||||
from ansible.galaxy.dependency_resolution.dataclasses import _GALAXY_YAML
|
||||
from ansible.galaxy.user_agent import user_agent
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
@@ -71,8 +71,7 @@ class ConcreteArtifactsManager:
|
||||
self._artifact_cache = {} # type: dict[bytes, bytes]
|
||||
self._galaxy_artifact_cache = {} # type: dict[Candidate | Requirement, bytes]
|
||||
self._artifact_meta_cache = {} # type: dict[bytes, dict[str, str | list[str] | dict[str, str] | None | t.Type[Sentinel]]]
|
||||
self._galaxy_collection_cache = {} # type: dict[Candidate | Requirement, tuple[str, str, GalaxyToken]]
|
||||
self._galaxy_collection_origin_cache = {} # type: dict[Candidate, tuple[str, list[dict[str, str]]]]
|
||||
self._galaxy_collection_cache: dict[Candidate, tuple[CollectionVersionMetadata, GalaxyAPI]] = {}
|
||||
self._b_working_directory = b_working_directory # type: bytes
|
||||
self._supplemental_signature_cache = {} # type: dict[str, str]
|
||||
self._keyring = keyring # type: str
|
||||
@@ -107,15 +106,12 @@ class ConcreteArtifactsManager:
|
||||
|
||||
def get_galaxy_artifact_source_info(self, collection):
|
||||
# type: (Candidate) -> dict[str, t.Union[str, list[dict[str, str]]]]
|
||||
server = collection.src.api_server
|
||||
|
||||
try:
|
||||
download_url = self._galaxy_collection_cache[collection][0]
|
||||
signatures_url, signatures = self._galaxy_collection_origin_cache[collection]
|
||||
metadata, server = self._galaxy_collection_cache[collection]
|
||||
except KeyError as key_err:
|
||||
raise RuntimeError(
|
||||
'The is no known source for {coll!s}'.
|
||||
format(coll=collection),
|
||||
f"There is no known source for {collection!s}"
|
||||
) from key_err
|
||||
|
||||
return {
|
||||
@@ -123,14 +119,13 @@ class ConcreteArtifactsManager:
|
||||
"namespace": collection.namespace,
|
||||
"name": collection.name,
|
||||
"version": collection.ver,
|
||||
"server": server,
|
||||
"version_url": signatures_url,
|
||||
"download_url": download_url,
|
||||
"signatures": signatures,
|
||||
"server": server.api_server,
|
||||
"version_url": metadata.signatures_url,
|
||||
"download_url": metadata.download_url,
|
||||
"signatures": metadata.signatures,
|
||||
}
|
||||
|
||||
def get_galaxy_artifact_path(self, collection):
|
||||
# type: (t.Union[Candidate, Requirement]) -> bytes
|
||||
def get_galaxy_artifact_path(self, collection: Candidate) -> bytes:
|
||||
"""Given a Galaxy-stored collection, return a cached path.
|
||||
|
||||
If it's not yet on disk, this method downloads the artifact first.
|
||||
@@ -141,11 +136,10 @@ class ConcreteArtifactsManager:
|
||||
pass
|
||||
|
||||
try:
|
||||
url, sha256_hash, token = self._galaxy_collection_cache[collection]
|
||||
metadata, api = self._galaxy_collection_cache[collection]
|
||||
except KeyError as key_err:
|
||||
raise RuntimeError(
|
||||
'There is no known source for {coll!s}'.
|
||||
format(coll=collection),
|
||||
f'There is no known source for {collection!s}'
|
||||
) from key_err
|
||||
|
||||
display.vvvv(
|
||||
@@ -155,39 +149,27 @@ class ConcreteArtifactsManager:
|
||||
|
||||
try:
|
||||
b_artifact_path = _download_file(
|
||||
url,
|
||||
metadata.download_url,
|
||||
self._b_working_directory,
|
||||
expected_hash=sha256_hash,
|
||||
validate_certs=self._validate_certs,
|
||||
token=token,
|
||||
expected_hash=metadata.artifact_sha256,
|
||||
validate_certs=api.validate_certs,
|
||||
token=api.token,
|
||||
) # type: bytes
|
||||
except URLError as err:
|
||||
raise AnsibleError(
|
||||
'Failed to download collection tar '
|
||||
"from '{coll_src!s}': {download_err!s}".
|
||||
format(
|
||||
coll_src=to_native(collection.src),
|
||||
download_err=to_native(err),
|
||||
),
|
||||
f"from '{api!s}': {err!s}"
|
||||
) from err
|
||||
except Exception as err:
|
||||
raise AnsibleError(
|
||||
'Failed to download collection tar '
|
||||
"from '{coll_src!s}' due to the following unforeseen error: "
|
||||
'{download_err!s}'.
|
||||
format(
|
||||
coll_src=to_native(collection.src),
|
||||
download_err=to_native(err),
|
||||
),
|
||||
f"from '{api!s}' due to the following unforeseen error: "
|
||||
f'{err!s}'
|
||||
) from err
|
||||
else:
|
||||
display.vvv(
|
||||
"Collection '{coll!s}' obtained from "
|
||||
'server {server!s} {url!s}'.format(
|
||||
coll=collection, server=collection.src or 'Galaxy',
|
||||
url=collection.src.api_server if collection.src is not None
|
||||
else '',
|
||||
)
|
||||
f"Collection '{collection!s}' obtained from server {api!s} "
|
||||
f"{api.api_server!s}"
|
||||
)
|
||||
|
||||
self._galaxy_artifact_cache[collection] = b_artifact_path
|
||||
@@ -368,15 +350,13 @@ class ConcreteArtifactsManager:
|
||||
# NOTE: Using None as a sentinel since it's not a valid value otherwise.
|
||||
return runtime.get("requires_ansible")
|
||||
|
||||
def save_collection_source(self, collection, url, sha256_hash, token, signatures_url, signatures):
|
||||
# type: (Candidate, str, str, GalaxyToken, str, list[dict[str, str]]) -> None
|
||||
"""Store collection URL, SHA256 hash and Galaxy API token.
|
||||
def save_collection_source(self, collection: Candidate, metadata: CollectionVersionMetadata, api: GalaxyAPI) -> None:
|
||||
"""Store collection version metadata and origin.
|
||||
|
||||
This is a hook that is supposed to be called before attempting to
|
||||
download Galaxy-based collections with ``get_galaxy_artifact_path()``.
|
||||
"""
|
||||
self._galaxy_collection_cache[collection] = url, sha256_hash, token
|
||||
self._galaxy_collection_origin_cache[collection] = signatures_url, signatures
|
||||
self._galaxy_collection_cache[collection] = (metadata, api)
|
||||
|
||||
@classmethod
|
||||
@contextmanager
|
||||
|
||||
@@ -146,11 +146,8 @@ class MultiGalaxyAPIProxy:
|
||||
else:
|
||||
self._concrete_art_mgr.save_collection_source(
|
||||
collection_candidate,
|
||||
version_metadata.download_url,
|
||||
version_metadata.artifact_sha256,
|
||||
api.token,
|
||||
version_metadata.signatures_url,
|
||||
version_metadata.signatures,
|
||||
version_metadata,
|
||||
api
|
||||
)
|
||||
return version_metadata
|
||||
|
||||
|
||||
Reference in New Issue
Block a user