mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-07 22:03:01 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
520e7c6278 | ||
|
|
1da1fdc3b0 | ||
|
|
c5135496c8 | ||
|
|
05864d366c | ||
|
|
43ba69e495 | ||
|
|
62b4535465 | ||
|
|
c0072d29f5 | ||
|
|
1bfee3c23b | ||
|
|
7f7704ece8 | ||
|
|
7cc52204a8 | ||
|
|
8e76660e80 | ||
|
|
114c98928d | ||
|
|
ba5c551a29 | ||
|
|
09c45551fe | ||
|
|
75413d0b08 | ||
|
|
dfff658f34 | ||
|
|
1dd771c0c4 | ||
|
|
bc16487882 | ||
|
|
ec2d662320 | ||
|
|
690561ecd9 | ||
|
|
1aa313ab96 | ||
|
|
0636123f56 | ||
|
|
05c9e09d20 | ||
|
|
f219cac94c | ||
|
|
b4303b3a32 | ||
|
|
84f0c7f163 |
@@ -24,5 +24,6 @@ skip_list:
|
|||||||
- risky-file-permissions
|
- risky-file-permissions
|
||||||
- risky-shell-pipe
|
- risky-shell-pipe
|
||||||
- var-naming[no-reserved]
|
- var-naming[no-reserved]
|
||||||
|
- var-naming[no-role-prefix]
|
||||||
- var-naming[pattern]
|
- var-naming[pattern]
|
||||||
- var-naming[read-only]
|
- var-naming[read-only]
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ variables:
|
|||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: default
|
- container: default
|
||||||
image: quay.io/ansible/azure-pipelines-test-container:6.0.0
|
image: quay.io/ansible/azure-pipelines-test-container:7.0.0
|
||||||
|
|
||||||
pool: Standard
|
pool: Standard
|
||||||
|
|
||||||
@@ -103,12 +103,12 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: devel/linux/{0}
|
testFormat: devel/linux/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: Fedora 41
|
- name: Fedora 42
|
||||||
test: fedora41
|
test: fedora42
|
||||||
- name: Ubuntu 24.04
|
- name: Ubuntu 24.04
|
||||||
test: ubuntu2404
|
test: ubuntu2404
|
||||||
- name: Alpine 3.21
|
- name: Alpine 3.22
|
||||||
test: alpine321
|
test: alpine322
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
@@ -122,6 +122,8 @@ stages:
|
|||||||
targets:
|
targets:
|
||||||
- name: Fedora 41
|
- name: Fedora 41
|
||||||
test: fedora41
|
test: fedora41
|
||||||
|
- name: Alpine 3.21
|
||||||
|
test: alpine321
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
@@ -169,9 +171,11 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: devel/linux-community/{0}
|
testFormat: devel/linux-community/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: Debian Bookworm
|
- name: Debian 13 Trixie
|
||||||
|
test: debian-13-trixie/3.13
|
||||||
|
- name: Debian 12 Bookworm
|
||||||
test: debian-bookworm/3.11
|
test: debian-bookworm/3.11
|
||||||
- name: Debian Bullseye
|
- name: Debian 11 Bullseye
|
||||||
test: debian-bullseye/3.9
|
test: debian-bullseye/3.9
|
||||||
- name: ArchLinux
|
- name: ArchLinux
|
||||||
test: archlinux/3.13
|
test: archlinux/3.13
|
||||||
@@ -188,10 +192,10 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: devel/{0}
|
testFormat: devel/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: Alpine 3.21
|
- name: Alpine 3.22
|
||||||
test: alpine/3.21
|
test: alpine/3.22
|
||||||
- name: Fedora 41
|
- name: Fedora 42
|
||||||
test: fedora/41
|
test: fedora/42
|
||||||
- name: Ubuntu 22.04
|
- name: Ubuntu 22.04
|
||||||
test: ubuntu/22.04
|
test: ubuntu/22.04
|
||||||
- name: Ubuntu 24.04
|
- name: Ubuntu 24.04
|
||||||
@@ -210,10 +214,10 @@ stages:
|
|||||||
test: macos/15.3
|
test: macos/15.3
|
||||||
- name: RHEL 10.0
|
- name: RHEL 10.0
|
||||||
test: rhel/10.0
|
test: rhel/10.0
|
||||||
- name: RHEL 9.5
|
- name: RHEL 9.6
|
||||||
test: rhel/9.5
|
test: rhel/9.6
|
||||||
- name: FreeBSD 14.2
|
- name: FreeBSD 14.3
|
||||||
test: freebsd/14.2
|
test: freebsd/14.3
|
||||||
- name: FreeBSD 13.5
|
- name: FreeBSD 13.5
|
||||||
test: freebsd/13.5
|
test: freebsd/13.5
|
||||||
groups:
|
groups:
|
||||||
@@ -227,8 +231,12 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: 2.19/{0}
|
testFormat: 2.19/{0}
|
||||||
targets:
|
targets:
|
||||||
|
- name: RHEL 9.5
|
||||||
|
test: rhel/9.5
|
||||||
- name: RHEL 10.0
|
- name: RHEL 10.0
|
||||||
test: rhel/10.0
|
test: rhel/10.0
|
||||||
|
- name: FreeBSD 14.2
|
||||||
|
test: freebsd/14.2
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
@@ -259,8 +267,8 @@ stages:
|
|||||||
targets:
|
targets:
|
||||||
- name: RHEL 9.3
|
- name: RHEL 9.3
|
||||||
test: rhel/9.3
|
test: rhel/9.3
|
||||||
- name: FreeBSD 13.3
|
- name: FreeBSD 13.5
|
||||||
test: freebsd/13.3
|
test: freebsd/13.5
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
@@ -274,11 +282,11 @@ stages:
|
|||||||
nameFormat: Python {0}
|
nameFormat: Python {0}
|
||||||
testFormat: devel/generic/{0}
|
testFormat: devel/generic/{0}
|
||||||
targets:
|
targets:
|
||||||
- test: "3.8"
|
|
||||||
- test: "3.9"
|
- test: "3.9"
|
||||||
- test: "3.10"
|
- test: "3.10"
|
||||||
- test: "3.11"
|
- test: "3.11"
|
||||||
- test: "3.13"
|
- test: "3.13"
|
||||||
|
- test: "3.14"
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
|
|||||||
1
.github/workflows/docs-pr.yml
vendored
1
.github/workflows/docs-pr.yml
vendored
@@ -21,6 +21,7 @@ jobs:
|
|||||||
name: Build Ansible Docs
|
name: Build Ansible Docs
|
||||||
uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@main
|
uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@main
|
||||||
with:
|
with:
|
||||||
|
ansible-ref: devel
|
||||||
collection-name: community.crypto
|
collection-name: community.crypto
|
||||||
init-lenient: false
|
init-lenient: false
|
||||||
init-fail-on-error: true
|
init-fail-on-error: true
|
||||||
|
|||||||
1
.github/workflows/docs-push.yml
vendored
1
.github/workflows/docs-push.yml
vendored
@@ -27,6 +27,7 @@ jobs:
|
|||||||
name: Build Ansible Docs
|
name: Build Ansible Docs
|
||||||
uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@main
|
uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@main
|
||||||
with:
|
with:
|
||||||
|
ansible-ref: devel
|
||||||
collection-name: community.crypto
|
collection-name: community.crypto
|
||||||
init-lenient: false
|
init-lenient: false
|
||||||
init-fail-on-error: true
|
init-fail-on-error: true
|
||||||
|
|||||||
172
.github/workflows/ee.yml
vendored
172
.github/workflows/ee.yml
vendored
@@ -1,172 +0,0 @@
|
|||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: execution environment
|
|
||||||
'on':
|
|
||||||
# Run CI against all pushes (direct commits, also merged PRs), Pull Requests
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
pull_request:
|
|
||||||
# Run CI once per day (at 09:00 UTC)
|
|
||||||
# This ensures that even if there haven't been commits that we are still testing against latest version of ansible-builder
|
|
||||||
schedule:
|
|
||||||
- cron: '0 9 * * *'
|
|
||||||
|
|
||||||
env:
|
|
||||||
NAMESPACE: community
|
|
||||||
COLLECTION_NAME: crypto
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build and test EE (${{ matrix.name }})
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
name:
|
|
||||||
- ''
|
|
||||||
ansible_core:
|
|
||||||
- ''
|
|
||||||
ansible_runner:
|
|
||||||
- ''
|
|
||||||
base_image:
|
|
||||||
- ''
|
|
||||||
pre_base:
|
|
||||||
- ''
|
|
||||||
extra_vars:
|
|
||||||
- ''
|
|
||||||
other_deps:
|
|
||||||
- ''
|
|
||||||
exclude:
|
|
||||||
- ansible_core: ''
|
|
||||||
include:
|
|
||||||
- name: ansible-core devel @ RHEL UBI 9
|
|
||||||
ansible_core: https://github.com/ansible/ansible/archive/devel.tar.gz
|
|
||||||
ansible_runner: ansible-runner
|
|
||||||
other_deps: |2
|
|
||||||
python_interpreter:
|
|
||||||
package_system: python3.12 python3.12-pip python3.12-wheel python3.12-cryptography
|
|
||||||
python_path: "/usr/bin/python3.12"
|
|
||||||
base_image: docker.io/redhat/ubi9:latest
|
|
||||||
pre_base: '"#"'
|
|
||||||
- name: ansible-core 2.17 @ Rocky Linux 9
|
|
||||||
ansible_core: https://github.com/ansible/ansible/archive/stable-2.17.tar.gz
|
|
||||||
ansible_runner: ansible-runner
|
|
||||||
other_deps: |2
|
|
||||||
python_interpreter:
|
|
||||||
package_system: python3.11 python3.11-pip python3.11-wheel python3.11-cryptography
|
|
||||||
python_path: "/usr/bin/python3.11"
|
|
||||||
base_image: quay.io/rockylinux/rockylinux:9
|
|
||||||
pre_base: RUN dnf install -y epel-release
|
|
||||||
- name: ansible-core 2.18 @ CentOS Stream 9
|
|
||||||
ansible_core: https://github.com/ansible/ansible/archive/stable-2.18.tar.gz
|
|
||||||
ansible_runner: ansible-runner
|
|
||||||
other_deps: |2
|
|
||||||
python_interpreter:
|
|
||||||
package_system: python3.11 python3.11-pip python3.11-wheel python3.11-cryptography
|
|
||||||
python_path: "/usr/bin/python3.11"
|
|
||||||
base_image: quay.io/centos/centos:stream9
|
|
||||||
pre_base: '"#"'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
path: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.11'
|
|
||||||
|
|
||||||
- name: Install ansible-builder and ansible-navigator
|
|
||||||
run: pip install ansible-builder ansible-navigator
|
|
||||||
|
|
||||||
- name: Verify requirements
|
|
||||||
run: ansible-builder introspect --sanitize .
|
|
||||||
|
|
||||||
- name: Make sure galaxy.yml has version entry
|
|
||||||
run: >-
|
|
||||||
python -c
|
|
||||||
'import yaml ;
|
|
||||||
f = open("galaxy.yml", "rb") ;
|
|
||||||
data = yaml.safe_load(f) ;
|
|
||||||
f.close() ;
|
|
||||||
data["version"] = data.get("version") or "0.0.1" ;
|
|
||||||
f = open("galaxy.yml", "wb") ;
|
|
||||||
f.write(yaml.dump(data).encode("utf-8")) ;
|
|
||||||
f.close() ;
|
|
||||||
'
|
|
||||||
working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}
|
|
||||||
|
|
||||||
- name: Build collection
|
|
||||||
run: |
|
|
||||||
ansible-galaxy collection build --output-path ../../../
|
|
||||||
working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}
|
|
||||||
|
|
||||||
- name: Create files for building execution environment
|
|
||||||
run: |
|
|
||||||
COLLECTION_FILENAME="$(ls "${NAMESPACE}-${COLLECTION_NAME}"-*.tar.gz)"
|
|
||||||
|
|
||||||
# EE config
|
|
||||||
cat > execution-environment.yml <<EOF
|
|
||||||
---
|
|
||||||
version: 3
|
|
||||||
dependencies:
|
|
||||||
ansible_core:
|
|
||||||
package_pip: ${{ matrix.ansible_core }}
|
|
||||||
ansible_runner:
|
|
||||||
package_pip: ${{ matrix.ansible_runner }}
|
|
||||||
galaxy: requirements.yml
|
|
||||||
${{ matrix.other_deps }}
|
|
||||||
|
|
||||||
images:
|
|
||||||
base_image:
|
|
||||||
name: ${{ matrix.base_image }}
|
|
||||||
|
|
||||||
additional_build_files:
|
|
||||||
- src: ${COLLECTION_FILENAME}
|
|
||||||
dest: src
|
|
||||||
|
|
||||||
additional_build_steps:
|
|
||||||
prepend_base:
|
|
||||||
- ${{ matrix.pre_base }}
|
|
||||||
EOF
|
|
||||||
echo "::group::execution-environment.yml"
|
|
||||||
cat execution-environment.yml
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
# Requirements
|
|
||||||
cat > requirements.yml <<EOF
|
|
||||||
---
|
|
||||||
collections:
|
|
||||||
- name: src/${COLLECTION_FILENAME}
|
|
||||||
type: file
|
|
||||||
EOF
|
|
||||||
echo "::group::requirements.yml"
|
|
||||||
cat requirements.yml
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Build image based on ${{ matrix.base_image }}
|
|
||||||
run: |
|
|
||||||
ansible-builder build --verbosity 3 --tag test-ee:latest --container-runtime podman
|
|
||||||
|
|
||||||
- name: Show images
|
|
||||||
run: podman image ls
|
|
||||||
|
|
||||||
- name: Run basic tests
|
|
||||||
run: >
|
|
||||||
ansible-navigator run
|
|
||||||
--mode stdout
|
|
||||||
--container-engine podman
|
|
||||||
--pull-policy never
|
|
||||||
--set-environment-variable ANSIBLE_PRIVATE_ROLE_VARS=true
|
|
||||||
--execution-environment-image test-ee:latest
|
|
||||||
-v
|
|
||||||
all.yml
|
|
||||||
${{ matrix.extra_vars }}
|
|
||||||
working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}/tests/ee
|
|
||||||
5
.github/workflows/nox.yml
vendored
5
.github/workflows/nox.yml
vendored
@@ -21,8 +21,11 @@ jobs:
|
|||||||
name: "Run extra sanity tests"
|
name: "Run extra sanity tests"
|
||||||
steps:
|
steps:
|
||||||
- name: Check out collection
|
- name: Check out collection
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Run nox
|
- name: Run nox
|
||||||
uses: ansible-community/antsibull-nox@main
|
uses: ansible-community/antsibull-nox@main
|
||||||
|
|
||||||
|
ansible-test:
|
||||||
|
uses: ansible-community/antsibull-nox/.github/workflows/reusable-nox-matrix.yml@main
|
||||||
|
|||||||
569
CHANGELOG.md
569
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,46 @@ Community Crypto Release Notes
|
|||||||
|
|
||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
|
v3.0.4
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Maintenance release.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Avoid deprecated functionality in ansible-core 2.20 (https://github.com/ansible-collections/community.crypto/pull/953).
|
||||||
|
|
||||||
|
v3.0.3
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Bugfix release.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- acme_* modules - also retry on HTTP responses 502 Bad Gateway and 504 Gateway Timeout. The latter is needed for ZeroSSL, which seems to have a lot of 504s (https://github.com/ansible-collections/community.crypto/issues/945, https://github.com/ansible-collections/community.crypto/pull/947).
|
||||||
|
- acme_* modules - increase the maximum amount of retries from 10 to 20 to accomodate ZeroSSL's buggy implementation (https://github.com/ansible-collections/community.crypto/pull/949).
|
||||||
|
|
||||||
|
v3.0.2
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Bugfix release.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Improve error message when loading a private key fails due to correct private key files or wrong passwords. Also include the original cryptography error since it likely contains more helpful information (https://github.com/ansible-collections/community.crypto/issues/936, https://github.com/ansible-collections/community.crypto/pull/939).
|
||||||
|
|
||||||
v3.0.1
|
v3.0.1
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
[collection_sources]
|
[collection_sources]
|
||||||
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
|
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
|
||||||
|
|
||||||
|
[vcs]
|
||||||
|
vcs = "git"
|
||||||
|
development_branch = "main"
|
||||||
|
stable_branches = [ "stable-*" ]
|
||||||
|
|
||||||
[sessions]
|
[sessions]
|
||||||
|
|
||||||
[sessions.lint]
|
[sessions.lint]
|
||||||
@@ -15,14 +20,14 @@ run_flake8 = true
|
|||||||
flake8_config = ".flake8"
|
flake8_config = ".flake8"
|
||||||
run_pylint = true
|
run_pylint = true
|
||||||
pylint_rcfile = ".pylintrc"
|
pylint_rcfile = ".pylintrc"
|
||||||
pylint_ansible_core_package = "ansible-core>=2.19.0b4"
|
pylint_ansible_core_package = "ansible-core>=2.19.0"
|
||||||
run_yamllint = true
|
run_yamllint = true
|
||||||
yamllint_config = ".yamllint"
|
yamllint_config = ".yamllint"
|
||||||
yamllint_config_plugins = ".yamllint-docs"
|
yamllint_config_plugins = ".yamllint-docs"
|
||||||
yamllint_config_plugins_examples = ".yamllint-examples"
|
yamllint_config_plugins_examples = ".yamllint-examples"
|
||||||
yamllint_config_extra_docs = ".yamllint-extra-docs"
|
yamllint_config_extra_docs = ".yamllint-extra-docs"
|
||||||
run_mypy = true
|
run_mypy = true
|
||||||
mypy_ansible_core_package = "ansible-core>=2.19.0b4"
|
mypy_ansible_core_package = "ansible-core>=2.19.0"
|
||||||
mypy_config = ".mypy.ini"
|
mypy_config = ".mypy.ini"
|
||||||
mypy_extra_deps = [
|
mypy_extra_deps = [
|
||||||
"cryptography",
|
"cryptography",
|
||||||
@@ -79,3 +84,36 @@ skip_paths = [
|
|||||||
run_galaxy_importer = true
|
run_galaxy_importer = true
|
||||||
|
|
||||||
[sessions.ansible_lint]
|
[sessions.ansible_lint]
|
||||||
|
|
||||||
|
[[sessions.ee_check.execution_environments]]
|
||||||
|
name = "devel-ubi-9"
|
||||||
|
description = "ansible-core devel @ RHEL UBI 9"
|
||||||
|
test_playbooks = ["tests/ee/all.yml"]
|
||||||
|
config.images.base_image.name = "docker.io/redhat/ubi9:latest"
|
||||||
|
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/devel.tar.gz"
|
||||||
|
config.dependencies.ansible_runner.package_pip = "ansible-runner"
|
||||||
|
config.dependencies.python_interpreter.package_system = "python3.12 python3.12-pip python3.12-wheel python3.12-cryptography"
|
||||||
|
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.12"
|
||||||
|
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
|
||||||
|
|
||||||
|
[[sessions.ee_check.execution_environments]]
|
||||||
|
name = "2.17-rocky-9"
|
||||||
|
description = "ansible-core 2.17 @ Rocky Linux 9"
|
||||||
|
test_playbooks = ["tests/ee/all.yml"]
|
||||||
|
config.images.base_image.name = "quay.io/rockylinux/rockylinux:9"
|
||||||
|
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/stable-2.17.tar.gz"
|
||||||
|
config.dependencies.ansible_runner.package_pip = "ansible-runner"
|
||||||
|
config.dependencies.python_interpreter.package_system = "python3.11 python3.11-pip python3.11-wheel python3.11-cryptography"
|
||||||
|
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.11"
|
||||||
|
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
|
||||||
|
|
||||||
|
[[sessions.ee_check.execution_environments]]
|
||||||
|
name = "2.18-centos-stream-9"
|
||||||
|
description = "ansible-core 2.18 @ CentOS Stream 9"
|
||||||
|
test_playbooks = ["tests/ee/all.yml"]
|
||||||
|
config.images.base_image.name = "quay.io/centos/centos:stream9"
|
||||||
|
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/stable-2.18.tar.gz"
|
||||||
|
config.dependencies.ansible_runner.package_pip = "ansible-runner"
|
||||||
|
config.dependencies.python_interpreter.package_system = "python3.11 python3.11-pip python3.11-wheel python3.11-cryptography"
|
||||||
|
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.11"
|
||||||
|
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
|
||||||
|
|||||||
@@ -1841,3 +1841,39 @@ releases:
|
|||||||
- 3.0.1.yml
|
- 3.0.1.yml
|
||||||
- 395-csr-key_usage.yml
|
- 395-csr-key_usage.yml
|
||||||
release_date: '2025-07-17'
|
release_date: '2025-07-17'
|
||||||
|
3.0.2:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- Improve error message when loading a private key fails due to correct private
|
||||||
|
key files or wrong passwords. Also include the original cryptography error
|
||||||
|
since it likely contains more helpful information (https://github.com/ansible-collections/community.crypto/issues/936,
|
||||||
|
https://github.com/ansible-collections/community.crypto/pull/939).
|
||||||
|
release_summary: Bugfix release.
|
||||||
|
fragments:
|
||||||
|
- 3.0.2.yml
|
||||||
|
- 939-private-key-errors.yml
|
||||||
|
release_date: '2025-07-26'
|
||||||
|
3.0.3:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- acme_* modules - also retry on HTTP responses 502 Bad Gateway and 504 Gateway
|
||||||
|
Timeout. The latter is needed for ZeroSSL, which seems to have a lot of
|
||||||
|
504s (https://github.com/ansible-collections/community.crypto/issues/945,
|
||||||
|
https://github.com/ansible-collections/community.crypto/pull/947).
|
||||||
|
- acme_* modules - increase the maximum amount of retries from 10 to 20 to
|
||||||
|
accomodate ZeroSSL's buggy implementation (https://github.com/ansible-collections/community.crypto/pull/949).
|
||||||
|
release_summary: Bugfix release.
|
||||||
|
fragments:
|
||||||
|
- 3.0.3.yml
|
||||||
|
- 947-acme-retry.yml
|
||||||
|
- 949-acme-retry.yml
|
||||||
|
release_date: '2025-08-04'
|
||||||
|
3.0.4:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- Avoid deprecated functionality in ansible-core 2.20 (https://github.com/ansible-collections/community.crypto/pull/953).
|
||||||
|
release_summary: Maintenance release.
|
||||||
|
fragments:
|
||||||
|
- 3.0.4.yml
|
||||||
|
- 953-deprecations.yml
|
||||||
|
release_date: '2025-10-01'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ changelog_filename_template: ../CHANGELOG.rst
|
|||||||
changelog_filename_version_depth: 0
|
changelog_filename_version_depth: 0
|
||||||
changes_file: changelog.yaml
|
changes_file: changelog.yaml
|
||||||
changes_format: combined
|
changes_format: combined
|
||||||
|
ignore_other_fragment_extensions: true
|
||||||
keep_fragments: false
|
keep_fragments: false
|
||||||
mention_ancestor: true
|
mention_ancestor: true
|
||||||
new_plugins_after_name: removed_features
|
new_plugins_after_name: removed_features
|
||||||
@@ -39,3 +40,4 @@ use_fqcn: true
|
|||||||
add_plugin_period: true
|
add_plugin_period: true
|
||||||
changelog_nice_yaml: true
|
changelog_nice_yaml: true
|
||||||
changelog_sort: version
|
changelog_sort: version
|
||||||
|
vcs: auto
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace: community
|
namespace: community
|
||||||
name: crypto
|
name: crypto
|
||||||
version: 3.0.1
|
version: 3.0.4
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Ansible (github.com/ansible)
|
- Ansible (github.com/ansible)
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from ansible.module_utils.common._collections_compat import Mapping
|
|
||||||
from ansible_collections.community.crypto.plugins.module_utils._acme.errors import (
|
from ansible_collections.community.crypto.plugins.module_utils._acme.errors import (
|
||||||
ACMEProtocolException,
|
ACMEProtocolException,
|
||||||
ModuleFailException,
|
ModuleFailException,
|
||||||
@@ -22,6 +22,11 @@ if t.TYPE_CHECKING:
|
|||||||
ACMEClient,
|
ACMEClient,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_JsonMapping = Mapping[str, t.Any]
|
||||||
|
else:
|
||||||
|
# Since we need to pass this to t.cast(), we need a version that doesn't break with Python 3.7 and 3.8
|
||||||
|
_JsonMapping = Mapping
|
||||||
|
|
||||||
|
|
||||||
class ACMEAccount:
|
class ACMEAccount:
|
||||||
"""
|
"""
|
||||||
@@ -42,7 +47,7 @@ class ACMEAccount:
|
|||||||
terms_agreed: bool = False,
|
terms_agreed: bool = False,
|
||||||
allow_creation: bool = True,
|
allow_creation: bool = True,
|
||||||
external_account_binding: dict[str, t.Any] | None = None,
|
external_account_binding: dict[str, t.Any] | None = None,
|
||||||
) -> tuple[bool, dict[str, t.Any] | None]:
|
) -> tuple[bool, Mapping[str, t.Any] | None]:
|
||||||
"""
|
"""
|
||||||
Registers a new ACME account. Returns a pair ``(created, data)``.
|
Registers a new ACME account. Returns a pair ``(created, data)``.
|
||||||
Here, ``created`` is ``True`` if the account was created and
|
Here, ``created`` is ``True`` if the account was created and
|
||||||
@@ -132,7 +137,7 @@ class ACMEAccount:
|
|||||||
# Account did not exist
|
# Account did not exist
|
||||||
if "location" in info:
|
if "location" in info:
|
||||||
self.client.set_account_uri(info["location"])
|
self.client.set_account_uri(info["location"])
|
||||||
return True, result
|
return True, t.cast(_JsonMapping, result)
|
||||||
if info["status"] == 200:
|
if info["status"] == 200:
|
||||||
# Account did exist
|
# Account did exist
|
||||||
if result.get("status") == "deactivated":
|
if result.get("status") == "deactivated":
|
||||||
@@ -147,7 +152,7 @@ class ACMEAccount:
|
|||||||
raise ModuleFailException("Account is deactivated")
|
raise ModuleFailException("Account is deactivated")
|
||||||
if "location" in info:
|
if "location" in info:
|
||||||
self.client.set_account_uri(info["location"])
|
self.client.set_account_uri(info["location"])
|
||||||
return False, result
|
return False, t.cast(_JsonMapping, result)
|
||||||
if (
|
if (
|
||||||
info["status"] in (400, 404)
|
info["status"] in (400, 404)
|
||||||
and result["type"] == "urn:ietf:params:acme:error:accountDoesNotExist"
|
and result["type"] == "urn:ietf:params:acme:error:accountDoesNotExist"
|
||||||
@@ -236,7 +241,7 @@ class ACMEAccount:
|
|||||||
allow_creation: t.Literal[True] = True,
|
allow_creation: t.Literal[True] = True,
|
||||||
remove_account_uri_if_not_exists: bool = False,
|
remove_account_uri_if_not_exists: bool = False,
|
||||||
external_account_binding: dict[str, t.Any] | None = None,
|
external_account_binding: dict[str, t.Any] | None = None,
|
||||||
) -> tuple[bool, dict[str, t.Any]]: ...
|
) -> tuple[bool, Mapping[str, t.Any]]: ...
|
||||||
|
|
||||||
@t.overload
|
@t.overload
|
||||||
def setup_account(
|
def setup_account(
|
||||||
@@ -247,7 +252,7 @@ class ACMEAccount:
|
|||||||
allow_creation: bool = True,
|
allow_creation: bool = True,
|
||||||
remove_account_uri_if_not_exists: bool = False,
|
remove_account_uri_if_not_exists: bool = False,
|
||||||
external_account_binding: dict[str, t.Any] | None = None,
|
external_account_binding: dict[str, t.Any] | None = None,
|
||||||
) -> tuple[bool, dict[str, t.Any] | None]: ...
|
) -> tuple[bool, Mapping[str, t.Any] | None]: ...
|
||||||
|
|
||||||
def setup_account(
|
def setup_account(
|
||||||
self,
|
self,
|
||||||
@@ -257,7 +262,7 @@ class ACMEAccount:
|
|||||||
allow_creation: bool = True,
|
allow_creation: bool = True,
|
||||||
remove_account_uri_if_not_exists: bool = False,
|
remove_account_uri_if_not_exists: bool = False,
|
||||||
external_account_binding: dict[str, t.Any] | None = None,
|
external_account_binding: dict[str, t.Any] | None = None,
|
||||||
) -> tuple[bool, dict[str, t.Any] | None]:
|
) -> tuple[bool, Mapping[str, t.Any] | None]:
|
||||||
"""
|
"""
|
||||||
Detect or create an account on the ACME server. For ACME v1,
|
Detect or create an account on the ACME server. For ACME v1,
|
||||||
as the only way (without knowing an account URI) to test if an
|
as the only way (without knowing an account URI) to test if an
|
||||||
@@ -288,7 +293,7 @@ class ACMEAccount:
|
|||||||
created = False
|
created = False
|
||||||
# Verify that the account key belongs to the URI.
|
# Verify that the account key belongs to the URI.
|
||||||
# (If update_contact is True, this will be done below.)
|
# (If update_contact is True, this will be done below.)
|
||||||
account_data = self.get_account_data()
|
account_data: Mapping[str, t.Any] | None = self.get_account_data()
|
||||||
if account_data is None:
|
if account_data is None:
|
||||||
if remove_account_uri_if_not_exists and not allow_creation:
|
if remove_account_uri_if_not_exists and not allow_creation:
|
||||||
self.client.account_uri = None
|
self.client.account_uri = None
|
||||||
@@ -314,7 +319,7 @@ class ACMEAccount:
|
|||||||
|
|
||||||
def update_account(
|
def update_account(
|
||||||
self, *, account_data: dict[str, t.Any], contact: list[str] | None = None
|
self, *, account_data: dict[str, t.Any], contact: list[str] | None = None
|
||||||
) -> tuple[bool, dict[str, t.Any]]:
|
) -> tuple[bool, Mapping[str, t.Any]]:
|
||||||
"""
|
"""
|
||||||
Update an account on the ACME server. Check mode is fully respected.
|
Update an account on the ACME server. Check mode is fully respected.
|
||||||
|
|
||||||
@@ -340,9 +345,11 @@ class ACMEAccount:
|
|||||||
return False, dict(account_data)
|
return False, dict(account_data)
|
||||||
|
|
||||||
# Apply change
|
# Apply change
|
||||||
|
account_data_res: Mapping[str, t.Any]
|
||||||
if self.client.module.check_mode:
|
if self.client.module.check_mode:
|
||||||
account_data = dict(account_data)
|
account_data_dict = dict(account_data)
|
||||||
account_data.update(update_request)
|
account_data_dict.update(update_request)
|
||||||
|
account_data_res = account_data_dict
|
||||||
else:
|
else:
|
||||||
raw_account_data, info = self.client.send_signed_request(
|
raw_account_data, info = self.client.send_signed_request(
|
||||||
self.client.account_uri, update_request
|
self.client.account_uri, update_request
|
||||||
@@ -354,9 +361,9 @@ class ACMEAccount:
|
|||||||
info=info,
|
info=info,
|
||||||
content_json=account_data,
|
content_json=account_data,
|
||||||
)
|
)
|
||||||
account_data = raw_account_data
|
account_data_res = raw_account_data
|
||||||
|
|
||||||
return True, account_data
|
return True, account_data_res
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("ACMEAccount",)
|
__all__ = ("ACMEAccount",)
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ if t.TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
# -1 usually means connection problems
|
# -1 usually means connection problems
|
||||||
RETRY_STATUS_CODES = (-1, 408, 429, 503)
|
RETRY_STATUS_CODES = (-1, 408, 429, 502, 503, 504)
|
||||||
|
|
||||||
RETRY_COUNT = 10
|
RETRY_COUNT = 20
|
||||||
|
|
||||||
|
|
||||||
def _decode_retry(
|
def _decode_retry(
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from ansible_collections.community.crypto.plugins.module_utils._crypto.pem impor
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from cryptography import x509
|
from cryptography import x509
|
||||||
|
from cryptography.exceptions import UnsupportedAlgorithm
|
||||||
from cryptography.hazmat.primitives import hashes, serialization
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -168,13 +169,15 @@ def load_privatekey(
|
|||||||
priv_key_detail,
|
priv_key_detail,
|
||||||
None if passphrase is None else to_bytes(passphrase),
|
None if passphrase is None else to_bytes(passphrase),
|
||||||
)
|
)
|
||||||
|
except UnsupportedAlgorithm as exc:
|
||||||
|
raise OpenSSLBadPassphraseError(f"Unsupported private key type: {exc}") from exc
|
||||||
except TypeError as exc:
|
except TypeError as exc:
|
||||||
raise OpenSSLBadPassphraseError(
|
raise OpenSSLBadPassphraseError(
|
||||||
"Wrong or empty passphrase provided for private key"
|
"Wrong or empty passphrase provided for private key"
|
||||||
) from exc
|
) from exc
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise OpenSSLBadPassphraseError(
|
raise OpenSSLBadPassphraseError(
|
||||||
"Wrong passphrase provided for private key"
|
f"Wrong passphrase provided for private key, or private key cannot be parsed: {exc}"
|
||||||
) from exc
|
) from exc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -320,11 +320,12 @@ def main() -> t.NoReturn:
|
|||||||
result["account_uri"] = client.account_uri
|
result["account_uri"] = client.account_uri
|
||||||
result["exists"] = True
|
result["exists"] = True
|
||||||
# Make sure promised data is there
|
# Make sure promised data is there
|
||||||
|
account_data_dict = dict(account_data)
|
||||||
if "contact" not in account_data:
|
if "contact" not in account_data:
|
||||||
account_data["contact"] = []
|
account_data_dict["contact"] = []
|
||||||
if client.account_key_data:
|
if client.account_key_data:
|
||||||
account_data["public_account_key"] = client.account_key_data["jwk"]
|
account_data_dict["public_account_key"] = client.account_key_data["jwk"]
|
||||||
result["account"] = account_data
|
result["account"] = account_data_dict
|
||||||
# Retrieve orders list
|
# Retrieve orders list
|
||||||
if (
|
if (
|
||||||
account_data.get("orders")
|
account_data.get("orders")
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ import traceback
|
|||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.module_utils.basic import SEQUENCETYPE, remove_values
|
from ansible.module_utils.basic import remove_values
|
||||||
from ansible.module_utils.common._collections_compat import Mapping
|
|
||||||
from ansible.module_utils.common.arg_spec import ArgumentSpecValidator
|
from ansible.module_utils.common.arg_spec import ArgumentSpecValidator
|
||||||
from ansible.module_utils.errors import UnsupportedError
|
from ansible.module_utils.errors import UnsupportedError
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
@@ -164,39 +163,9 @@ class AnsibleActionModule:
|
|||||||
if "invocation" not in kwargs:
|
if "invocation" not in kwargs:
|
||||||
kwargs["invocation"] = {"module_args": self.params}
|
kwargs["invocation"] = {"module_args": self.params}
|
||||||
|
|
||||||
if "warnings" in kwargs:
|
|
||||||
if isinstance(kwargs["warnings"], list):
|
|
||||||
for w in kwargs["warnings"]:
|
|
||||||
self.warn(w)
|
|
||||||
else:
|
|
||||||
self.warn(kwargs["warnings"])
|
|
||||||
|
|
||||||
if self.__warnings:
|
if self.__warnings:
|
||||||
kwargs["warnings"] = self.__warnings
|
kwargs["warnings"] = self.__warnings
|
||||||
|
|
||||||
if "deprecations" in kwargs:
|
|
||||||
if isinstance(kwargs["deprecations"], list):
|
|
||||||
for d in kwargs["deprecations"]:
|
|
||||||
if isinstance(d, SEQUENCETYPE) and len(d) == 2:
|
|
||||||
self.deprecate(d[0], version=d[1])
|
|
||||||
elif isinstance(d, Mapping):
|
|
||||||
self.deprecate(
|
|
||||||
d["msg"],
|
|
||||||
version=d.get("version"),
|
|
||||||
date=d.get("date"),
|
|
||||||
collection_name=d.get("collection_name"),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# pylint: disable-next=unknown-option-value
|
|
||||||
self.deprecate( # pylint: disable=ansible-deprecated-no-version
|
|
||||||
d
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# pylint: disable-next=unknown-option-value
|
|
||||||
self.deprecate( # pylint: disable=ansible-deprecated-no-version
|
|
||||||
kwargs["deprecations"]
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.__deprecations:
|
if self.__deprecations:
|
||||||
kwargs["deprecations"] = self.__deprecations
|
kwargs["deprecations"] = self.__deprecations
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,32 @@
|
|||||||
- "'public_data' not in result"
|
- "'public_data' not in result"
|
||||||
- "'private_data' not in result"
|
- "'private_data' not in result"
|
||||||
|
|
||||||
|
- name: ({{ select_crypto_backend }}) Get key 3 info (with wrong passphrase)
|
||||||
|
community.crypto.openssl_privatekey_info:
|
||||||
|
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
|
||||||
|
return_private_key_data: true
|
||||||
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
passphrase: blabla
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Check that loading passphrase protected key with wrong passphrase failed
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
# Check that return values are there
|
||||||
|
- result.can_load_key is defined
|
||||||
|
- result.can_parse_key is defined
|
||||||
|
# Check that return values are correct
|
||||||
|
- result.can_load_key
|
||||||
|
- not result.can_parse_key
|
||||||
|
# Check that additional data isn't there
|
||||||
|
- "'pulic_key' not in result"
|
||||||
|
- "'pulic_key_fingerprints' not in result"
|
||||||
|
- "'type' not in result"
|
||||||
|
- "'public_data' not in result"
|
||||||
|
- "'private_data' not in result"
|
||||||
|
|
||||||
- name: ({{ select_crypto_backend }}) Get key 3 info (with passphrase)
|
- name: ({{ select_crypto_backend }}) Get key 3 info (with passphrase)
|
||||||
community.crypto.openssl_privatekey_info:
|
community.crypto.openssl_privatekey_info:
|
||||||
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
|
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
|
||||||
@@ -155,3 +181,53 @@
|
|||||||
- "result.public_data.y > 2"
|
- "result.public_data.y > 2"
|
||||||
- "'private_data' in result"
|
- "'private_data' in result"
|
||||||
- "result.private_data.x > 2"
|
- "result.private_data.x > 2"
|
||||||
|
|
||||||
|
- name: ({{ select_crypto_backend }}) Get empty key info
|
||||||
|
community.crypto.openssl_privatekey_info:
|
||||||
|
content: ''
|
||||||
|
return_private_key_data: true
|
||||||
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Check that empty key loading failed
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
# Check that return values are there
|
||||||
|
- result.can_load_key is defined
|
||||||
|
- result.can_parse_key is defined
|
||||||
|
# Check that return values are correct
|
||||||
|
- result.can_load_key
|
||||||
|
- not result.can_parse_key
|
||||||
|
# Check that additional data isn't there
|
||||||
|
- "'pulic_key' not in result"
|
||||||
|
- "'pulic_key_fingerprints' not in result"
|
||||||
|
- "'type' not in result"
|
||||||
|
- "'public_data' not in result"
|
||||||
|
- "'private_data' not in result"
|
||||||
|
|
||||||
|
- name: ({{ select_crypto_backend }}) Get corrupt key info
|
||||||
|
community.crypto.openssl_privatekey_info:
|
||||||
|
content: C0RRUPT
|
||||||
|
return_private_key_data: true
|
||||||
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Check that corrupt key loading failed
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
# Check that return values are there
|
||||||
|
- result.can_load_key is defined
|
||||||
|
- result.can_parse_key is defined
|
||||||
|
# Check that return values are correct
|
||||||
|
- result.can_load_key
|
||||||
|
- not result.can_parse_key
|
||||||
|
# Check that additional data isn't there
|
||||||
|
- "'pulic_key' not in result"
|
||||||
|
- "'pulic_key_fingerprints' not in result"
|
||||||
|
- "'type' not in result"
|
||||||
|
- "'public_data' not in result"
|
||||||
|
- "'private_data' not in result"
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ system_python_version_data:
|
|||||||
- '3.9'
|
- '3.9'
|
||||||
'12':
|
'12':
|
||||||
- '3.11'
|
- '3.11'
|
||||||
|
'13':
|
||||||
|
- '3.13'
|
||||||
Alpine:
|
Alpine:
|
||||||
'3.16':
|
'3.16':
|
||||||
- '3.10'
|
- '3.10'
|
||||||
@@ -95,3 +97,6 @@ cannot_upgrade_cryptography:
|
|||||||
- '3.9' # this is the default container for ansible-core 2.12; upgrading cryptography wrecks pyOpenSSL
|
- '3.9' # this is the default container for ansible-core 2.12; upgrading cryptography wrecks pyOpenSSL
|
||||||
'24':
|
'24':
|
||||||
- '3.12' # ERROR: Cannot uninstall cryptography 41.0.7, RECORD file not found. Hint: The package was installed by debian.
|
- '3.12' # ERROR: Cannot uninstall cryptography 41.0.7, RECORD file not found. Hint: The package was installed by debian.
|
||||||
|
Debian:
|
||||||
|
'13':
|
||||||
|
- '3.13' # ERROR: Cannot uninstall cryptography 43.0.0, RECORD file not found. Hint: The package was installed by debian.
|
||||||
|
|||||||
Reference in New Issue
Block a user