diff --git a/.codespellignorelines b/.codespellignorelines index 59936541356..6768407657e 100644 --- a/.codespellignorelines +++ b/.codespellignorelines @@ -13,3 +13,7 @@ see the `Active Directory Certificate Services documentation "$6$43927$lQxPKz2M2X.NWO.gK.t7phLwOKQMcSq72XxDZQ0XzYV6DlL1OD72h417aj16OnHTGxNzhftXJQBcjbunLEepM0" table#network-platform-table thead tr th.head { +# Following lines from the generated file docs/docsite/rst/reference_appendices/config.rst +:Description: This setting changes the behaviour of mismatched host patterns, it allows you to force a fatal error, a warning or just ignore it. + This setting changes the behaviour of mismatched host patterns, it allows you to force a fatal error, a warning or just ignore it. + /msg alis LIST #ansible* -min 5 diff --git a/.github/workflows/build-package-docs.yaml b/.github/workflows/build-package-docs.yaml index aa00854f026..5d95397fe78 100644 --- a/.github/workflows/build-package-docs.yaml +++ b/.github/workflows/build-package-docs.yaml @@ -2,6 +2,8 @@ name: Ansible package docs build on: + schedule: + - cron: '17 5 * * *' # Run at 05:17 am workflow_dispatch: inputs: repository-owner: @@ -16,34 +18,31 @@ on: description: Branch, tag, or commit SHA required: true default: devel - language: - type: choice - description: Language - required: true - default: english - options: - - english - - japanese ansible-package-version: type: choice - description: Version of the Ansible community package to build + description: Ansible community package version required: true default: devel options: - devel + - '11' - '10' - '9' - - '8' - - '7' - latest-symlink: + deploy: type: boolean - description: Add latest symlink + description: Deploy the build required: true - + deployment-environment: + type: choice + description: Deployment environment + required: true + default: test + options: + - production + - test env: - PACKAGE_VERSION: ${{ github.event.inputs.ansible-package-version }} - LANGUAGE: ${{ github.event.inputs.language }} + PACKAGE_VERSION: ${{ github.event.inputs.ansible-package-version || 'devel' }} jobs: build-package-docs: @@ -54,11 +53,11 @@ jobs: with: repository: >- ${{ - github.event.inputs.repository-owner + github.event.inputs.repository-owner || 'ansible' }}/${{ - github.event.inputs.repository-name + github.event.inputs.repository-name || 'ansible-documentation' }} - ref: ${{ github.event.inputs.repository-branch }} + ref: ${{ github.event.inputs.repository-branch || 'devel' }} path: build-directory - name: Setup nox @@ -81,30 +80,20 @@ jobs: - name: Set the COLLECTION_LIST variable if: env.PACKAGE_VERSION != 'devel' run: >- - echo COLLECTION_LIST='"${PACKAGE_VERSION}"' + echo COLLECTION_LIST="${PACKAGE_VERSION}" >> "${GITHUB_ENV}" - name: Set the VERSION variable - run: | - if [ ${LANGUAGE} == "english" ]; then - echo VERSION="${PACKAGE_VERSION}" >> "${GITHUB_ENV}" - elif [ ${LANGUAGE} == "japanese" ]; then - echo VERSION="${PACKAGE_VERSION}_ja" >> "${GITHUB_ENV}" - fi + run: echo VERSION="${PACKAGE_VERSION}" >> "${GITHUB_ENV}" - name: Build the Ansible community package docs run: make webdocs ANSIBLE_VERSION="${COLLECTION_LIST}" working-directory: build-directory/docs/docsite - - name: Create latest symlink - if: fromJSON(github.event.inputs.latest-symlink) - run: ln -s "${VERSION}" _build/html/latest - working-directory: build-directory/docs/docsite - - name: Create a tarball with the build contents run: >- tar -czvf - ansible-package-docs-html-"${PACKAGE_VERSION}"-$(date '+%Y-%m-%d')-${{ + ansible-package-docs-html-"${PACKAGE_VERSION}"-"$(date '+%Y-%m-%d')"-${{ github.run_id }}-${{ github.run_number @@ -120,3 +109,131 @@ jobs: name: package-docs-build path: build-directory/docs/docsite/ansible-package-docs-html-*.tar.gz retention-days: 7 + + check-deploy: + if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'true' + needs: build-package-docs + runs-on: ubuntu-latest + steps: + - name: Log the workflow inputs if deployed + run: | + { + echo "## Deployment details :shipit:"; + echo "Publish to: ${{ github.event.inputs.deployment-environment }}"; + echo "Package version: ${{ github.event.inputs.ansible-package-version }}"; + echo "Owner: ${{ github.event.inputs.repository-owner }}"; + echo "Branch: ${{ github.event.inputs.repository-branch }}"; + } >> "${GITHUB_STEP_SUMMARY}" + + notify-build-failures: + if: failure() + needs: build-package-docs + runs-on: ubuntu-latest + env: + ROOM_URL: https://ansible-accounts.ems.host/_matrix/client/v3/rooms/!HJtetIFWYEIDBOXxFE:libera.chat/send/m.room.message + FAIL_MESSAGE: >- + Oh no! A community package docs build has failed. + Check this workflow run to see what went wrong: + https://github.com/ansible/ansible-documentation/actions/runs/${{ github.run_id }} + @orandon @samccann + steps: + - name: Set a transaction ID + run: echo "TX_ID=$(date +%s)" >> "${GITHUB_ENV}" + + - name: Notify the DaWGs in Matrix + run: | + curl -X PUT "${{ env.ROOM_URL }}/${TX_ID}" \ + -H "Authorization: Bearer ${{ secrets.DOCS_BOT_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d '{"msgtype": "m.text", "body": "${{ env.FAIL_MESSAGE }}"}' + + deploy-package-docs: + needs: + - check-deploy + runs-on: ubuntu-latest + environment: + name: deploy-package-docs + url: ${{ env.ENV_URL }} + env: + TARGET: ${{ github.event.inputs.deployment-environment }} + DEST_REPO: ansible-community/package-doc-builds + USER_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com" + USER_NAME: "github-actions[bot]" + steps: + - name: Download the build archive + uses: actions/download-artifact@v4 + with: + name: package-docs-build + + - name: Extract the tarball + run: >- + tar -xvzf + ansible-package-docs-html-*.tar.gz + --one-top-level + + - name: Set the production branch and url + if: env.TARGET == 'production' + env: + BRANCH_NAME: ${{ github.event.inputs.ansible-package-version }} + PROD_URL: https://ansible.readthedocs.io/projects/ansible + run: | + echo "BRANCH=${BRANCH_NAME}" >> "${GITHUB_ENV}" + echo "ENV_URL=${PROD_URL}/${BRANCH_NAME}" >> "${GITHUB_ENV}" + + - name: Set the test branch and url + if: env.TARGET == 'test' + env: + TEST_URL: https://ansible-community.github.io/package-doc-builds + run: | + echo "BRANCH=gh-pages" >> "${GITHUB_ENV}" + echo "ENV_URL=${TEST_URL}" >> "${GITHUB_ENV}" + + - name: Checkout the deploy directory + uses: actions/checkout@v4 + with: + repository: ${{ env.DEST_REPO }} + ref: ${{ env.BRANCH }} + path: deploy-directory + fetch-depth: 0 + ssh-key: ${{ secrets.DEPLOY_DOC_BUILD }} + persist-credentials: true + + - name: Copy the generated HTML and assets for production + run: >- + rsync -av --delete --mkpath + ansible-package-docs-html-*/ + deploy-directory/docs + + - name: Create a norobots.txt file for the test site + if: env.TARGET == 'test' + run: | + touch norobots.txt + echo "User-agent: *" > norobots.txt + echo "Disallow: /" >> norobots.txt + working-directory: deploy-directory/docs + + - name: Configure the git user + run: | + git config --local user.email "${USER_EMAIL}" + git config --local user.name "${USER_NAME}" + working-directory: deploy-directory + + - name: Git add the generated HTML and assets + run: git add ./docs --all --force + working-directory: deploy-directory + + - name: Commit generated HTML and assets + run: >- + git diff-index --quiet HEAD || + git commit -m "Push docs build $(date '+%Y-%m-%d')-${{ + github.run_id + }}-${{ + github.run_number + }}-${{ + github.run_attempt + }}" + working-directory: deploy-directory + + - name: Push build to deploy repository + run: git push origin + working-directory: deploy-directory diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3d92f5c4ede..c52912470b2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,9 @@ name: Ansible Docsite CI on: + schedule: + # Daily + - cron: "23 7 * * *" push: branches-ignore: - 'patchback/**' @@ -11,3 +14,17 @@ on: jobs: nox: uses: ./.github/workflows/reusable-nox.yml + + check: + if: always() + + needs: + - nox + + runs-on: ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 7b69e67a9b2..501729b85e4 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -44,10 +44,13 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.11" + - name: Set up UV + run: curl -LsSf https://astral.sh/uv/install.sh | sh - name: Setup venv run: | - python -m venv venv - ./venv/bin/pip install -r hacking/pr_labeler/requirements.txt + uv venv venv + uv pip install --python venv \ + -e hacking/pr_labeler -c tests/pr_labeler.txt - name: "Run the issue labeler" if: "github.event.issue || inputs.type == 'issue'" env: @@ -55,7 +58,7 @@ jobs: GITHUB_TOKEN: ${{ steps.create_token.outputs.token }} number: "${{ github.event.issue.number || inputs.number }}" run: | - ./venv/bin/python hacking/pr_labeler/label.py issue "${number}" + ./venv/bin/ad-triage issue "${number}" - name: "Run the PR labeler" if: "github.event.pull_request || inputs.type == 'pr'" env: @@ -63,4 +66,4 @@ jobs: GITHUB_TOKEN: ${{ steps.create_token.outputs.token }} number: "${{ github.event.number || inputs.number }}" run: | - ./venv/bin/python hacking/pr_labeler/label.py pr "${number}" + ./venv/bin/ad-triage pr "${number}" diff --git a/.github/workflows/pip-compile-dev.yml b/.github/workflows/pip-compile-dev.yml index c648cd9dcf9..98727d90deb 100644 --- a/.github/workflows/pip-compile-dev.yml +++ b/.github/workflows/pip-compile-dev.yml @@ -6,39 +6,62 @@ name: "Refresh dev dependencies" - cron: "0 0 * * 0" workflow_dispatch: inputs: - base-branch: - required: false - type: string - pr-branch: - required: false - type: string reset-branch: type: boolean default: false labels: required: false type: string - push: - branches: - - devel - paths: - - .github/workflows/reusable-pip-compile.yml - - ".github/workflows/pip-compile-dev.yml" - - "tests/*.in" jobs: refresh: + strategy: + fail-fast: false + matrix: + include: + - base-branch: devel + pr-branch: pip-compile/devel/dev + nox-args: >- + -e 'pip-compile-3.11(formatters)' + 'pip-compile-3.11(typing)' + 'pip-compile-3.11(static)' + 'pip-compile-3.11(spelling)' + 'pip-compile-3.11(tag)' + - base-branch: stable-2.17 + pr-branch: pip-compile/stable-2.17/dev + nox-args: >- + -e 'pip-compile-3.10(formatters)' + 'pip-compile-3.10(typing)' + 'pip-compile-3.10(static)' + 'pip-compile-3.10(spelling)' + - base-branch: stable-2.16 + pr-branch: pip-compile/stable-2.16/dev + nox-args: >- + -e 'pip-compile-3.10(formatters)' + 'pip-compile-3.10(typing)' + 'pip-compile-3.10(static)' + 'pip-compile-3.10(spelling)' + - base-branch: stable-2.15 + pr-branch: pip-compile/stable-2.15/dev + nox-args: >- + -e 'pip-compile-3.10(formatters)' + 'pip-compile-3.10(typing)' + 'pip-compile-3.10(static)' + 'pip-compile-3.10(spelling)' + - base-branch: stable-2.14 + pr-branch: pip-compile/stable-2.14/dev + nox-args: >- + -e 'pip-compile-3.10(formatters)' + 'pip-compile-3.10(typing)' + 'pip-compile-3.10(static)' + 'pip-compile-3.10(spelling)' name: "Refresh dev dependencies" uses: ./.github/workflows/reusable-pip-compile.yml with: message: "ci: refresh dev dependencies" - base-branch: "${{ inputs.base-branch || 'devel' }}" - pr-branch: "${{ inputs.pr-branch || 'pip-compile/devel/dev' }}" - nox-args: >- - -e 'pip-compile-3.10(formatters)' - 'pip-compile-3.10(typing)' - 'pip-compile-3.10(static)' - 'pip-compile-3.10(spelling)' + base-branch: "${{ matrix.base-branch }}" + pr-branch: "${{ matrix.pr-branch }}" + nox-args: "${{ matrix.nox-args }}" reset-branch: "${{ inputs.reset-branch || false }}" - labels: "${{ inputs.labels || 'backport-2.14,backport-2.15,backport-2.16,backport-2.17,tooling' }}" + labels: "${{ inputs.labels || 'no_backport,tooling' }}" secrets: inherit diff --git a/.github/workflows/pip-compile-docs.yml b/.github/workflows/pip-compile-docs.yml index 6c90c24e10c..8c42c90c840 100644 --- a/.github/workflows/pip-compile-docs.yml +++ b/.github/workflows/pip-compile-docs.yml @@ -18,13 +18,6 @@ name: "Refresh docs build dependencies" labels: required: false type: string - push: - branches: - - devel - paths: - - .github/workflows/reusable-pip-compile.yml - - ".github/workflows/pip-compile-docs.yml" - - "tests/*.in" jobs: refresh: @@ -34,7 +27,10 @@ jobs: message: "ci: refresh docs build dependencies" base-branch: "${{ inputs.base-branch || 'devel' }}" pr-branch: "${{ inputs.pr-branch || 'pip-compile/devel/docs' }}" - nox-args: "-e 'pip-compile-3.10(requirements)' 'pip-compile-3.10(requirements-relaxed)'" + nox-args: >- + -e + 'pip-compile-3.11(requirements)' + 'pip-compile-3.11(requirements-relaxed)' reset-branch: "${{ inputs.reset-branch || false }}" labels: "${{ inputs.labels || 'doc builds,no_backport' }}" secrets: inherit diff --git a/.github/workflows/reusable-nox.yml b/.github/workflows/reusable-nox.yml index bf8ac66ab75..1793e35e026 100644 --- a/.github/workflows/reusable-nox.yml +++ b/.github/workflows/reusable-nox.yml @@ -11,6 +11,10 @@ jobs: fail-fast: false matrix: include: + # Inputs: + # session: name of session + # python-versions: comma-separated list of Python versions to install + # extra-args (optional): extra arguments to pass to nox session. - session: static python-versions: "3.11" - session: formatters_check @@ -23,6 +27,11 @@ jobs: python-versions: "3.11" - session: "checkers(docs-build)" python-versions: "3.11" + - session: "actionlint" + python-versions: "3.11" + - session: "pip-compile" + extra-args: "--check" + python-versions: "3.11" name: "Run nox ${{ matrix.session }} session" steps: - name: Check out repo @@ -36,4 +45,6 @@ jobs: nox -e clone-core - name: "Run nox -e ${{ matrix.session }}" run: | - nox -e "${{ matrix.session }}" + # Using GHA expression interpolation is fine here, + # as we control all the inputs. + nox -e "${{ matrix.session }}" -- ${{ matrix.extra-args }} diff --git a/.github/workflows/reusable-pip-compile.yml b/.github/workflows/reusable-pip-compile.yml index 0fcae147eec..5fcb9db3915 100644 --- a/.github/workflows/reusable-pip-compile.yml +++ b/.github/workflows/reusable-pip-compile.yml @@ -88,12 +88,15 @@ jobs: base_branch: "${{ inputs.base-branch }}" pr_branch: "${{ inputs.pr-branch }}" message: "${{ inputs.message }}" + pr_title: "[${{ inputs.base-branch }}] ${{ inputs.message }}" changed_files: "${{ inputs.changed-files }}" labels: "${{ inputs.labels }}" run: | set -x git diff || : + # shellcheck disable=SC2086 git add ${changed_files} + # shellcheck disable=SC2086 if git diff-index --quiet HEAD ${changed_files}; then echo "Nothing to do!" exit @@ -105,7 +108,7 @@ jobs: then command=(gh pr create --base "${base_branch}" - --title "${message}" + --title "${pr_title}" --body "" --label dependency_update ) diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 00000000000..5bad5a6c6c2 --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,49 @@ +--- +name: Sync tags with ansible-core releases + +"on": + workflow_dispatch: + inputs: + dry-run: + type: boolean + default: false + description: "Select to run the tag script in dry-run mode" + schedule: + - cron: "0 * * * *" # Hourly + +jobs: + tag: + runs-on: "ubuntu-latest" + environment: github-bot + permissions: + contents: write + steps: + - name: Generate temp GITHUB_TOKEN + id: create_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.BOT_APP_ID }} + private_key: ${{ secrets.BOT_APP_KEY }} + - name: Check out us + uses: actions/checkout@v4 + with: + path: ansible-documentation + fetch-depth: 0 + token: "${{ steps.create_token.outputs.token }}" + - name: Check out core + uses: actions/checkout@v4 + with: + repository: ansible/ansible + path: ansible + fetch-depth: 0 + - name: Setup nox + uses: wntrblm/nox@2024.04.15 + with: + python-versions: "3.12" + - name: Set up git committer + run: | + ./hacking/get_bot_user.sh "ansible-documentation-bot" "Ansible Documentation Bot" + working-directory: ansible-documentation + - name: Run tag script + run: nox -s tag -- tag ${{ inputs.dry-run && '--no-push' || '' }} + working-directory: ansible-documentation diff --git a/.gitignore b/.gitignore index 680520eb406..fe1eaed9155 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ docs/docsite/rst/index.rst docs/docsite/rst/cli/ansible-*.rst docs/docsite/rst/cli/ansible.rst docs/docsite/rst/dev_guide/collections_galaxy_meta.rst +docs/docsite/rst/dev_guide/testing/sanity/index.rst.new docs/docsite/rst/dev_guide/index.rst docs/docsite/rst/modules/*.rst docs/docsite/rst/collections/*.rst @@ -90,6 +91,8 @@ Vagrantfile /lib/ansible_base.egg-info/ # First used in the `devel` branch during Ansible 2.11 development. /lib/ansible_core.egg-info/ +# First used in the `devel` branch during Ansible 2.18 development. +/ansible_core.egg-info/ # vendored lib dir lib/ansible/_vendor/* !lib/ansible/_vendor/__init__.py @@ -97,8 +100,6 @@ lib/ansible/_vendor/* /test/integration/cloud-config-*.* !/test/integration/cloud-config-*.*.template .python-version -/hacking/tests/selinux/*.mod -/hacking/tests/selinux/*.pp # Release directory packaging/release/ansible_release /.cache/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 713b64960a3..75c8f4cf037 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,3 +9,41 @@ By contributing to ansible-documentation, you agree to the Developer Certificate Origin (DCO). This document was created by the Linux Kernel community and is a simple statement that you, as a contributor, have the legal right to make the contribution. See the [DCO](DCO) file for details. + +## Backport labels + +This repository has `stable-.` branches to correspond to each +ansible-core major release. +ansible-documentation commmitters can add `backport-.` labels to +pull requests so the [Patchback bot] will automatically create backport pull +requests after the original PR is merged. +Small fixes or cleanups should at least be backported to the latest +stable branch. +If a PR should stay on the `devel` and not be backported—for example, if the +documentation update addresses an ansible-core change that only occurred on the +ansible-core development branch—maintainers should instead add the +`no_backport` label. + +[Patchback bot]: https://github.com/apps/patchback + +## Merging pull requests + +This repository has two ways to apply pull requests: +`Squash and merge` and `Create a merge commit`. +`Squash and merge` squashes all of the commits from the PR's base branch into a +single commit and then applies that commit on top of the target branch in the +upstream ansible-documentation repository. +`Create a merge commit` uses `git merge` which preserves the entire commit +history from the base branch. +This may not be desired if, for example, there are a lot of fixup commits with +nondescriptive commit messages. +For other more complex changes—especially those that involve the docs build +scripts or other tooling code—it may be desirable to preserve the full commit +history to keep logical changes separated and avoid clobbering useful metadata +so the Git history remains useful in the future. The maintainer who merges the +PR can select the merge mode through the dropdown menu next to the green merge +button. +Generally, maintainers should apply PRs using `Squash and merge`. +`Create a merge commit` should be used if the PR author added the +`merge_commit` label or the maintainer otherwise assesses that merge mode makes +sense for the change in question. diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 00000000000..7d1425cc206 --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,82 @@ +# Maintainers guide + +Find details about maintaining the `ansible-documentation` repository. +Note that maintainers have privileged access to the repository to perform special functions such as branching for new versions and preparing Ansible documentation for publishing. +If you're interested in becoming a maintainer, or want to get in touch with us, please join us on Matrix at [#docs:ansible.im](https://matrix.to/#/#docs:ansible.im). +We have weekly meetings on Matrix every Tuesday. +See [the Ansible calendar](https://forum.ansible.com/upcoming-events) for meeting details. + +## Branching for new stable versions + +The branching strategy for this repository mirrors the [`ansible/ansible`](https://github.com/ansible/ansible) repository. +When a new `stable-*` branch is created in the core repository, a corresponding branch in the `ansible-documentation` repository needs to be created. +There are various other changes that should occur around the same time that the new stable branch is cut. + +### Creating stable branches + +Create new stable branches as follows: + +```bash +# Make sure your checkout is up to date. +git fetch upstream + +# Create a new stable branch against the devel branch. +git checkout -b stable-2.18 upstream/devel + +# Push the new stable branch to the repository. +git push upstream stable-2.18 +``` + +After the new stable branch is created, the following changes should be committed as pull requests to the new stable branch: + +* Update the core branch in the `docs/ansible-core-branch.txt` file. +* Remove devel-only tooling. +* Update Python versions in the support matrix. + +### Updating the core branch + +The script that grafts portions of the core repository uses the `docs/ansible-core-branch.txt` file to specify which branch to clone. +When a new stable branch is created, modify the file so that it specifies the correct version. + +```bash +sed -i 's/devel/stable-2.18/g' docs/ansible-core-branch.txt +``` + +### Removing devel-only tooling + +There are some scripts and other tooling artefacts that should be on the `devel` branch only. +After creating a new stable branch, remove the appropriate files and references. + +```bash +# Remove the following workflow files, the tagger script, and tagger requirements. +git rm -r .github/workflows/pip-compile-dev.yml .github/workflows/pip-compile-docs.yml .github/workflows/reusable-pip-compile.yml .github/workflows/tag.yml hacking/tagger tests/tag.* +``` + +Next, remove references to the tagger dependencies as follows: + +1. Remove the reference from the typing input file. + + ```bash + sed -i '/-r tag.in/d' tests/typing.in + ``` + +2. Clean up the typing lockfile. + + ```bash + nox -s pip-compile -- --no-upgrade + ``` + +3. Open `noxfile.py` and remove `"hacking/tagger/tag.py",` from the `LINT_FILES` tuple. + +### Update Python versions in the support matrix + +The minimum supported Python version changes with each Ansible core version. +This requires an update to the support matrix documentation after a new stable branch is created to reflect the appropriate Control Node Python versions. + +Uncomment the new stable version from the `ansible-core support matrix` section in the `docs/docsite/rst/reference_appendices/release_and_maintenance.rst` file. +Submit a PR with the changes and request a core team review. + +### Updating the tagger script + +Update the list of active branches in the `hacking/tagger/tag.py` script on the `devel` branch. +Add the new stable branch and remove the lowest version from the `DEFAULT_ACTIVE_BRANCHES` tuple. diff --git a/README.md b/README.md index e9392b53ba5..3bb09ee9c03 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,11 @@ The `nox` configuration also contains session to run automated docs checkers. nox -s lint ``` + The `actionlint` linter that is run as part of the `lint` session requires + `podman` or `docker` to be installed. + If both container engines are installed, `podman` is preferred. + Set `CONTAINER_ENGINE=docker` to change this behavior. + ### Checking spelling Use [`codespell`](https://github.com/codespell-project/codespell) to check for common spelling mistakes in the documentation source. @@ -109,7 +114,7 @@ The lock files contain tested dependencies that are automatically updated on a w If you'd like to use untested dependencies, set `PINNED=false` as in the following example: -``` +```bash PINNED=false nox -s "checkers(docs-build)" ``` @@ -136,3 +141,27 @@ If you do not have Python 3.10 installed, you can use root-less podman with a Py ```bash podman run --rm --tty --volume "$(pwd):/mnt:z" --workdir /mnt docker.io/library/python:3.10 bash -c 'pip install nox ; nox -s pip-compile' ``` + +## Creating release tags + +When a tag is created in the [`ansible/ansible`](https://github.com/ansible/ansible) repository for a release or release candidate, a corresponding tag should be created in this `ansible-documentation` repository. + +First, ensure that you have the [`ansible/ansible`](https://github.com/ansible/ansible) and [`ansible/ansible-documentation`](https://github.com/ansible/ansible-documentation) repositories checked out. +The tool assumes that both checkouts have the same parent directory. You can set different paths to your checkouts with the `--docs` and `--core` options if you have them set up another way. + +Next, run the `tag` `nox` session. + +This will determine any missing `ansible-core` tags and create them in `ansible-documentation` if needed, exiting normally otherwise: + +``` bash +# The tagger scripts assumes "origin" as the upstream remote. +nox -s tag + +# If you use a different upstream remote, specify the name. +nox -s tag -- --remote tag + +# If your core repo is not in the same filesystem location, specify the path. +nox -s tag -- --core tag +``` + +See `nox -s tag -- --help` for extended options. diff --git a/docs/bin/clone-core.py b/docs/bin/clone-core.py index 4ef29087948..5412aca15b6 100755 --- a/docs/bin/clone-core.py +++ b/docs/bin/clone-core.py @@ -18,11 +18,36 @@ DEFAULT_BRANCH = (ROOT / "docs" / "ansible-core-branch.txt").read_text().strip() DEFAULT_ANSIBLE_CORE_REPO = "https://github.com/ansible/ansible" +"""Directories to copy from ansible-core into the ansible-documentation tree""" +KEEP_DIRS = ( + "bin", + "lib", + "packaging", + "test/lib", +) + +"""Files to copy from ansible-core into the ansible-documentation tree""" +KEEP_FILES = ( + "MANIFEST.in", + "pyproject.toml", + "requirements.txt", +) + +"""Files to remove after cloning ansible-core""" +REMOVE_FILES = ( + # See https://github.com/ansible/ansible/commit/68515abf97dfc769c9aed2ba457ed7b8b2580a5c + # ansible-core removed setup.py and setup.cfg so we need to make sure to + # remove those when syncing the new version. + "setup.py", + "setup.cfg", +) + @dataclasses.dataclass() class Args: branch: str | None repo: str + check: bool def parse_args(args: list[str] | None = None) -> Args: @@ -47,24 +72,45 @@ def parse_args(args: list[str] | None = None) -> Args: help="ansible-core repository to check out. Default: %(default)s", default=DEFAULT_ANSIBLE_CORE_REPO, ) + parser.add_argument( + "--check", + action=argparse.BooleanOptionalAction, + help="Ensure that the necessary files exist." + " If they don't clone new ones from ansible-core." + " Otherwise, leave the existing versions alone.", + ) return Args(**vars(parser.parse_args(args))) +def remove_files(directory: pathlib.Path = pathlib.Path.cwd()) -> list[pathlib.Path]: + removed: list[pathlib.Path] = [] + for file in REMOVE_FILES: + path = directory / file + if path.is_file(): + print(f"Removing {file!r} ...") + path.unlink() + removed.append(path) + return removed + + def main(args: Args) -> None: - keep_dirs = [ - "bin", - "lib", - "packaging", - "test/lib", - ] - - keep_files = [ - "MANIFEST.in", - "pyproject.toml", - "requirements.txt", - "setup.cfg", - "setup.py", - ] + # Start by removing extra files + removed_files = remove_files() + + if ( + # Check is enabled + args.check + # All core files exist + and all(pathlib.Path(file).is_file() for file in KEEP_FILES) + # All core directories exist + and all(pathlib.Path(directory).is_dir() for directory in KEEP_DIRS) + # If any extra files are still around, that means our checkout is out + # of date and needs to be refreshed. + and not removed_files + ): + print("The necessary core files already exist.") + print("Run 'nox -e clone-core' without --check to update the core files.") + return with tempfile.TemporaryDirectory() as temp_dir: cmd: list[str] = ["git", "clone", args.repo, "--depth=1"] @@ -73,7 +119,7 @@ def main(args: Args) -> None: cmd.append(temp_dir) subprocess.run(cmd, check=True) - for keep_dir in keep_dirs: + for keep_dir in KEEP_DIRS: src = pathlib.Path(temp_dir, keep_dir) dst = pathlib.Path.cwd() / keep_dir @@ -86,7 +132,7 @@ def main(args: Args) -> None: (dst / ".gitignore").write_text("*") - for keep_file in keep_files: + for keep_file in KEEP_FILES: src = pathlib.Path(temp_dir, keep_file) dst = pathlib.Path.cwd() / keep_file diff --git a/docs/docsite/.templates/banner.html b/docs/docsite/.templates/banner.html index 7f0dc156f45..28280bcbb8c 100644 --- a/docs/docsite/.templates/banner.html +++ b/docs/docsite/.templates/banner.html @@ -16,13 +16,12 @@ var banner = ''; var extra_banner = ''; /*use extra_banner for when we want something extra, like a survey or Community Day notice */ - /* var extra_banner = + var extra_banner = '
' + '

' + - 'Discuss Ansible in the new Ansible Forum!' + + 'We want to hear from you! Help us gain insights into the state of the Ansible ecosystem by taking the Ansible Project Survey 2024.' + '

' + '
'; - */ // Create a banner if we're not on the official docs site if (location.host == "docs.testing.ansible.com") { document.write('
' + diff --git a/docs/docsite/Makefile b/docs/docsite/Makefile index afcfe4bab7f..8fa6373fca5 100644 --- a/docs/docsite/Makefile +++ b/docs/docsite/Makefile @@ -89,14 +89,14 @@ gettext: gettext_structure gettext_generate_rst generate-po: ifeq ($(LANGUAGES),) - @echo 'LANGUAGES is not defined. It is mandatory. LANGUAGES should be a comma separated list of languages to support. (Exampe: fr,es)' + @echo 'LANGUAGES is not defined. It is mandatory. LANGUAGES should be a comma separated list of languages to support. (Example: fr,es)' else (cd docs/docsite/; sphinx-intl update -w 0 -d rst/locales -p "$(POTDIR)" -l $(LANGUAGES)) endif needs-translation: ifeq ($(LANGUAGES),) - @echo 'LANGUAGES is not defined. It is mandatory. LANGUAGES should be a comma separated list of languages to support. (Exampe: fr,es)' + @echo 'LANGUAGES is not defined. It is mandatory. LANGUAGES should be a comma separated list of languages to support. (Example: fr,es)' else (cd docs/docsite/; sphinx-intl stat -d rst/locales -l $(LANGUAGES) | grep -E ' [1-9][0-9]* (fuzzy|untranslated)' | sort) endif diff --git a/docs/docsite/rst/collections_guide/collections_installing.rst b/docs/docsite/rst/collections_guide/collections_installing.rst index 50366b41928..7c346bbb882 100644 --- a/docs/docsite/rst/collections_guide/collections_installing.rst +++ b/docs/docsite/rst/collections_guide/collections_installing.rst @@ -11,12 +11,67 @@ Installing collections in containers ------------------------------------ You can install collections with their dependencies in containers known as Execution Environments. -See `Getting started with Execution Environments `_ for details. +See :ref:`getting_started_ee_index` for details. Installing collections with ``ansible-galaxy`` ---------------------------------------------- -.. include:: ../shared_snippets/installing_collections.txt + +By default, ``ansible-galaxy collection install`` uses https://galaxy.ansible.com as the Galaxy server (as listed in the +:file:`ansible.cfg` file under :ref:`galaxy_server`). You do not need any further configuration. +By default, Ansible installs the collection in ``~/.ansible/collections`` under the ``ansible_collections`` directory. + +See :ref:`Configuring the ansible-galaxy client ` if you are using any other Galaxy server, such as Red Hat Automation Hub. + +To install a collection hosted in Galaxy: + +.. code-block:: bash + + ansible-galaxy collection install my_namespace.my_collection + +To upgrade a collection to the latest available version from the Galaxy server you can use the ``--upgrade`` option: + +.. code-block:: bash + + ansible-galaxy collection install my_namespace.my_collection --upgrade + +You can also directly use the tarball from your build: + +.. code-block:: bash + + ansible-galaxy collection install my_namespace-my_collection-1.0.0.tar.gz -p ./collections + +You can build and install a collection from a local source directory. The ``ansible-galaxy`` utility builds the collection using the ``MANIFEST.json`` or ``galaxy.yml`` +metadata in the directory. + +.. code-block:: bash + + ansible-galaxy collection install /path/to/collection -p ./collections + +You can also install multiple collections in a namespace directory. + +.. code-block:: text + + ns/ + ├── collection1/ + │ ├── MANIFEST.json + │ └── plugins/ + └── collection2/ + ├── galaxy.yml + └── plugins/ + +.. code-block:: bash + + ansible-galaxy collection install /path/to/ns -p ./collections + +.. note:: + The install command automatically appends the path ``ansible_collections`` to the one specified with the ``-p`` option unless the + parent directory is already in a folder called ``ansible_collections``. + + +When using the ``-p`` option to specify the install path, use one of the values configured in :ref:`COLLECTIONS_PATHS`, as this is +where Ansible itself will expect to find collections. If you don't specify a path, ``ansible-galaxy collection install`` installs +the collection to the first path defined in :ref:`COLLECTIONS_PATHS`, which by default is ``~/.ansible/collections`` .. _installing_signed_collections: @@ -54,7 +109,7 @@ You can also include signatures in addition to those provided by the distributio ansible-galaxy collection install my_namespace.my_collection --signature https://examplehost.com/detached_signature.asc --keyring ~/.ansible/pubring.kbx -GnuPG verification only occurs for collections installed from a distribution server. User-provided signatures are not used to verify collections installed from git repositories, source directories, or URLs/paths to tar.gz files. +GnuPG verification only occurs for collections installed from a distribution server. User-provided signatures are not used to verify collections installed from Git repositories, source directories, or URLs/paths to tar.gz files. You can also include additional signatures in the collection ``requirements.yml`` file under the ``signatures`` key. @@ -114,12 +169,40 @@ Downloading a collection for offline use .. include:: ../shared_snippets/download_tarball_collections.txt +.. _collection_local_install: + +Installing collections adjacent to playbooks +-------------------------------------------- + +You can install collections locally next to your playbooks inside your project instead of in a global location on your system or on AWX. + +Using locally installed collections adjacent to playbooks has some benefits, such as: + +* Ensuring that all users of the project use the same collection version. +* Using self-contained projects makes it easy to move across different environments. Increased portability also reduces overhead when setting up new environments. This is a benefit when deploying Ansible playbooks in cloud environments. +* Managing collections locally lets you version them along with your playbooks. +* Installing collections locally isolates them from global installations in environments that have multiple projects. + +Here is an example of keeping a collection adjacent to the current playbook, under a ``collections/ansible_collections/`` directory structure. + +.. code-block:: text + + ./ + ├── play.yml + ├── collections/ + │ └── ansible_collections/ + │ └── my_namespace/ + │ └── my_collection/ + + +See :ref:`collection_structure` for details on the collection directory structure. + Installing a collection from source files ----------------------------------------- .. include:: ../shared_snippets/installing_collections_file.rst -Installing a collection from a git repository +Installing a collection from a Git repository --------------------------------------------- .. include:: ../shared_snippets/installing_collections_git_repo.txt diff --git a/docs/docsite/rst/command_guide/cheatsheet.rst b/docs/docsite/rst/command_guide/cheatsheet.rst index 3e9402e3da9..cb55b5366e7 100644 --- a/docs/docsite/rst/command_guide/cheatsheet.rst +++ b/docs/docsite/rst/command_guide/cheatsheet.rst @@ -105,3 +105,20 @@ Runs ``ansible localhost``- on your local system. "cache_updated": false, "changed": false #... + +ansible-doc +=========== + +* Show plugin names and their source files: + +.. code-block:: bash + + ansible-doc -F + #... + +* Show available plugins: + +.. code-block:: bash + + ansible-doc -t module -l + #... \ No newline at end of file diff --git a/docs/docsite/rst/command_guide/index.rst b/docs/docsite/rst/command_guide/index.rst index 4027e3493d7..ca5b41d0e88 100644 --- a/docs/docsite/rst/command_guide/index.rst +++ b/docs/docsite/rst/command_guide/index.rst @@ -25,5 +25,5 @@ Ansible provides ad hoc commands and several utilities for performing various op `Ansible Navigator `_ A command-line tool and a TUI that provides a convenient user interface for most of the native Ansible command-line utilities and allows to run Ansible automation content - inside containers (`Execution Environments `_) + inside containers (:ref:`Execution Environments`) diff --git a/docs/docsite/rst/command_guide/intro_adhoc.rst b/docs/docsite/rst/command_guide/intro_adhoc.rst index 6e1810fa197..91b2bc286ef 100644 --- a/docs/docsite/rst/command_guide/intro_adhoc.rst +++ b/docs/docsite/rst/command_guide/intro_adhoc.rst @@ -224,7 +224,5 @@ Now that you understand the basic elements of Ansible execution, you are ready t Browse existing collections, modules, and plugins :ref:`working_with_playbooks` Using Ansible for configuration management & deployment - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/community/advanced_index.rst b/docs/docsite/rst/community/advanced_index.rst index b07b72ff17a..6ccc9269b90 100644 --- a/docs/docsite/rst/community/advanced_index.rst +++ b/docs/docsite/rst/community/advanced_index.rst @@ -4,7 +4,7 @@ Advanced Contributor Guide ********************************************** -This guide focuses on contributors who are committers, GitHub admins, or release managers. +This guide focuses on contributors who are committers, GitHub admins, release managers, or Ansible ecosystem project developers. .. toctree:: :maxdepth: 1 @@ -12,3 +12,4 @@ This guide focuses on contributors who are committers, GitHub admins, or release committer_guidelines release_managers github_admins + ecosystem_project_resources diff --git a/docs/docsite/rst/community/collection_contributors/collection_package_removal.rst b/docs/docsite/rst/community/collection_contributors/collection_package_removal.rst new file mode 100644 index 00000000000..01e9da48a9e --- /dev/null +++ b/docs/docsite/rst/community/collection_contributors/collection_package_removal.rst @@ -0,0 +1,245 @@ +.. + THIS DOCUMENT IS OWNED BY THE ANSIBLE COMMUNITY STEERING COMMITTEE. ALL CHANGES MUST BE APPROVED BY THE STEERING COMMITTEE! + For small changes (fixing typos, language errors, etc.) create a PR and ping @ansible/steering-committee. + For other changes, create a :ref:`topic` on the Forum to discuss the changes. + (Creating a draft PR for this file and mentioning it in the community topic is also OK.) + +.. _removal_from_ansible: + +***************************************************** +Ansible Community Package Collections Removal Process +***************************************************** + +.. contents:: + :local: + +Overview +======== + +Sometimes the Ansible community removes a collection from the Ansible package for stability, legal, or security reasons. This document describes why we might remove a collection from the `Ansible community package `_ (`build data `_). + +In cases of emergency (for example, a serious security vulnerability that is not fixed in a collection) the :ref:`Ansible Community Engineering Steering Committee` can vote on emergency exceptions. In most cases, we follow the rules listed on this page. + +General processes +================= + +The general process of removing a collection follows these steps: + +#. Announcing an upcoming removal of a collection. +#. Removing the collection. +#. When appropriate, re-adding the collection. + + +.. _announce_removal: + +Announcing upcoming removal +--------------------------- + +#. Announce upcoming removal in the Ansible changelog (``https://github.com/ansible-community/ansible-build-data/blob/main//changelog.yaml``). + See the following link for an `example on how to add changelog entries to the Ansible changelog `__. +#. Announce upcoming removal in the collection's issue tracker if possible. +#. Announce upcoming removal in The Bullhorn. + +.. _remove_collection: + +Removing a collection +--------------------- + +To remove a collection from Ansible version X.0.0: + +#. Remove from ``ansible.in`` (``https://github.com/ansible-community/ansible-build-data/blob/main//ansible.in``). +#. Remove from ``collection-meta.yaml`` (``https://github.com/ansible-community/ansible-build-data/blob/main//collection-meta.yaml``). +#. Document actual removal for the first/next alpha of Ansible X.0.0 in the Ansible changelog (``https://github.com/ansible-community/ansible-build-data/blob/main//changelog.yaml``). + See the following link for an `example on how to add changelog entries to the Ansible changelog `__. + +.. _readd_collection: + +Re-adding a collection +---------------------- + +Re-adding a collection to Ansible works the same as adding it in the first place. See the `process of adding a new collection to Ansible `_ for reference. + +#. Re-add collection to ``ansible.in`` (``https://github.com/ansible-community/ansible-build-data/blob/main//ansible.in``). +#. Re-add collection to ``collection-meta.yaml`` (``https://github.com/ansible-community/ansible-build-data/blob/main//collection-meta.yaml``). +#. If the removal was announced in the Ansible changelog for a version that has not yet been released (``https://github.com/ansible-community/ansible-build-data/blob/main//changelog.yaml``), remove the announcement. + +Broken collections +================== + +The community can remove a collection from the Ansible community package if the collection is broken. + +Identifying and removing a broken collection +-------------------------------------------- + +Conditions for removal +~~~~~~~~~~~~~~~~~~~~~~ + +A collection is considered broken if one of the following conditions is true: + +#. It depends on another collection included in X.0.0 but does not work with the actual version of it that is included, and there is no content in the collection that still works. + +We remove broken collections from Ansible (X+1).0.0 under the following conditions: + +#. The collection seems to be unmaintained and nobody fixes the problems. +#. The plan to remove the collection in the next major Ansible release is publicized at least two months before the (X+1).0.0 release, and at least one month before the first (X+1).0.0 beta release (feature freeze). + +Process +~~~~~~~ + +The announcement mentioned below must state the reasons for the proposed removal and alert maintainers and the Ansible community that, to prevent the removal, the collection urgently needs new maintainers who can fix the problems. + +#. `Announce upcoming removal in Ansible X+1 `_. +#. `Remove collection from Ansible X+1 `_. + +Canceling removal of a broken collection +----------------------------------------- + +Conditions +~~~~~~~~~~ + +#. The issues have to be fixed and a new release (bugfix, minor or major) has to be made before the Ansible X+1 feature freeze. +#. Someone has to promise to maintain the collection and prevent a similar situation at least for some time. + +Process +~~~~~~~ + +#. Update the removal issue in the collection's issue tracker and close the issue. +#. Announce canceled removal in The Bullhorn. +#. `Re-add collection to Ansible X+1 `_. + +Re-adding collection to Ansible +------------------------------- + +Conditions +~~~~~~~~~~ + +Conditions under which the collections can be re-included in the Ansible package without going through the `full inclusion process `_: + +#. The issues have to be fixed and a new release has to be made before the Ansible X+2 feature freeze. +#. Someone has to promise to maintain the collection and prevent a similar situation at least for some time. + +Process +~~~~~~~ + +#. Follow `regular process of adding a new collection to Ansible `_. + +Unmaintained collections +======================== + +Removing a collection that has been explicitly deprecated or abandoned by its (former) maintainers +-------------------------------------------------------------------------------------------------- + +Process +~~~~~~~ + +If the current major release is X and there hasn't been a feature freeze release of the next major version X+1, remove the collection from Y=(X+1).0.0. +If there already has been a feature freeze release of the next major version X+1, remove the collection from Y=(X+2).0.0. + +#. `Announce upcoming removal from the Y Ansible release `_. +#. `Remove collection from the Y Ansible release `_. + +See `the example pull request `_ in the ``ansible-build-data`` repository to learn how to remove the collection. + +Identifying and removing an unmaintained collection that has not been deprecated by its maintainers +--------------------------------------------------------------------------------------------------- + +Conditions for removal +~~~~~~~~~~~~~~~~~~~~~~ + +A collection is considered unmaintained if multiple of the following conditions are satisfied: + +#. There has been no maintainer's activity in the collection repository for several months (for example, pull request merges and releases). +#. CI has stopped passing (or even has not been running) for several months. +#. Bug reports and bugfix PRs start piling up without being reviewed. + +There is no complete formal definition of an unmaintained collection. + +Process +~~~~~~~ + +#. The appearance that the collection is no longer maintained and might be removed from the Ansible package has to be announced both in The Bullhorn and in the collection's issue tracker. +#. At least four weeks after the notice appeared in The Bullhorn and the collection's issue tracker, the Ansible Community Engineering Steering Committee (SC) must look at the collection and vote that it considers it unmaintained. The vote must be open for at least one week. +#. If the SC does not vote that the collection seems to be unmaintained, the process is stopped. The issue needs to be updated accordingly. +#. If X.0.0 will be released next, set Y=X+1. If X.0.0 has already been released, but (X+1).0.0 has not yet been released, set Y=X+2. +#. `Announce upcoming removal from Ansible Y `_. +#. `Remove collection from Ansible Y `_. + +Canceling removal of an unmaintained collection +------------------------------------------------ + +Conditions +~~~~~~~~~~ + +#. Ansible Y has not yet been released. +#. One or multiple maintainers step up, or return, to clean up the collection's state. +#. There have been concrete results made by new maintainers (for example, CI has been fixed, the collection has been released, pull request authors have got meaningful feedback). + +Process +~~~~~~~ + +#. The Steering Committee votes on whether the result is acceptable. +#. A negative vote must come with a good explanation why the clean up work has not been sufficient. In that case, this process stops. +#. If the Steering Committee does not vote against still removing the collection (this includes the case that the vote did not reach quorum), proceed as follows. +#. `Re-add collection to Ansible Y `_. + +Re-adding collection to Ansible +------------------------------- + +There is no simplified process. Once the collection has been removed from Ansible Y.0.0, it needs to go through the full inclusion process to be re-added to the Ansible package. Exceptions are only possible if the Steering Committee votes on them. The Steering Committee can approve or deny a fast re-entry without going through the full review process. + +Collections not satisfying the Collection requirements +====================================================== + +A collection can be removed from the package if it violates one or more of the :ref:`Collection requirements` without resolving the violations within the time allowed. + +This section is not applicable to cases of broken or unmaintained collections. Instead, see the corresponding paragraphs of this document. + +Identifying and removing a collection +------------------------------------- + +Conditions for removal +~~~~~~~~~~~~~~~~~~~~~~ + +#. A collection violates one or more of the :ref:`Collection requirements`. +#. Collection maintainers have not fixed the violations and have not released a fixed version of the collection within the time period established by this document. + +Process +~~~~~~~ + +#. Any community member who finds a collection that violates one or more of the :ref:`Collection requirements` may file an issue against said collection's repository. If the reporter is unsure whether something constitutes a violation or believes that the apparently violated guideline is unclear, they should consult with the steering committee by filing a :ref:`community topic` before proceeding. +#. The issue filed against the collection's repository should include the following information: + + * References to the corresponding :ref:`Collection requirements` the collection violates. + * Actions collection maintainers need to do to make the collection comply with the requirements. + +#. A default term for the collection to solve the issue is four weeks since the issue was created. It can vary depending on a requirement violated, SC opinions or other circumstances. +#. If the violation is not fixed or there is a disagreement between the reporter and the maintainers, the reporter or another person creates a :ref:`community topic`. +#. Two SC members check the reported circumstances and confirm in the topic that the violation is present from their point of view, and is one that must be fixed. +#. The Community and SC vote on considering the collection violating the requirements and removing it from the package. The vote must be open for at least one week. +#. If SC votes that the collection does NOT violate the requirements, the process is stopped. The issue needs to be updated accordingly. +#. If X.0.0 will be released next, set Y=X+1. If X.0.0 has already been released, but (X+1).0.0 has not yet been released, set Y=X+2. +#. Announce upcoming removal from Ansible Y in the original issue in the collection's repository. +#. `Announce upcoming removal from Ansible Y `_. +#. `Remove collection from Ansible Y `_. + +Canceling removal +------------------ + +Conditions +~~~~~~~~~~ + +#. Ansible Y has not yet been released. +#. All the requirements violations have been fixed. + +Process +~~~~~~~ + +#. SC votes on whether the result is acceptable. +#. A negative vote must come with a good explanation why the actions done by collection maintainers have not been sufficient. +#. If SC does not vote against the removal of the collection (this includes the case that the vote did not reach quorum), the removal will continue. +#. If SC votes to cancel the removal, `re-add collection to Ansible Y `_. + +Re-adding collection to Ansible +------------------------------- + +There is no simplified process. Once the collection has been removed from Ansible Y.0.0, it needs to go through the full inclusion process to be re-added to the Ansible package. Exceptions are only possible if SC votes on them. SC can approve or deny a fast re-entry without going through the full review process. diff --git a/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst b/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst index 0eae079863c..1aaece95ee8 100644 --- a/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst +++ b/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst @@ -255,7 +255,7 @@ Releasing when more minor versions are expected The format is reStructuredText but not a list as for regular changelog fragments. This text will be inserted into the changelog. - Add to git and commit. + Add to Git and commit. 5. Generate the changelogs. diff --git a/docs/docsite/rst/community/collection_contributors/collection_requirements.rst b/docs/docsite/rst/community/collection_contributors/collection_requirements.rst index 581ae8d60fc..1784b702ddd 100644 --- a/docs/docsite/rst/community/collection_contributors/collection_requirements.rst +++ b/docs/docsite/rst/community/collection_contributors/collection_requirements.rst @@ -1,7 +1,7 @@ .. THIS DOCUMENT IS OWNED BY THE ANSIBLE COMMUNITY STEERING COMMITTEE. ALL CHANGES MUST BE APPROVED BY THE STEERING COMMITTEE! For small changes (fixing typos, language errors, etc.) create a PR and ping @ansible/steering-committee. - For other changes, create a discussion in https://github.com/ansible-community/community-topics/ to discuss the changes. + For other changes, create a :ref:`topic` on the Forum to discuss the changes. (Creating a draft PR for this file and mentioning it in the community topic is also OK.) .. _collections_requirements: @@ -10,123 +10,157 @@ Ansible community package collections requirements ************************************************** -This section describes the requirements for maintainers of Ansible community collections in the `ansible-collections `_ repository or included in the Ansible community package. - .. contents:: :local: - Overview ======== -This section provides help, advice, and guidance on making sure your collections are correct and ready for inclusion in the Ansible community package. +This document describes the requirements for maintainers of Ansible community collections included in the Ansible community package. All inclusion candidates and already included collections must meet the criteria marked with ``MUST`` in this document. -.. note:: +You can also find these requirements on the `Collection inclusion criteria checklist `_. - `Inclusion of a new collection `_ in the Ansible package is ultimately at the discretion of the :ref:`community_steering_committee`. Every rejected candidate will get feedback. Differences of opinion should be taken to a dedicated `Community Topic `_ for discussion and a final vote. +Every rejected candidate will get feedback from the :ref:`community_steering_committee` based on a decision made in a dedicated :ref:`community topic`. Feedback and communications ============================== -As with any project it is very important that we get feedback from users, contributors, and maintainers. You can get feedback and help as follows: - -* Discussing in the `#community:ansible.com Matrix room `_, which is bridged with the ``#ansible-community`` channel on Libera.Chat IRC. See the :ref:`Ansible Communication Guide ` for details. -* Discussing in the `Community Working Group meeting `_. -* Creating `GitHub Issues `_ in the ``ansible-collections`` repository. +Any feedback and help is very welcome. Please create a :ref:`community topic` or bring your questions to the :ref:`community meeting`. Keeping informed ================ -You should subscribe to: +To track changes that affect collections: + +* Join the `Collection Maintainers & Contributors forum group `_. +* Subscribe to the :ref:`bullhorn` Ansible contributor newsletter. + +.. _coll_wg_reqs: + +Communication and Working Groups +================================ + +Forum overview +-------------- + +The :ref:`ansible_forum` is our asynchronous default communication platform. + +In the context of organizing communication around Ansible collections, you need to understand the following notions: + +* `Tags `_: together with categories, tags are the main feature used in the Forum to organize conversations around specific topics. Most Ansible projects have one or more associated tags. For Ansible collections the main tag name is usually the technology the collection targets: examples include `kubernetes `_ for ``kubernetes.core``, `windows `_ for ``ansible.windows``, and `postgresql `_ for ``community.postgresql``. +* `Forum groups `_: groups allow you to organize users, manage permissions, have a working group page that provides related information, automatically subscribe members to tags, mention or message the whole group, and more. An example collection working group is the `PostgreSQL Ansible Collection Working Group `_. + +See the `Working Groups - things you can ask for! `_ forum topic for more details. + +Communication requirements +-------------------------- + +Your collection: + +* MUST have a corresponding public tag in the :ref:`ansible_forum` or reuse at least one of the `existing tags `_. + + * Multiple collections can share a tag if they cover similar topics; for example, ``amazon.aws`` and ``community.aws`` could both use the tag ``aws``. + + * In addition, the collection can :ref:`request a forum group`. If the collection requests or already has a group: + + * All related tags MUST be associated with the group. Everyone who joins the group is automatically subscribed to the tags. + * The group MUST be public and free to join by any forum user. + + * Use the `Requesting a tag/forum group `_ topic to request a tag and a forum group. + +* MUST have a communication section in its README with references to the :ref:`ansible_forum` similar to the `collection_template README.md `_. -* The `news-for-maintainers repository `_ to track changes that collection maintainers should be aware of. Subscribe only to issues if you want less traffic. -* The `Bullhorn `_ Ansible contributor newsletter. + * The section MUST contain at least a reference to the `Get Help `_ forum category, potentially including a tag in the URL. + * The section MUST contain information on which tags participants should use for collection-related topics. + * If the collection has a forum group, the section MUST contain a reference to the group. + * Descriptions of the references MUST welcome readers to join and participate. + * Maintainers of the collection SHOULD be subscribed to all associated tags and be members of all associated groups. + +* SHOULD have the ``Discussions`` GitHub feature disabled in favor of the Forum. + + * Unless GitHub discussions are currently used, this feature MUST be `disabled on the repo `_. .. _coll_infrastructure_reqs: Collection infrastructure ========================= +The following guidelines describe the required infrastructure for your collection: -The following guidelines describe the required structure for your collection: - -* MUST have a publicly available issue tracker that does not require a paid level of service to create an account or view issues. -* MUST have a Code of Conduct (CoC). +* MUST have a publicly available issue tracker that does not require a paid level of service to create an account and to create and view issues. +* MUST have the issue feature enabled in its repository and accept issue reports from anyone. +* MUST have a Code of Conduct (CoC) compatible with the :ref:`code_of_conduct`. - * The collection's CoC MUST be compatible with the :ref:`code_of_conduct`. - * The collections SHOULD consider using the Ansible CoC if they do not have a CoC that they consider better. - * The :ref:`Diversity and Inclusion working group ` may evaluate all CoCs and object to a collection's inclusion based on the CoCs contents. * The CoC MUST be linked from the ``README.md`` file, or MUST be present or linked from the ``CODE_OF_CONDUCT.md`` file in the collection root. + * The recommended approach is have a link to the Ansible :ref:`code_of_conduct`. + * If the collection has its own CoC, it MUST be evaluated by the :ref:`Diversity and Inclusion working group ` and confirmed as compatible with the :ref:`code_of_conduct`. -* MUST be published to `Ansible Galaxy `_. +* MUST be published to `Ansible Galaxy `_ with version 1.0.0 or later. +* MUST contain only objects that follow the :ref:`Licensing rules `. * SHOULD NOT contain any large objects (binaries) comparatively to the current Galaxy tarball size limit of 20 MB, For example, do not include package installers for testing purposes. * SHOULD NOT contain any unnecessary files such as temporary files. -* MUST only contain objects that follow the :ref:`Licensing rules `. - .. _coll_python_compatibility: Python Compatibility ==================== -A collection MUST be developed and tested using the below Python requirements as Ansible supports a wide variety of machines. - -The collection should adhere to the tips at :ref:`ansible-and-python-3`. +In addition to the Python requirements specified in this section, collections SHOULD adhere to the tips at :ref:`ansible-and-python-3`. .. _coll_python_reqs: Python Requirements ------------------- -Python requirements for a collection vary between **controller environment** and **other environment**. On the controller-environment, the Python versions required may be higher than what is required on the other-environment. While developing a collection, you need to understand the definitions of both the controller-environment and other-environment to help you choose Python versions accordingly: - -* controller environment: The plugins/modules always run in the same environment (Python interpreter, venv, host, and so on) as ansible-core itself. -* other environment: It is possible, even if uncommon in practice, for the plugins/modules to run in a different environment than ansible-core itself. - -One example scenario where the "even if" clause comes into play is when using cloud modules. These modules mostly run on the controller node but in some environments, the controller might run on one machine inside a demilitarized zone which cannot directly access the cloud machines. The user has to have the cloud modules run on a bastion host/jump server which has access to the cloud machines. - -An **eligible controller Python version** for a collection is a Python version that is supported on the controller side by at least one ansible-core version that the collection supports. Similarly, an **eligible target Python version** for a collection is a Python version that is supported on the target side by at least one ansible-core version that the collection supports. The eligible controller and target Python versions can be determined from the :ref:`ansible_core_support_matrix` and from the ``requires_ansible`` value in ``meta/runtime.yml`` in the collection. +Python requirements for a collection vary between **controller environment** and **other environment**. .. _coll_controller_req: Controller environment ~~~~~~~~~~~~~~~~~~~~~~ -Collections MUST support all eligible controller Python versions in the controller environment, unless required libraries do not support these Python versions. The :ref:`Steering Committee ` can grant other exceptions on a case-by-case basis. +* Collections MUST support all eligible controller Python versions in the controller environment, unless required libraries do not support these Python versions. The :ref:`Steering Committee ` can grant other exceptions on a case-by-case basis. -The collection MUST document all eligible controller Python versions that are not supported in the controller environment. See :ref:`coll_python_docs_req` for details. + * controller environment: the plugins/modules always run in the same environment (Python interpreter, venv, host, and so on) as ansible-core itself. + * eligible controller Python version: a Python version that is supported on the controller side by at least one ansible-core version that the collection supports. The eligible versions can be determined from the :ref:`ansible_core_support_matrix` and from the ``requires_ansible`` value in ``meta/runtime.yml`` in the collection. + +* The collection MUST document all eligible controller Python versions that are **not** supported in the controller environment. See :ref:`coll_python_docs_req` for details. Other environment ~~~~~~~~~~~~~~~~~ -Collections MUST support all eligible controller Python versions in the other environment, unless required libraries do not support these Python versions. The :ref:`Steering Committee ` can grant other exceptions on a case-by-case basis. +* Collections MUST support all eligible controller Python versions in the other environment, unless required libraries do not support these Python versions. The :ref:`Steering Committee ` can grant other exceptions on a case-by-case basis. -Collections SHOULD support all eligible target Python versions in the other environment. + * other environment: the plugins/modules run not in a controller environment. + * eligible target Python version: a Python version that is supported on the target side by at least one ansible-core version that the collection supports. The eligible versions can be determined from the :ref:`ansible_core_support_matrix` and from the ``requires_ansible`` value in ``meta/runtime.yml`` in the collection. -The collection MUST document all eligible target Python versions that are not supported in the other environment. See :ref:`coll_python_docs_req` for details. +* The collection MUST document all eligible target Python versions that are not supported in the other environment. See :ref:`coll_python_docs_req` for details. -.. note:: +Dropping Python versions support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Note that dropping support for a Python version for an existing module/plugin is a breaking change, and thus requires a major release. A collection MUST announce dropping support for Python versions in their changelog, if possible in advance (for example, in previous versions before support is dropped). +Because dropping support for a Python version for an existing module/plugin is a breaking change, the collection: + +* SHOULD announce it under the deprecated features section in its changelog in previous versions before the support is dropped. +* MUST release a major version that actually drops the support. .. _coll_python_docs_req: Python documentation requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* If everything in your collection supports all eligible controller/target Python versions, you do not need to document supported Python versions. -* If your collection does not support those Python versions, you MUST document which versions it supports in the README. +* If your collection does not support all eligible controller/target Python versions, you MUST document which versions it supports in the README. * If most of your collection supports the same Python versions as ansible-core, but some modules and plugins do not, you MUST include the supported Python versions in the documentation for those modules and plugins. -For example, if your collection supports Ansible 2.9 to ansible-core 2.13, the Python versions supported for modules are 2.6, 2.7, and 3.5 and newer (until at least 3.10), while the Python versions supported for plugins are 2.7 and 3.5 and newer (until at least 3.10). So if the modules in your collection do not support Python 2.6, you have to document this in the README, for example ``The content in this collection supports Python 2.7, Python 3.5 and newer.``. - .. _coll_plugin_standards: Standards for developing module and plugin utilities ==================================================== * ``module_utils`` and ``plugin_utils`` can be marked for only internal use in the collection, but they MUST document this and MUST use a leading underscore for file names. -* It is a breaking change when you make an existing ``module_utils`` private and in that case the collection requires a major version bump. + + * If you change a utility in ``module_utils`` from public to private, you are making a breaking change. If you do this, you must release a new major version of your collection. + * Below are some recommendations for ``module_utils`` documentation: * No docstring: everything we recommend for ``other-environment`` is supported. @@ -142,8 +176,7 @@ galaxy.yml ---------- * The ``tags`` field MUST be set. -* Collection dependencies must meet a set of rules. See the section on `Collection Dependencies ` for details. -* The ``ansible`` package MUST NOT depend on collections not shipped in the package. +* Collection dependencies MUST meet a set of rules. See the section on :ref:`Collection Dependencies ` for details. * If you plan to split up your collection, the new collection MUST be approved for inclusion before the smaller collections replace the larger in Ansible. * If you plan to add other collections as dependencies, they MUST run through the formal application process. @@ -159,19 +192,16 @@ meta/runtime.yml Example: `meta/runtime.yml `_ -* The ``meta/runtime.yml`` MUST define the minimum version of Ansible which this collection works with. - - * If the collection works with Ansible 2.9, then this should be set to `>=2.9.10` - * It is usually better to avoid adding `<2.11` as a restriction, since this for example makes it impossible to use the collection with the current ansible-base devel branch (which has version 2.11.0.dev0) +* The ``meta/runtime.yml`` MUST define the minimum version of ansible-core which this collection works with using the ``requires_ansible`` field. For example, if the collection works with ansible-core 2.16 and later, set ``requires_ansible: '>=2.16'`` in the ``meta/runtime.yml`` file. .. _coll_module-reqs: meta/execution-environment.yml ------------------------------ -If a collection has controller-side Python package and/or system package requirements, to allow easy `execution environment `_ building, they SHOULD be listed in corresponding files under the ``meta`` directory, specified in ``meta/execution-environment.yml``, and `verified `_. +If a collection has controller-side Python package and/or system package requirements, to allow easy :ref:`execution environment` building, they SHOULD be listed in corresponding files under the ``meta`` directory, specified in ``meta/execution-environment.yml``, and `verified `_. -See the `Collection-level dependencies guide `_ for more information and `collection_template/meta ` directory content as an example. +See the `Collection-level dependencies guide `_ for more information and `collection_template/meta `_ directory content as an example. Modules & Plugins ------------------ @@ -189,32 +219,33 @@ Modules & Plugins Other directories ----------------- -Collections MUST not use files outside ``meta/``, ``plugins/``, ``roles/`` and ``playbooks/`` in any plugin, role, or playbook that can be called by FQCN, used from other collections, or used from user playbooks and roles. A collection must work if every file or directory is deleted from the installed collection except those four directories and their contents. +* Collections MUST not use files outside ``meta/``, ``plugins/``, ``roles/`` and ``playbooks/`` in any plugin, role, or playbook that can be called by FQCN, used from other collections, or used from user playbooks and roles. -Internal plugins, roles and playbooks (artifacts used only in testing, or only to release the collection, or only for some other internal purpose and not used externally) are exempt from this rule and may rely on files in other directories. + * A collection MUST work if every file or directory is deleted from the installed collection except those four directories and their contents. + * Internal plugins, roles and playbooks (artifacts used only in testing, or only to release the collection, or only for some other internal purpose and not used externally) are exempt from this rule and may rely on files in other directories. .. _coll_docs_structure_reqs: Documentation requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All modules and plugins MUST: +Collections: -* Include a :ref:`DOCUMENTATION ` block. -* Include an :ref:`EXAMPLES ` block (except where not relevant for the plugin type). -* Use FQCNs when referring to modules, plugins and documentation fragments inside and outside the collection (including ``ansible.builtin`` for the listed entities from ansible-core. - -When using ``version_added`` in the documentation: +* ``MUST`` use :ref:`links and formatting macros `. +* ``SHOULD`` have contributor guidelines in the ``CONTRIBUTING.md`` or ``README.md`` file. -* Declare the version of the collection in which the options were added -- NOT the version of Ansible. -* If you for some reason really have to specify version numbers of Ansible or of another collection, you also have to provide ``version_added_collection: collection_name``. We strongly recommend to NOT do this. -* Include ``version_added`` when you add new content (modules, plugins, options) to an existing collection. The values are shown in the documentation and can be useful, but you do not need to add ``version_added`` to every option, module, and plugin when creating a new collection. +All modules and plugins: -Other items: +* ``MUST`` include a :ref:`DOCUMENTATION ` block. +* ``MUST`` include an :ref:`EXAMPLES ` block (except where not relevant for the plugin type). +* ``MUST`` use FQCNs when referring to modules, plugins and documentation fragments inside and outside the collection including ``ansible.builtin.`` for ansible-core. +* ``MUST`` include a :ref:`RETURN ` block for modules and other plugins that return data. +* ``MUST`` include the ``version_added`` field when adding new content to an existing collection for entities that support it, for example, for modules, plugins, options, return values, and attributes. -* The ``CONTRIBUTING.md`` (or ``README.md``) file MUST state what types of contributions (pull requests, feature requests, and so on) are accepted and any relevant contributor guidance. Issues (bugs and feature requests) reports must always be accepted. -* Collections are encouraged to use z:ref:`links and formatting macros ` -* Including a :ref:`RETURN ` block for modules is strongly encouraged but not required. + * You do not have to add ``version_added`` when creating a new collection before its first release. + * The ``version_added`` field for objects in a collection MUST refer to the version of the collection in which the options were added -- ``NOT`` the version of Ansible or ansible-core. + + * If, for some reason, you need to specify version numbers of Ansible or another collection, you ``MUST`` also provide ``version_added_collection: collection_name``. We strongly recommend to ``NOT`` do this. .. _coll_workflow: @@ -226,30 +257,39 @@ Contributor Workflow Changelogs ---------- -Collections are required to include a changelog. To give a consistent feel for changelogs across collections and ensure changelogs exist for collections included in the ``ansible`` package we suggest you use `antsibull-changelog `_ to maintain and generate this but other options exist. Preferred (in descending order): - -#. Use antsibull-changelog (preferred). -#. Provide ``changelogs/changelog.yaml`` in the `correct format `_. (You can use ``antsibull-lint changelog-yaml /path/to/changelog.yaml`` to validate the format.) -#. Provide a link to the changelog file (self-hosted) (not recommended). +* Collections MUST include a changelog in the `correct format `_. -Note that the porting guide is compiled from ``changelogs/changelog.yaml`` (sections ``breaking_changes``, ``major_changes``, ``deprecated_features``, ``removed_features``). So if you use option 3, you will not be able to add something to the porting guide. + #. You can generate or check changelogs using `antsibull-changelog `_ (`documentation `_), which provides consistency for changelogs across collections included in the ``ansible`` package. .. _coll_versioning_req: Versioning and deprecation -~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------- + +* Collections MUST adhere to the `Semantic versioning conventions `_: + + * MUST have this information in its ``README.md`` file in the collection root directory. + * SHOULD have this information in its contributor and maintainer documentation. + * MUST have changelog entries under correct categories (``Major changes``, ``Minor changes``, ``Bugfixes``, and so on). -* Collections MUST adhere to `semantic versioning `_. -* To preserve backward compatibility for users, every Ansible minor version series (x.Y.z) will keep the major version of a collection constant. If Ansible 3.0.0 includes ``community.general`` 2.2.0, then each 3.Y.z (3.1.z, 3.2.z, and so on) release will include the latest ``community.general`` 2.y.z release available at build time. Ansible 3.y.z will **never** include a ``community.general`` 3.y.z release, even if it is available. Major collection version changes will be included in the next Ansible major release (4.0.0 in this example). -* Therefore, ensure that the current major release of your collection included in 3.0.0 receives at least bugfixes as long as new 3.Y.Z releases are produced. -* Since new minor releases are included, you can include new features, modules and plugins. You must make sure that you do not break backward compatibility! (See `semantic versioning `_.) This means in particular: +* Collections MUST preserve backward compatibility: - * You can fix bugs in patch releases, but not add new features or deprecate things. - * You can add new features and deprecate things in minor releases but not remove things or change the behavior of existing features. - * You can only remove things or make breaking changes in major releases. -* We recommend that you ensure that if a deprecation is added in a collection version that is included in Ansible 3.y.z, the removal itself will only happen in a collection version included in Ansible 5.0.0 or later, but not in a collection version included in Ansible 4.0.0. -* Content moved from ansible/ansible that was scheduled for removal in 2.11 or later MUST NOT be removed in the current major release available when ansible 2.10.0 is released. Otherwise it would already be removed in 2.10, unexpectedly for users! Deprecation cycles can be shortened (since they are now uncoupled from ansible or ansible-base versions), but existing ones must not be unexpectedly terminated. -* We recommend you announce your policy of releasing, versioning and deprecation to contributors and users in some way. For an example of how to do this, see `the announcement in community.general `_. You could also do this in the README. + * To preserve backward compatibility for users, every Ansible minor version series (x.Y.z) will keep the major version of a collection constant. + + * For example, if Ansible 3.0.0 includes ``community.general`` 2.2.0, then each 3.Y.z (3.1.z, 3.2.z, and so on) release will include the latest ``community.general`` 2.y.z release available at build time. + * Ansible 3.y.z will **never** include a ``community.general`` 3.y.z release, even if it is available. + * Major collection version changes will be included in the next Ansible major release (4.0.0 in this example). + * Therefore, ensure that the current major release of your collection included in 3.0.0 receives at least bugfixes as long as new 3.Y.Z releases are produced. + * Since new minor releases are included, you can include new features, modules and plugins. You MUST make sure that you DO NOT break backward compatibility! This means in particular: + + * You can fix bugs in ``patch releases``, but you MUST NOT add new features or deprecate things. + * You can add new features and deprecate things in ``minor releases`` but you MUST NOT remove things or change the behavior of existing features. + * You can only remove things or make breaking changes in ``major releases``. + * See `semantic versioning `_ for more information. + + * We recommend that you ensure if a deprecation is added in a collection version that is included in Ansible 3.y.z, the removal itself will only happen in a collection version included in Ansible 5.0.0 or later, but not in a collection version included in Ansible 4.0.0. + +* The collection SHOULD make its policy of releasing and deprecation available to contributors and users in some way, for example, in its README or pinned issue. See `the announcement in community.general `_ as an example. .. _ coll_naming_req: @@ -259,29 +299,33 @@ Naming Collection naming ----------------- -For collections under ansible-collections the repository SHOULD be named ``NAMESPACE.COLLECTION``. - -To create a new collection and corresponding repository, first, a new namespace in Galaxy has to be created by submitting `Request a namespace `_. +When choosing a name for a brand new namespace: -`Namespace limitations `_ lists requirements for namespaces in Galaxy. +* Take into consideration the `Namespace limitations `_ which list requirements for namespaces in Galaxy. +* If the namespace does not exit yet and is not occupied by anybody else, submit a `namespace request `_ to have it created for you. -For collections created for working with a particular entity, they should contain the entity name, for example ``community.mysql``. +Naming recommendations: -For corporate maintained collections, the repository can be named ``COMPANY_NAME.PRODUCT_NAME``, for example ``ibm.db2``. +* For collections under the ``ansible-collections`` GitHub organization the repository SHOULD be named ``NAMESPACE.COLLECTION``. +* For collections created for working with a particular entity, they should contain the entity name, for example ``community.mysql``. +* For corporate maintained collections, the repository can be named ``COMPANY_NAME.PRODUCT_NAME``, for example ``ibm.db2``. +* Avoid FQCN/repository names: -We should avoid FQCN / repository names: + * which are unnecessarily long: try to make it compact but clear. + * contain the same words / collocations in ``NAMESPACE`` and ``COLLECTION`` parts, for example ``my_system.my_system``. -* which are unnecessary long: try to make it compact but clear. -* contain the same words / collocations in ``NAMESPACE`` and ``COLLECTION`` parts, for example ``my_system.my_system``. +.. note:: -If your collection is planned to be certified on **Red Hat Automation Hub**, please consult with Red Hat Partner Engineering through ``ansiblepartners@redhat.com`` to ensure collection naming compatibility between the community collection on **Galaxy**. + If you plan to get your collection certified on **Red Hat Automation Hub**, please consult with Red Hat Partner Engineering through ``ansiblepartners@redhat.com`` to ensure collection naming compatibility between the community collection on **Galaxy** and the certified collection. .. _coll_module_name_req: Module naming ------------- -Modules that only gather information MUST be named ``_info``. Modules that return ``ansible_facts`` are named ``_facts`` and do not return non-facts. +* Modules that only gather and return information MUST be named ``_info``. +* Modules that gather and return ``ansible_facts`` MUST be named ``_facts`` and MUST NOT return anything but facts. + For more information, refer to the :ref:`Developing modules guidelines `. .. _coll_licensing_req: @@ -289,44 +333,29 @@ For more information, refer to the :ref:`Developing modules guidelines `_ -:module_utils: must be licensed with a free software license that is compatible with the - `GPL-3.0-or-later `_. Ansible - itself typically uses the `BSD-2-clause - `_ license to make it possible for - third-party modules which are licensed incompatibly with the GPLv3 to use them. - Please consider this use case when licensing your own ``module_utils``. -:All other code in ``plugins/``: All other code in ``plugins/`` must be under the `GPL-3.0-or-later - `_. These plugins - are run inside of the Ansible controller process which is licensed under - the ``GPL-3.0-or-later`` and often must import code from the controller. - For these reasons, ``GPL-3.0-or-later`` must be used. -:All other code: Code outside ``plugins/`` may be licensed under another free software license that is compatible - with the `GPL-3.0-or-later `_, - provided that such code does not import any other code that is licensed under - the ``GPL-3.0-or-later``. If the file does import other ``GPL-3.0-or-later`` code, - then it must similarly be licensed under ``GPL-3.0-or-later``. Note that this applies in - particular to unit tests; these often import code from ansible-core, plugins, module utils, - or modules, and such code is often licensed under ``GPL-3.0-or-later``. -:Non code content: At the moment, these must also be under the `GPL-3.0-or-later - `_. - -Use `the list of licenses from gnu.org -`_ to find which licenses are -compatible with the GPLv3+. The license must be considered open source and compatible with GPLv3+ on both the gnu.org license -list and the `Debian Free Software Guidelines `_ to be -allowed. - -These guidelines are the policy for inclusion in the Ansible package and are in addition to any -licensing and legal concerns that may otherwise affect your code. +There are several types of content in collections which licensing has to address in different ways. + +* The content that MUST be licensed with a free software license that is **compatible with** the `GPL-3.0-or-later `_: + + * The ``modules/`` directory content. + * The ``module_utils/`` directory content: ansible-core typically uses the `BSD-2-clause `_ license to allow third-party modules to use the ``module_utils`` in cases when those third-party modules have licenses that are incompatible with the GPLv3. Please consider this use case when licensing your own ``module_utils``. + * Code outside ``plugins/``: if it DOES NOT import code licensed under ``GPL-3.0-or-later`` it may be licensed under another license compatible with ``GPL-3.0-or-later``. + * Non-code content. + * To be allowed, the license MUST be considered open source and compatible with ``GPL-3.0-or-later`` on **both**: + + * The `gnu.org license list `_. + * The `Debian Free Software Guidelines `_. + +* The content that MUST be licensed with the `GPL-3.0-or-later `_: + + * All other code in the ``plugins/`` directory except code under the ``modules/`` and ``module_utils/`` directories (see above): these plugins are run inside of the Ansible controller process which is licensed under the ``GPL-3.0-or-later`` and often must import code from the controller. For these reasons, ``GPL-3.0-or-later`` MUST be used. + * Code outside ``plugins/``: if it imports any other code that is licensed under ``GPL-3.0-or-later``. Note that this applies in particular to unit tests that often import code from ansible-core, ``plugins/``, ``module_utils/``, or ``modules/``, and such code is often licensed under ``GPL-3.0-or-later``. Contributor License Agreements @@ -346,31 +375,33 @@ and lower barriers to contribution. Repository management ===================== -Every collection MUST have a public git repository. Releases of the collection MUST be tagged in said repository. This means that releases MUST be ``git tag``\ ed and that the tag name MUST exactly match the Galaxy version number. Tag names MAY have a ``v`` prefix, but a collection's tag names MUST have a consistent format from release to release. +* Every collection MUST have a public Git repository. +* Releases of the collection MUST be tagged in its repository. + + * The ``git`` utility with the ``tag`` argument MUST be used to tag the releases. + * The tag name MUST exactly match the Galaxy version number. + * Tag names MAY have a ``v`` prefix. + * Tag names MUST have a consistent format from release to release. -Additionally, collection artifacts released to Galaxy MUST be built from the sources that are tagged in the collection's git repository as that release. Any changes made during the build process MUST be clearly documented so the collection artifact can be reproduced. +* Collection artifacts released to Galaxy MUST be built from the sources that are tagged in the collection's Git repository as that release. -We are open to allowing other SCM software once our tooling supports them. + * Any changes made during the build process MUST be clearly documented so the collection artifact can be reproduced. .. _coll_branch_config: Branch name and configuration ----------------------------- -This subsection is **only** for repositories under `ansible-collections `_! Other collection repositories can also follow these guidelines, but do not have to. - -All new repositories MUST have ``main`` as the default branch. - -Existing repositories SHOULD be converted to use ``main``. - -Repository Protections: +.. note:: -* Allow merge commits: disallowed + This subsection is **only** for repositories under `ansible-collections `_! Other collection repositories can also follow these guidelines, but do not have to. -Branch protections MUST be enforced: +* All new repositories MUST have ``main`` as the default branch. +* Pull Requests settings MUST disallow ``merge commits``. +* The following branch protection rules that MUST be enabled for all release branches: -* Require linear history -* Include administrators + * ``Require linear history`` + * ``Do not allow bypassing the above settings`` .. _coll_ci_tests: @@ -379,31 +410,29 @@ CI Testing .. note:: - You can copy the free-to-use `GitHub action workflow file `_ from the `Collection Template repository `_ to the `.github/workflows` directory in your collection to set up testing through GitHub actions. The workflow covers all the requirements below. + You can copy the free-to-use `GitHub action workflow file `_ from the `collection_template `_ repository to the ``.github/workflows`` directory in your collection to set up testing through GitHub actions. The workflow covers all the requirements below. -.. note:: - - Subscribe to the `news-for-maintainers repository `_ - and keep your matrix up to date in accordance to related announcements. Add new `ansible-core` versions in a timely manner and consider dropping support and testing against its EOL versions and versions your collection does not support. - If your collection repository is under the ``ansible-collections`` GitHub organization, please keep in mind that the number of testing jobs is limited - and shared across all the collections in the organization. So, focusing on good test coverage of your collection, - please avoid testing against unnecessary entities such as ``ansible-core`` EOL versions your collection does not support. + If your collection repository is under the ``ansible-collections`` GitHub organization, please keep in mind that the number of testing jobs is limited and shared across all the collections in the organization. Therefore, focusing on good test coverage of your collection, please avoid testing against unnecessary entities such as ``ansible-core`` EOL versions that your collection does not support. + +To receive important announcements that can affect the collections (for example, testing), collection maintainers SHOULD: + +* Subscribe to the `news-for-maintainers `_ repository. +* Join the `Collection Maintainers & Contributors `_ forum group. * You MUST run the ``ansible-test sanity`` command from the `latest stable ansible-base/ansible-core branch `_. * Collections MUST run an equivalent of the ``ansible-test sanity --docker`` command. - * If they do not use ``--docker``, they must make sure that all tests run, in particular the compile and import tests (which should run for all :ref:`supported Python versions `). - * Collections can choose to skip certain Python versions that they explicitly do not support; this needs to be documented in ``README.md`` and in every module and plugin (hint: use a docs fragment). However, we strongly recommend you follow the :ref:`Ansible Python Compatibility ` section for more details. -* You SHOULD suggest to *additionally* run ``ansible-test sanity`` from the ansible/ansible ``devel`` branch so that you find out about new linting requirements earlier. -* The sanity tests MUST pass. + * If they do not use ``--docker``, they must make sure that all tests run, in particular the compile and import tests (which should run for all :ref:`supported Python versions `). + * Collections can choose to skip certain Python versions that they explicitly do not support; this needs to be documented in ``README.md`` and in every module and plugin (hint: use a docs fragment). However, we strongly recommend you follow the :ref:`Ansible Python Compatibility ` section for more details. - * Adding some entries to the ``test/sanity/ignore*.txt`` file is an allowed method of getting them to pass, except cases listed below. - * You SHOULD not have ignored test entries. A reviewer can manually evaluate and approve your collection if they deem an ignored entry to be valid. +* You SHOULD *additionally* run ``ansible-test sanity`` from the ansible/ansible ``devel`` branch so that you find out about new linting requirements earlier. +* The sanity tests MUST pass. - * You MUST not ignore the following validations. They must be fixed before approval: + * You SHOULD avoid adding entries to the ``test/sanity/ignore*.txt`` files to get your tests to pass but it is allowed except in cases listed below. + * You MUST NOT ignore the following validations. They MUST be fixed and removed from the files before approval: * ``validate-modules:doc-choices-do-not-match-spec`` * ``validate-modules:doc-default-does-not-match-spec`` * ``validate-modules:doc-missing-type`` @@ -420,15 +449,14 @@ CI Testing 1. A dangerous module parameter has been deprecated or removed, and code is present to inform the user that they should not use this specific parameter anymore or that it stopped working intentionally. 2. Module parameters are only used to pass in data from an accompanying action plugin. - * All entries in ignores.txt MUST have a justification in a comment in the ignore.txt file for each entry. For example ``plugins/modules/docker_container.py use-argspec-type-path # uses colon-separated paths, can't use type=path``. - * Reviewers can block acceptance of a new collection if they don't agree with the ignores.txt entries. + * All entries in ``ignore-*.txt`` files MUST have a justification in a comment in the files for each entry. For example ``plugins/modules/docker_container.py use-argspec-type-path # uses colon-separated paths, can't use type=path``. -* You MUST run CI against each of the "major versions" (2.10, 2.11, 2.12, etc) of ``ansible-base``/``ansible-core`` that the collection supports. (Usually the ``HEAD`` of the stable-xxx branches.) +* You MUST run CI against each of the "major versions" (2.14, 2.16, 2.17, etc) of ``ansible-core`` that the collection supports. (Usually the ``HEAD`` of the stable-xxx branches.) * All CI tests MUST run against every pull request and SHOULD pass before merge. * At least sanity tests MUST run against a commit that releases the collection; if they do not pass, the collection will NOT be released. - If the collection has integration/unit tests, they SHOULD run too; if they do not pass, the errors SHOULD be analyzed to decide whether they should block the release or not. -* All CI tests MUST run regularly (nightly, or at least once per week) to ensure that repositories without regular commits are tested against the latest version of ansible-test from each ansible-base/ansible-core version tested. The results from the regular CI runs MUST be checked regularly. +* All CI tests MUST run regularly (nightly, or at least once per week) to ensure that repositories without regular commits are tested against the latest version of ansible-test from each ansible-core version tested. The results from the regular CI runs MUST be checked regularly. All of the above can be achieved by using the `GitHub Action template `_. @@ -437,47 +465,25 @@ To learn how to add tests to your collection, see: * :ref:`collection_integration_tests` * :ref:`collection_unit_tests` - -.. _coll_wg_reqs: - -Collections and Working Groups -============================== - -The collections have: - -* Working group page(s) on a corresponding wiki if needed. Makes sense if there is a group of modules for working with one common entity, for example, postgresql, zabbix, grafana, and so on. -* Issue for agenda (or pinboard if there are no regular meetings) as a pinned issue in the repository. - .. _coll_migrating_reqs: When moving modules between collections ======================================= -All related entities must be moved/copied including: - -* Related plugins and module_utils files (when moving, be sure it is not used by other modules, otherwise copy). -* CI and unit tests. -* Corresponding documentation fragments from ``plugins/doc_fragments``. - -Also: - -* Change ``M()``, examples, ``seealso``, ``extended_documentation_fragments`` to use actual FQCNs in moved content and in other collections that have references to the content. -* Move all related issues, pull requests, and wiki pages. -* Look through ``docs/docsite`` directory of `ansible-base GitHub repository `_ (for example, using the ``grep`` command-line utility) to check if there are examples using the moved modules and plugins to update their FQCNs. - -See :ref:`Migrating content to a different collection ` for complete details. +See :ref:`Migrating content to a different collection ` for complete details. .. _coll_development_conventions: Development conventions ======================= -Besides all the requirements listed in the :ref:`module_dev_conventions`, be sure: +All modules in your collection: -* Your modules satisfy the concept of :ref:`idempotency `: if a module repeatedly runs with the same set of inputs, it will not make any changes on the system. -* Your modules do not query information using special ``state`` option values like ``get``, ``list``, ``query``, or ``info`` - +* MUST satisfy all the requirements listed in the :ref:`module_dev_conventions`. +* MUST satisfy the concept of :ref:`idempotency `: if a module repeatedly runs with the same set of inputs, it will not make any changes on the system. +* MUST NOT query information using special ``state`` option values like ``get``, ``list``, ``query``, or ``info`` - create new ``_info`` or ``_facts`` modules instead (for more information, refer to the :ref:`Developing modules guidelines `). -* ``check_mode`` is supported in all ``*_info`` and ``*_facts`` modules (for more information, refer to the :ref:`Development conventions <#following-ansible-conventions>`). +* ``check_mode`` MUST be supported by all ``*_info`` and ``*_facts`` modules (for more information, refer to the :ref:`Development conventions <#following-ansible-conventions>`). .. _coll_dependencies: @@ -486,7 +492,9 @@ Collection Dependencies **Notation:** if foo.bar has a dependency on baz.bam, we say that baz.bam is the collection *depended on*, and foo.bar is the *dependent collection*. -* Collection dependencies must have a lower bound on the version which is at least 1.0.0. +* The collection MUST NOT depend on collections not included in the ``ansible`` package. +* Collection dependencies MUST be published on Galaxy. +* Collection dependencies MUST have a lower bound on the version which is at least 1.0.0. * This means that all collection dependencies have to specify lower bounds on the versions, and these lower bounds should be stable releases, and not versions of the form 0.x.y. * When creating new collections where collection dependencies are also under development, you need to watch out since Galaxy checks whether dependencies exist in the required versions: @@ -496,13 +504,13 @@ Collection Dependencies #. Then modify ``foo.bar``'s ``galaxy.yml`` to specify ``'>=1.0.0'`` for ``foo.baz``. #. Finally release ``foo.bar`` as 1.0.0. -* The dependencies between collections included in Ansible must be valid. If a dependency is violated, the involved collections must be pinned so that all dependencies are valid again. This means that the version numbers from the previous release are kept or only partially incremented so that the resulting set of versions has no invalid dependencies. +* The dependencies between collections included in Ansible MUST be valid. If a dependency is violated, the involved collections MUST be pinned so that all dependencies are valid again. This means that the version numbers from the previous release are kept or only partially incremented so that the resulting set of versions has no invalid dependencies. * If a collection has a too strict dependency for a longer time, and forces another collection depended on to be held back, that collection will be removed from the next major Ansible release. What "longer time" means depends on when the next Ansible major release happens. If a dependent collection prevents a new major version of a collection it depends on to be included in the next major Ansible release, the dependent collection will be removed from that major release to avoid blocking the collection being depended on. * We strongly suggest that collections also test against the ``main`` branches of their dependencies to ensure that incompatibilities with future releases of these are detected as early as possible and can be resolved in time to avoid such problems. Collections depending on other collections must understand that they bear the risk of being removed when they do not ensure compatibility with the latest releases of their dependencies. -* Collections included in Ansible must not depend on other collections except if they satisfy one of the following cases: +* Collections included in Ansible MUST NOT depend on other collections except if they satisfy one of the following cases: #. They have a loose dependency on one (or more) major versions of other collections included in Ansible. For example, ``ansible.netcommon: >=1.0.0``, or ``ansible.netcommon: >=2.0.0, <3.0.0``. In case a collection depends on releases of a new major version outside of this version range that will be included in the next major Ansible release, the dependent collection will be removed from the next major Ansible release. The cut-off date for this is feature freeze. #. They are explicitly being allowed to do so by the Steering Committee. @@ -521,22 +529,6 @@ Examples * ``ansible.netcommon 4.0.0`` is released during this major Ansible release cycle. * ``community.foonetwork`` either releases a new version before feature freeze of the next major Ansible release that allows depending on all ``ansible.netcommon 4.x.y`` releases, or it will be removed from the next major Ansible release. -.. _coll_inclusion_reqs: - -Requirements for collections to be included in the Ansible Package -================================================================== - -To be included in the `ansible` package, collections must meet the following criteria: - -* :ref:`Development conventions `. -* `Collection requirements `_ (this document). - - * The `Collection Inclusion Criteria Checklist `_ covers most of the criteria from this document. -* :ref:`Ansible documentation format ` and the :ref:`style guide `. -* To pass the Ansible :ref:`sanity tests `. -* To have :ref:`unit `_and / or :ref:`integration tests ` according to the corresponding sections of this document. - - Other requirements =================== diff --git a/docs/docsite/rst/community/communication.rst b/docs/docsite/rst/community/communication.rst index 0a47bc5b582..4ffef1749b9 100644 --- a/docs/docsite/rst/community/communication.rst +++ b/docs/docsite/rst/community/communication.rst @@ -17,79 +17,54 @@ All communication and interactions in the Ansible Community are governed by our Forum ===== -The `Ansible Community Forum `_ is a single starting point for questions and help, development discussions, events, and much more. `Register `_ to join the community. Search by categories and tags to find interesting topics or start a new one; subscribe only to topics you need! +The `Ansible Forum `_ is a single starting point and our default communication platform for questions and help, development discussions, events, and much more. `Register `_ to join the community. Search by categories and tags to find interesting topics or start a new one; subscribe only to topics you need! Take a look at the `forum groups `_ and join ones that match your interests. In most cases, joining a forum group automatically subscribes you to related posts. -Want to create a group? -Request it in the `forum topic `_. +.. _bullhorn: + +The Bullhorn +------------ + +**The Bullhorn** is our newsletter for the Ansible contributor community published in the Forum: + +* To subscribe, click the ``bell`` button under the `Bullhorn category `_ description and then ``Watching``. +* To publish your news item, see the `About the Newsletter category post `_. +* Questions about the newsletter? Ask us in the `Ansible Social room on Matrix `_. + +Regional and Language-specific channels +--------------------------------------- + +If you feel more comfortable communicating in another language other than English, see the `International Communities forum category `_. Currently there are subcategories for Español (Spanish), Português (Portuguese), and Norsk (Norwegian). + +For more information including how to request a subcategory for a language, see the `About the International Communities category post `_. .. _communication_irc: Real-time chat ============== -For real-time interactions, conversations in the Ansible community happen over two chat protocols: Matrix (recommended) and IRC. -The main Matrix and IRC channels exchange messages. -This means you can choose whichever protocol you prefer for the main channels. +For real-time interactions, conversations in the Ansible community happen over the Matrix protocol. .. note:: - Although you can choose either Matrix or IRC, please take into account that many Ansible communities use only Matrix. - -Join a channel any time to ask questions, participate in a Working Group meeting, or just say hello. + The :ref:`ansible_forum` is our default communication platform. Join the forum and get in touch with the community there before considering other options like Matrix. -Ansible community on Matrix ---------------------------- - -To join the community using Matrix, you need two things: +Join a channel any time to chat with fellow enthusiasts, participate in a Working Group meeting, or just say hello. To chat on Matrix, you need: * a Matrix account (from `Matrix.org `_ or any other Matrix homeserver) * a `Matrix client `_ (we recommend `Element Webchat `_) -The Ansible community maintains its own Matrix homeserver at ``ansible.im``, however, public registration is currently unavailable. - -Matrix chat supports: - -* persistence (when you log on, you see all messages since you last logged off) -* edits (Let you fix typos and so on. **NOTE** Each edit you make on Matrix re-sends the message to IRC. Please try to avoid multiple edits!) -* replies to individual users -* reactions/emojis -* bridging to IRC -* no line limits -* images - The room links in the :ref:`general_channels` or the :ref:`working_group_list` list will take you directly to the relevant rooms. -If there is no appropriate room for your community, please create it. - For more information, see the community-hosted `Matrix FAQ `_. You can add Matrix shields to your repository's ``README.md`` using the shield in the `community-topics `_ repository as a template. -Ansible community on IRC ------------------------- - -The Ansible community maintains several IRC channels on `irc.libera.chat `_. To join the community using IRC, you need one thing: - -* an IRC client - -IRC chat supports: - -* no persistence (you only see messages when you are logged on unless you add a bouncer) -* simple text interface -* bridging from Matrix - -Our IRC channels may require you to register your IRC nickname. If you receive an error when you connect or when posting a message, see `libera.chat's Nickname Registration guide `_ for instructions. To find all ``ansible`` specific channels on the libera.chat network, use the following command in your IRC client: - -.. code-block:: text - - /msg alias LIST #ansible* -min 5 - -as described in the `libera.chat docs `_. +.. note:: -Our channels record history on the Matrix side. The channel history can be viewed in a browser - all channels will report an appropriate link to ``chat.ansible.im`` in their Chanserv entrymsg upon joining the room. Alternatively, a URL of the form ``https://chat.ansible.im/#/room/# {IRC channel name}:libera.chat`` will also work, for example - for the #ansible-docs channel it would be `https://app.element.io/#/room/#ansible-docs:libera.chat`. + IRC channels are no longer considered official communication channels. Please use the Forum and Matrix instead. .. _general_channels: @@ -98,30 +73,21 @@ General channels The clickable links will take you directly to the relevant Matrix room in your browser; room/channel information is also given for use in other clients: -- `Community social room and posting news for the Bullhorn newsletter `_ - ``Matrix: #social:ansible.com | IRC: #ansible-social`` -- `General usage and support questions `_ - ``Matrix: #users:ansible.com | IRC: #ansible`` -- `Discussions on developer topics and code related to features or bugs `_ - ``Matrix: #devel:ansible.com | IRC: #ansible-devel`` -- `Discussions on community and collections related topics `_ - ``Matrix: #community:ansible.com | IRC: #ansible-community`` -- `For public community meetings `_ - ``Matrix: #meeting:ansible.im | IRC: #ansible-meeting`` - - We will generally announce these on one or more of the above mailing lists. See the `meeting schedule `_ +- `Community social room and posting news for the Bullhorn newsletter `_ +- `General usage and support questions `_ +- `Discussions on developer topics and code related to features or bugs `_ +- `Discussions on community and collections related topics `_ Working group-specific channels ------------------------------- Many of the working groups have dedicated chat channels. See the :ref:`working_group_list` for more information. -Regional and Language-specific channels ---------------------------------------- - -- Comunidad Ansible en español - Matrix: `#espanol:ansible.im `_ | IRC: ``#ansible-es`` -- Communauté française d'Ansible - Matrix: `#francais:ansible.im `_ | IRC: ``#ansible-fr`` -- Communauté suisse d'Ansible - Matrix: `#suisse:ansible.im `_ | IRC: ``#ansible-zh`` -- European Ansible Community - Matrix: `#europe:ansible.im `_ | IRC: ``#ansible-eu`` +Meetings on Matrix +------------------ -Meetings on chat ----------------- - -The Ansible community holds regular meetings on various topics on Matrix/IRC, and anyone who is interested is invited to participate. For more information about Ansible meetings, consult the `meeting schedule and agenda page `_. +The Ansible community holds regular meetings on various topics on Matrix, and anyone who is interested is invited to participate. +For more information about Ansible meetings, consult the `meeting schedule and agenda page `_. .. _working_group_list: @@ -130,114 +96,44 @@ Working groups Working Groups are a way for Ansible community members to self-organize around particular topics of interest. -Our community working groups are represented in Matrix rooms and `Forum groups `_. - -Many of them meet in chat. If you want to get involved in a working group, join the Matrix room or IRC channel where it meets or comment on the agenda. +Our community working groups are represented in `Forum groups `_. +See those links for a complete list of communications channels. -- `AAP Configuration as Code `_ - Matrix: `#aap_config_as_code:ansible.com `_ -- `Amazon (AWS) Working Group `_ - Matrix: `#aws:ansible.com `_ | IRC: ``#ansible-aws`` -- `AWX Working Group `_ - Matrix: `#awx:ansible.com `_ | IRC: ``#ansible-awx`` -- Azure Working Group - Matrix: `#azure:ansible.com `_ | IRC: ``#ansible-azure`` -- `Community Working Group `_ (including Meetups) - Matrix: `#community:ansible.com `_ | IRC: ``#ansible-community`` -- Container Working Group - Matrix: `#container:ansible.com `_ | IRC: ``#ansible-container`` -- DigitalOcean Working Group - Matrix: `#digitalocean:ansible.im `_ | IRC: ``#ansible-digitalocean`` -- Diversity Working Group - Matrix: `#diversity:ansible.com `_ | IRC: ``#ansible-diversity`` -- Docker Working Group - Matrix: `#devel:ansible.com `_ | IRC: ``#ansible-devel`` -- `Documentation Working Group `_ - Matrix: `#docs:ansible.com `_ | IRC: ``#ansible-docs`` -- `Execution Environments Group `_ -- `Galaxy Working Group `_ - Matrix: `#galaxy:ansible.com `_ | IRC: ``#ansible-galaxy`` -- JBoss Working Group - Matrix: `#jboss:ansible.com `_ | IRC: ``#ansible-jboss`` -- Kubernetes Working Group - Matrix: `#kubernetes:ansible.com `_ | IRC: ``#ansible-kubernetes`` -- Linode Working Group - Matrix: `#linode:ansible.com `_ | IRC: ``#ansible-linode`` -- Molecule Working Group (`testing platform for Ansible playbooks and roles `_) - Matrix: `#molecule:ansible.im `_ | IRC: ``#ansible-molecule`` -- MySQL Working Group - Matrix: `#mysql:ansible.com `_ -- `Network Working Group `_ - Matrix: `#network:ansible.com `_ | IRC: ``#ansible-network`` -- `PostgreSQL Working Group `_ - Matrix: `#postgresql:ansible.com `_ -- `Release Management Working Group `_ - Matrix: `#release-management:ansible.com `_ -- Remote Management Working Group - Matrix: `#devel:ansible.com `_ | IRC: ``#ansible-devel`` -- Storage Working Group - Matrix: `#storage:ansible.com `_ | IRC: ``#ansible-storage`` -- VMware Working Group - Matrix: `#vmware:ansible.com `_ | IRC: ``#ansible-vmware`` -- Windows Working Group - Matrix: `#windows:ansible.com `_ | IRC: ``#ansible-windows`` -- Ansible developer tools Group - Matrix: `#devtools:ansible.com `_ | IRC: ``#ansible-devtools`` - -Forming a new working group ----------------------------- - -The basic components of a working group are: - -* Group name and charter (why the group exists). -* Registered :ref:`real-time chat channel`. -* Group of users (at least two!) who will be driving the agenda of the working group. -* Dedicated `forum group `_. - -The basic responsibilities of a working group are: - -* Follow the :ref:`code_of_conduct`. -* Be responsive on your real-time chat channel. -* Be responsive on the `forum `_ in related topics. -* Report semi-regularly on the cool stuff that your working group is working on. -* Keep your forum group information updated. +.. _requesting_forum_group: +Requesting a forum group +------------------------ -Requesting a working group -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +To request a new working group: -Anyone can request to start a Working Group, for any reason. +* Check if there is no appropriate `Forum group `_ you can join instead of starting a new one. +* See the `things you can ask for `_ with respect to working groups. +* Request a group in the `forum topic `_. +* If you also need a Matrix chat channel, see the `Ansible Community Matrix FAQ `_. -If you need only a `Forum group `_, -request it in the `forum topic `_. +.. _request_coll_repo: +Requesting a community collection repository +-------------------------------------------- -If you also need a real-time chat channel, you can `request one `_. +Working groups are often built around Ansible community collections. You can use a repository under your organization or request one under `ansible-collections `_ on the forum by creating a topic in the `Project Discussions category and the coll-repo-request tag `_. +.. _community_topics: Ansible Community Topics ======================== -The `Ansible Community Steering Committee `_ uses the `community-topics repository `_ to asynchronously discuss with the Community and vote on Community topics in corresponding issues. +The :ref:`Ansible Community Steering Committee` uses the :ref:`ansible_forum` to asynchronously discuss with the Community and vote on Community topics. -Create a new issue in the `repository `_ if you want to discuss an idea that impacts any of the following: +For more information, see: -* Ansible Community -* Community collection best practices and `requirements `_ -* `Community collection inclusion policy `_ -* `The Community governance `_ -* Other proposals of importance that need the Committee or overall Ansible community attention +* :ref:`creating_community_topic` +* :ref:`community_topics_workflow` +* `Community topics on the Forum `_ Ansible Automation Platform support questions ============================================= Red Hat Ansible `Automation Platform `_ is a subscription that contains support, certified content, and tooling for Ansible including content management, a controller, UI and REST API. -If you have a question about Ansible Automation Platform, visit `Red Hat support `_ rather than using a chat channel or the general project mailing list. - -The Bullhorn -============ - -**The Bullhorn** is our newsletter for the Ansible contributor community. You can get Bullhorn updates -from the :ref:`ansible_forum` or `subscribe `_ to receive it. - -If you have any questions or content you would like to share, you are welcome to chat with us -in the `Ansible Social room on Matrix, and mention -`newsbot `_ to have your news item tagged for review for -the next weekly issue. - -Read past issues of `the Bullhorn `_. - -Asking questions over email -=========================== - -.. note:: - - This form of communication is deprecated. Consider using the :ref:`ansible_forum` instead. - -Your first post to the mailing list will be moderated (to reduce spam), so please allow up to a day or so for your first post to appear. - -* `Ansible Announce list `_ is a read-only list that shares information about new releases of Ansible, and also rare infrequent event information, such as announcements about an upcoming AnsibleFest, which is our official conference series. Worth subscribing to! -* `Ansible AWX List `_ is for `Ansible AWX `_ -* `Ansible Development List `_ is for questions about developing Ansible modules (mostly in Python), fixing bugs in the Ansible Core code, asking about prospective feature design, or discussions about extending Ansible or features in progress. -* `Ansible Outreach List `_ help with promoting Ansible and `Ansible Meetups `_ -* `Ansible Project List `_ is for sharing Ansible tips, answering questions about playbooks and roles, and general user discussion. -* `Molecule Discussions `_ is designed to aid with the development and testing of Ansible roles with Molecule. - -The Ansible mailing lists are hosted on Google, but you do not need a Google account to subscribe. To subscribe to a group from a non-Google account, send an email to the subscription address requesting the subscription. For example: ``ansible-devel+subscribe@googlegroups.com``. +If you have a question about Ansible Automation Platform, visit `Red Hat support `_ rather than using community communication platforms. diff --git a/docs/docsite/rst/community/contributor_path.rst b/docs/docsite/rst/community/contributor_path.rst index d3a57e54311..a5171c0af04 100644 --- a/docs/docsite/rst/community/contributor_path.rst +++ b/docs/docsite/rst/community/contributor_path.rst @@ -82,7 +82,7 @@ See :ref:`communication` for ways to communicate and engage with the Ansible com Teach others ============ -Share your experience with other contributors through :ref:`improving documentation`, answering questions from other contributors and users on :ref:`Matrix/Libera.Chat IRC`, giving advice on issues and pull requests, and discussing `Community Topics `_. +Share your experience with other contributors through :ref:`improving documentation`, answering questions from other contributors and users on :ref:`Matrix/Libera.Chat IRC`, giving advice on issues and pull requests, and discussing topics on the :ref:`ansible_forum`. Become a collection maintainer =============================== @@ -105,10 +105,10 @@ Become a steering committee member You do NOT have to be a programmer to become a steering committee member. -The :ref:`Steering Committee ` member status reflects the highest level of trust which allows contributors to lead the project by making very important `decisions `_ for the Ansible project. The Committee members are the community leaders who shape the project's future and the future of automation in the IT world in general. +The :ref:`Steering Committee ` member status reflects the highest level of trust and allows contributors to lead the project by making important decisions for the Ansible project. The Committee members are community leaders who shape the project's future and the future of automation in the IT world in general. To reach the status, as the current Committee members did before getting it, along with the things mentioned in this document, you should: -* Subscribe to, comment on, and vote on the `Community Topics `_. +* Subscribe to, comment on, and vote on the `community topics`. * Propose your topics. * If time permits, join the `Community meetings `_. Note this is **NOT** a requirement. diff --git a/docs/docsite/rst/community/development_process.rst b/docs/docsite/rst/community/development_process.rst index 91847e89421..53e3db1f756 100644 --- a/docs/docsite/rst/community/development_process.rst +++ b/docs/docsite/rst/community/development_process.rst @@ -206,7 +206,7 @@ Here are some examples: remote_src=True even if mode was not set as a parameter. This failed on filesystems which do not have permission bits (https://github.com/ansible/ansible/issues/29444). -You can find more example changelog fragments in the `changelog directory `_ for the 2.16 release. +You can find more example changelog fragments in the `changelog directory `_ for the 2.17 release. After you have written the changelog fragment for your PR, commit the file and include it with the pull request. @@ -241,7 +241,7 @@ We do **not** backport features. These instructions assume that: - * ``stable-2.16`` is the targeted release branch for the backport + * ``stable-2.17`` is the targeted release branch for the backport * ``https://github.com/ansible/ansible.git`` is configured as a ``git remote`` named ``upstream``. If you do not use a ``git remote`` named ``upstream``, adjust the instructions accordingly. * ``https://github.com//ansible.git`` is configured as a ``git remote`` named ``origin``. If you do not use a ``git remote`` named ``origin``, adjust the instructions accordingly. @@ -250,7 +250,7 @@ We do **not** backport features. .. code-block:: shell git fetch upstream - git checkout -b backport/2.16/[PR_NUMBER_FROM_DEVEL] upstream/stable-2.16 + git checkout -b backport/2.17/[PR_NUMBER_FROM_DEVEL] upstream/stable-2.17 #. Cherry pick the relevant commit SHA from the devel branch into your feature branch, handling merge conflicts as necessary: @@ -264,15 +264,15 @@ We do **not** backport features. .. code-block:: shell - git push origin backport/2.16/[PR_NUMBER_FROM_DEVEL] + git push origin backport/2.17/[PR_NUMBER_FROM_DEVEL] -#. Submit the pull request for ``backport/2.16/[PR_NUMBER_FROM_DEVEL]`` against the ``stable-2.16`` branch +#. Submit the pull request for ``backport/2.17/[PR_NUMBER_FROM_DEVEL]`` against the ``stable-2.17`` branch #. The Release Manager will decide whether to merge the backport PR before the next minor release. There isn't any need to follow up. Just ensure that the automated tests (CI) are green. .. note:: - The branch name ``backport/2.16/[PR_NUMBER_FROM_DEVEL]`` is somewhat arbitrary but conveys meaning about the purpose of the branch. This branch name format is not required, but it can be helpful, especially when making multiple backport PRs for multiple stable branches. + The branch name ``backport/2.17/[PR_NUMBER_FROM_DEVEL]`` is somewhat arbitrary but conveys meaning about the purpose of the branch. This branch name format is not required, but it can be helpful, especially when making multiple backport PRs for multiple stable branches. .. note:: diff --git a/docs/docsite/rst/community/documentation_contributions.rst b/docs/docsite/rst/community/documentation_contributions.rst index a29b8c537f2..c830a0914ea 100644 --- a/docs/docsite/rst/community/documentation_contributions.rst +++ b/docs/docsite/rst/community/documentation_contributions.rst @@ -6,7 +6,7 @@ Contributing to the Ansible Documentation Ansible has a lot of documentation and a small team of writers. Community support helps us keep up with new features, fixes, and changes. -Improving the documentation is an easy way to make your first contribution to the Ansible project. You do not have to be a programmer, since most of our documentation is written in YAML (module documentation) or `reStructuredText `_ (rST). Some collection-level documentation is written in a subset of `Markdown `_. If you are using Ansible, you already use YAML in your playbooks. rST and Markdown are mostly just text. You do not even need git experience, if you use the ``Edit on GitHub`` option. +Improving the documentation is an easy way to make your first contribution to the Ansible project. You do not have to be a programmer, since most of our documentation is written in YAML (module documentation) or `reStructuredText `_ (rST). Some collection-level documentation is written in a subset of `Markdown `_. If you are using Ansible, you already use YAML in your playbooks. rST and Markdown are mostly just text. You do not even need Git experience, if you use the ``Edit on GitHub`` option. If you find a typo, a broken example, a missing topic, or any other error or omission on this documentation website, let us know. Here are some ways to support Ansible documentation: @@ -74,7 +74,7 @@ A great documentation GitHub issue or PR includes: Verifying your documentation PR ================================ -If you make multiple changes to the documentation, or add more than a line to it, before you open a pull request, please: +If you make multiple changes to the Ansible documentation, or add more than a line to it, before you open a pull request, please: #. Check that your text follows our :ref:`style_guide`. #. Test your changes for rST errors. @@ -82,7 +82,8 @@ If you make multiple changes to the documentation, or add more than a line to it .. note:: - The following sections apply to documentation sourced from the ``ansible/ansible-documentation`` repo and does not apply to documentation from an individual collection. See the collection README file for details on how to contribute to that collection. + The following sections apply to documentation sourced from the ``ansible/ansible-documentation`` repo and does not apply to documentation from an individual collection. See the collection README file for details on how to contribute to that collection. Collection developers can also lint their collection-level documentation. See :ref:`verify_collection_docs` for details. + Setting up your environment to build documentation locally ---------------------------------------------------------- @@ -114,6 +115,11 @@ For more information on minimum Python versions, see the :ref:`support matrix `_ or using IRC at `irc.libera.chat `_). For more information, including links to our agenda and a calendar invite, visit our `forum group `_. +The Documentation Working Group (DaWGs) meets weekly on Tuesdays in the `docs:ansible.im chat room `_ on :ref:`Matrix`. For more information, including links to our agenda, visit our `forum group `_. .. seealso:: :ref:`More about testing module documentation ` diff --git a/docs/docsite/rst/community/ecosystem_project_resources.rst b/docs/docsite/rst/community/ecosystem_project_resources.rst new file mode 100644 index 00000000000..e9f681074a3 --- /dev/null +++ b/docs/docsite/rst/community/ecosystem_project_resources.rst @@ -0,0 +1,41 @@ +.. _ecosystem_project_dev_resources: + +*********************************************** +Ansible Ecosystem Project Development Resources +*********************************************** + +This document lists resources to help contributors interested in developing a community project in the `Ansible ecosystem `_. + +.. note:: + + Any improvements to the resources listed in this document or to the document itself are very welcome! Please submit an issue or pull request in the corresponding GitHub repository. + +.. _onboarding_toolkit: + +Onboarding toolkit +================== + +The `Ansible Onboarding toolkit `_ provides guidelines on setting up GitHub repositories for new projects as well as the type of documentation your project should include. + +Despite being originally developed for Ansible ecosystem projects under the ``ansible-community`` GitHub organization, everyone is welcome to use the onboarding toolkit. + +Project template +================ + +The `Ansible project-template `_ is a GitHub repository template for Ansible ecosystem projects that contains: + +* Files normally present in every repository such as README, license, code of conduct, and so on. +* A docsite template that you are encouraged to use with your project to provide a consistent experience across the Ansible project ecosystem. + +Please take a look at the `docsite `_ built from the project-template to see it in action. + +You are welcome to take the template, fill in your project-specific information, build it using `Sphinx `_, and then publish it. + +Even if your project is not new and already has documentation, we recommend you take a look at the template and check if there is anything missed in documentation for your project users, contributors, and maintainers. + +List of community-curated projects +================================== + +Whether your project repository is under the ``ansible-community`` GitHub organization or under your own one, you are welcome to include your project in the `Awesome Ansible list `_. + +Before letting the community know about your shiny project by adding it to the list, make sure it satisfies the standards explained in the :ref:`onboarding_toolkit` to provide the best user and contributor experience. diff --git a/docs/docsite/rst/community/getting_started.rst b/docs/docsite/rst/community/getting_started.rst index 5eb4c4689da..94dcf8ef057 100644 --- a/docs/docsite/rst/community/getting_started.rst +++ b/docs/docsite/rst/community/getting_started.rst @@ -21,8 +21,8 @@ Other ways to get involved Here are some other ways to connect with the Ansible community: -* Find an `Ansible Meetup near me `_ - communication +* Visit the :ref:`Ansible communication guide`. +* Find an `Ansible Meetup near you `_. * Learn more about Ansible: * `Read books `_. @@ -30,4 +30,3 @@ Here are some other ways to connect with the Ansible community: * `Attend events `_. * `Review getting started guides `_. * `Watch videos `_ - includes Ansible Automates, AnsibleFest & webinar recordings. -* See where `new releases are announced `_ diff --git a/docs/docsite/rst/community/how_can_I_help.rst b/docs/docsite/rst/community/how_can_I_help.rst index 8dfd0757885..0b0bd89bdc0 100644 --- a/docs/docsite/rst/community/how_can_I_help.rst +++ b/docs/docsite/rst/community/how_can_I_help.rst @@ -27,7 +27,8 @@ When you become a power user, your ability and opportunities to help the Ansible Ask and answer questions online =============================== -There are many forums online where Ansible users ask and answer questions. Reach out and communicate with your fellow Ansible users. +There are many online platforms where Ansible users and contributors ask and answer questions including the :ref:`ansible_forum`. +Reach out and communicate with your fellow Ansible enthusiasts. You can find the official :ref:`Ansible communication channels `. diff --git a/docs/docsite/rst/community/maintainers_guidelines.rst b/docs/docsite/rst/community/maintainers_guidelines.rst index c85f8a21b5e..af4912b57da 100644 --- a/docs/docsite/rst/community/maintainers_guidelines.rst +++ b/docs/docsite/rst/community/maintainers_guidelines.rst @@ -70,7 +70,7 @@ See the :ref:`Communication guide ` to learn more about real- Community Topics ---------------- -The Community and the `Steering Committee `_ asynchronously discuss and vote on the `Community Topics `_ which impact the whole project or its parts including collections and packaging. +The Community and the :ref:`Steering Committee ` asynchronously discuss and vote on the :ref:`community topics` which impact the whole project or its parts including collections and packaging. Share your opinion and vote on the topics to help the community make the best decisions. diff --git a/docs/docsite/rst/community/maintainers_workflow.rst b/docs/docsite/rst/community/maintainers_workflow.rst index 09675502e43..62c001c3fe1 100644 --- a/docs/docsite/rst/community/maintainers_workflow.rst +++ b/docs/docsite/rst/community/maintainers_workflow.rst @@ -51,7 +51,7 @@ Collection maintainers are responsible for releasing new versions of a collectio #. Planning and announcement. #. Generating a changelog. -#. Creating a release git tag and pushing it. +#. Creating a release Git tag and pushing it. #. Automatically publishing the release tarball on `Ansible Galaxy `_ through the `Zuul dashboard `_. #. Final announcement. #. Optionally, `file a request to include a new collection into the Ansible package `_. diff --git a/docs/docsite/rst/community/other_tools_and_programs.rst b/docs/docsite/rst/community/other_tools_and_programs.rst index 4a87c77e628..68589bb5a26 100644 --- a/docs/docsite/rst/community/other_tools_and_programs.rst +++ b/docs/docsite/rst/community/other_tools_and_programs.rst @@ -40,7 +40,7 @@ Sublime A closed-source, subscription GUI text editor. You can customize the GUI with themes and install packages for language highlighting and other refinements. You can install Sublime on Linux, macOS and Windows. Useful Sublime plugins include: -* `GitGutter `_ - shows information about files in a git repository. +* `GitGutter `_ - shows information about files in a Git repository. * `SideBarEnhancements `_ - provides enhancements to the operations on Sidebar of Files and Folders. * `Sublime Linter `_ - a code-linting framework for Sublime Text 3. * `Pretty YAML `_ - prettifies YAML for Sublime Text 2 and 3. @@ -99,7 +99,6 @@ Other tools =========== - `Ansible Inventory Grapher `_ - visually displays inventory inheritance hierarchies and at what level a variable is defined in inventory. -- `Ansible Shell `_ - an interactive shell for Ansible with built-in tab completion for all the modules. - `Ansible Silo `_ - a self-contained Ansible environment by Docker. - `Ansigenome `_ - a command line tool designed to help you manage your Ansible roles. - `antsibull-changelog `_ - a changelog generator for Ansible collections. diff --git a/docs/docsite/rst/community/reporting_bugs_and_features.rst b/docs/docsite/rst/community/reporting_bugs_and_features.rst index a972603af36..dd950bcd7e4 100644 --- a/docs/docsite/rst/community/reporting_bugs_and_features.rst +++ b/docs/docsite/rst/community/reporting_bugs_and_features.rst @@ -21,9 +21,9 @@ Ansible practices responsible disclosure. To report security-related bugs, send Bugs in ansible-core -------------------- -Before reporting a bug, search in GitHub for `already reported issues `_ and `open pull requests `_ to see if someone has already addressed your issue. Unsure if you found a bug? Report the behavior on the :ref:`mailing list or community chat first `. +Before reporting a bug, search in GitHub for `already reported issues `_ and `open pull requests `_ to see if someone has already addressed your issue. Unsure if you found a bug? Discuss the behavior with the community on the :ref:`Ansible Forum`. -Also, use the mailing list or chat to discuss whether the problem is in ``ansible-core`` or a collection, and for "how do I do this" type questions. +Also, use the :ref:`Ansible Forum` to discuss whether the problem is in ``ansible-core`` or a collection, and for "how do I do this" type questions. You need a free GitHub account to `report bugs `_ that affect: diff --git a/docs/docsite/rst/community/reporting_collections.rst b/docs/docsite/rst/community/reporting_collections.rst index fbcd6ca732e..2b4b211a087 100644 --- a/docs/docsite/rst/community/reporting_collections.rst +++ b/docs/docsite/rst/community/reporting_collections.rst @@ -25,7 +25,7 @@ Many bugs only affect a single module or plugin. If you find a bug that affects #. Click on the Issue Tracker link for that collection. #. Follow the contributor guidelines or instructions in the collection repo. -If you are not sure whether a bug is in ansible-core or a collection, you can report the behavior on the :ref:`mailing list or community chat channel first `. +If you are not sure whether a bug is in ansible-core or a collection, you can report the behavior on the :ref:`Ansible Forum`. Requesting a feature ==================== diff --git a/docs/docsite/rst/community/steering/community_steering_committee.rst b/docs/docsite/rst/community/steering/community_steering_committee.rst index b6192360599..e87687280c9 100644 --- a/docs/docsite/rst/community/steering/community_steering_committee.rst +++ b/docs/docsite/rst/community/steering/community_steering_committee.rst @@ -70,16 +70,18 @@ John Barker (`gundalow `_) has been elected by the Committee members are selected based on their active contribution to the Ansible Project and its community. See :ref:`community_steering_guidelines` to learn details. +.. _creating_community_topic: + Creating new policy proposals & inclusion requests ---------------------------------------------------- The Committee uses the `Ansible Forum `_ to asynchronously discuss with the Community and vote on the proposals in corresponding `community topics `_. -You can create a `community topic `_ if you want to discuss an idea that impacts any of the following: +You can `create a community topic `_ (make sure you use the ``Project Discussions`` category and the ``community-wg`` tag) if you want to discuss an idea that impacts any of the following: * Ansible Community * Community collection best practices and requirements - * Community collection inclusion policy + * Community collection inclusion/exclusion policy and workflow * The Community governance * Other proposals of importance that need the Committee's or overall Ansible community attention @@ -96,7 +98,10 @@ Depending on a topic you want to discuss with the Community and the Committee, a * :ref:`code_of_conduct`. * :ref:`collections_requirements`. -* `Ansible Collection Inclusion Checklist `_. +* `Ansible Collection Inclusion Checklist `_. +* :ref:`removal_from_ansible`. + +.. _community_topics_workflow: Community topics workflow ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,19 +147,25 @@ When reviewing community collection `inclusion requests `_ into a corresponding `discussion `_. +#. A Committee member who conducts the inclusion review copies the `Ansible community collection checklist `_ into a corresponding `discussion `_. #. In the course of the review, the Committee member marks items as completed or leaves a comment saying whether the reviewer expects an issue to be addressed or whether it is optional (for example, it could be **MUST FIX:** or **SHOULD FIX:** under an item). #. For a collection to be included in the Ansible community package, the collection: - * MUST be reviewed and approved by at least two persons, where at least one person is a Steering Committee member. - * For a Non-Steering Committee review to be counted for inclusion, it MUST be checked and approved by *another* Steering Committee member. - * Reviewers must not be involved significantly in development of the collection. They must declare any potential conflict of interest (for example, being friends/relatives/coworkers of the maintainers/authors, being users of the collection, or having contributed to that collection recently or in the past). + * MUST be reviewed and approved as compliant with the requirements by at least two Steering Committee members. + + * At least one of the reviews checks compliance with the entire checklist. + * All subsequent reviews can focus only on compliance with documentation and development conventions. + + * Reviewers must not be involved significantly in development of the collection. They MUST declare any potential conflict of interest (for example, being friends/relatives/coworkers of the maintainers/authors, being users of the collection, or having contributed to that collection recently or in the past). -#. After the collection gets two or more Committee member approvals, a Committee member creates a `community topic `_ linked to the corresponding inclusion request. The issue's description says that the collection has been approved by two or more Committee members and establishes a date (a week by default) when the inclusion decision will be considered made. This time period can be used to raise concerns. +#. After the collection gets two Committee member approvals, a Committee member creates a `community topic `_ linked to the corresponding inclusion request. The issue's description says that the collection has been approved by the Committee and establishes a date (a week by default) when the inclusion decision will be considered made. -#. If no objections are raised up to the established date, the inclusion request is considered successfully resolved. In this case, a Committee member: + * The inclusion automatically gets suspended if the Committee members raise concerns or start another inclusion review within this time period. + * When there are no more objections or ongoing inclusion reviews, the inclusion date gets prolonged for another week. + +#. If the inclusion has not been suspended by the established date, the inclusion request is considered successfully resolved. In this case, a Committee member: #. Declares the decision in the topic and in the inclusion request. #. Moves the request to the ``Resolved reviews`` category. @@ -162,6 +173,13 @@ When reviewing community collection `inclusion requests `_. #. Closes the topic. +Collection exclusion workflow +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Committee uses the :ref:`removal_from_ansible` to remove collections not satisfying the :ref:`collections_requirements` from the Ansible package. + +.. _community_wg_meetings: + Community Working Group meetings --------------------------------- diff --git a/docs/docsite/rst/community/steering/community_topics_workflow.rst b/docs/docsite/rst/community/steering/community_topics_workflow.rst index 5cc0a0ead50..0e32d516d37 100644 --- a/docs/docsite/rst/community/steering/community_topics_workflow.rst +++ b/docs/docsite/rst/community/steering/community_topics_workflow.rst @@ -6,121 +6,123 @@ .. _community_topics_workflow: -Ansible community topics workflow -================================= +Community topics workflow +========================= Overview -------- -This document describes the Ansible community topics workflow (herein after ``Workflow``) to provide guidance on successful resolving topics in an asynchronous way. +This document describes the Ansible community topics workflow to provide guidance on successful resolving topics in the asynchronous way. -The Workflow is a set of actions that need to be done successively within the corresponding time frames. +The workflow is a set of actions that need to be completed in order within the corresponding time frames. .. note:: - If you have any ideas on how the Workflow can be improved, please create an issue in this repository or pull request against this document. + The following section outlines a generic scenario for a workflow. + Workflows can vary depending on a topic's complexity and other nuances; for example, when there is a mass agreement from the beginning. Creating a topic ---------------- -Any person can `create a topic `_ tagged with ``community-wg`` under the ``Project Discussions`` category in the `Ansible Forum `_. A :ref:`Steering Committee member` can tag the forum post with `community-wg-nextmtg` to put it on the meeting agenda. - -Workflow --------- - -.. note:: - - This is a rough scenario and it can vary depending on a topic's complexity and other nuances, for example, when there is a mass agreement upfront. +Any person can :ref:`create a community topic`. Preparation stage -^^^^^^^^^^^^^^^^^ +----------------- -A Committee person checks the topic content and asks the author, or other persons, to provide additional information if needed. +* A Committee person checks the topic's content and asks the author/other persons to provide additional information as needed. Discussion stage -^^^^^^^^^^^^^^^^ - -* If the topic is ready to be discussed, the Committee person: - - * Adds the ``community-wg-nextmtg`` tag if it needs to be discussed in the meeting. +---------------- - * Opens the discussion by adding a comment asking the Community and the Committee to take part in it. +* By default, the discussion happens asynchronously in the topic. -* No synchronous discussion is needed (there are no blockers, complications, confusion, or impasses). + * A :ref:`steering committee ` member can tag the forum post with ``community-wg-nextmtg`` to put it on the synchronous meeting agenda. Voting stage -^^^^^^^^^^^^ - -* Depending on the topic complexity, 1-2 weeks after the discussion was opened, the Committee person formulates vote options based on the prior discussion and gives participants a reasonable amount of time to propose changes to the options (no longer than a week). The person summarizes the options in a comment and also establishes a date when the vote begins if there are no objections about the options or vote date. -* In the vote date, the vote starts with a comment from a Committee person who opens the vote and establishes a date when the vote ends ($CURRENT_DATE + no longer than 21 days; Usually it should not exceed 14 days. 21 days should only be used if it is known that a lot of interested persons will likely not have time to vote in a 14 day period). -* The Committee person labels the topic with the ``active-vote`` tag. -* The Committee person adds ``[Vote ends on $YYYY-MM-DD]`` to the beginning of the topic description. -* A vote is actually two polls, one for the Steering Committee, one for everyone else. To create a vote in a topic: - - * Create a new post in the topic. - - * Click the ``gear`` button in the composer and select ``Build Poll``. - - * Click the ``gear`` in the Poll Builder for advanced mode. +------------ - * Set up the options (generally this will be Single Choice but other poll types can be used). +The Committee person: - * Title it "Steering Committee vote" and "Limit voting" to the ``Steering Committee``. +* Formulates vote options based on the prior discussion and gives participants up to one week to propose changes to the options. This step takes place one to two weeks after the discussion was opened, depending on the complexity of the topic. +* Summarizes the options in a comment and establishes a date for the vote to begin if there are no objections to the options. +* Starts the vote on the beginning date and establishes an end date, which is $CURRENT_DATE plus: - * Do not set the close date because it cannot be changed later. + * 7 days: simple cases + * 14 days: maximum vote length + * 21 days: only used in exceptional cases such as holiday seasons when the majority of the Committee are not able to participate in the vote +* Labels the topic with the ``active-vote`` tag. +* Adds ``[Vote ends on $YYYY-MM-DD]`` to the beginning of the topic's description. - * Results should be "Always Visible" unless there is some good reason for the SC votes not to be public. - - * Submit the poll (the BBcode will appear in the post) and then repeat the above for the second poll. - - * The title should be "Community vote". +The vote always consists of two polls: one for the Steering Committee, one for everyone else. To create a vote in a topic: + * Create a new post in the topic. + * Click the ``gear`` button in the composer and select ``Build Poll``. + * Click the ``gear`` in the ``Poll Builder`` for advanced mode. + * Set up the options (generally this will be ``Single Choice`` but other poll types can be used). + * Title it "Steering Committee vote" and ``Limit voting`` to the ``@SteeringCommittee``. + * Do NOT set the close date because this cannot be changed later. + * Results should be ``Always Visible`` unless there is a good reason for the SC votes not to be public. + * Submit the poll (the BBcode will appear in the post): + * Repeat the above steps for the second poll: + + * Title should be "Community vote". * No group limitation. Voting result stage -^^^^^^^^^^^^^^^^^^^ - -* The day after the last day of the vote, the Committee person: - - * Closes the polls. - - * Removes the ``active-vote`` tag. +------------------- - * Add a comment that the vote ended. - - * Changes the beginning of the topic's description to ``[Vote ended]``. - - * Creates a summary comment declaring the vote result. - -* The vote result and final decision are announced via the `Bullhorn newsletter `_. +On the vote end date, the Committee person: +* Closes the polls if the :ref:`quorum` is reached, otherwise prolongs the polls. +* Removes the ``active-vote`` tag. +* Adds a comment that the vote has ended. +* Changes the beginning of the topic's description to ``[Vote ended]``. +* Creates a summary comment declaring the vote result. +* Announces the vote result and the final decision in the :ref:`Bullhorn `. Implementation stage -^^^^^^^^^^^^^^^^^^^^ +-------------------- -* If the topic implies some actions (if it does not, just mark this as complete), the Committee person: +No further action required +~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Assigns the topic to the person who is responsible for performing the actions. +The Committee person: - * Add the ``being-implemented`` tag to the topic. +* Merges an associated pull request if exists. +* Adds the ``resolved`` tag. - * After the topic is implemented, the assignee: +Further actions required +~~~~~~~~~~~~~~~~~~~~~~~~ - * Comments on the topic that the work is done. +The Committee person: - * Removes the ``being-implemented`` tag. +* Assigns a person responsible for performing the actions by mentioning them in a comment. +* Adds the ``being-implemented`` tag to the topic. - * Add the ``implemented`` tag. +After the actions are done, the assignee: -* If the topic implies actions related to the future Ansible Community package releases (for example, a collection exclusion), the Committee person: +* Comments on the topic that the work is done. +* Removes the ``being-implemented`` tag. +* Adds the ``implemented`` and ``resolved`` tags. - * Adds the ``scheduled-for-future-release`` tag to the topic. +Package-release related actions required +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Checks if there is a corresponding milestone in the `ansible-build-data `_ repository. If there is no milestone, the person creates it. +If the topic implies actions related to the future Ansible community package releases (for example, a collection exclusion), the Committee person/assignee: - * Creates an issue in ansible-build-data that references the topic in community-topics, and adds it to the milestone. +* Adds the ``scheduled-for-future-release`` tag to the topic. +* Checks if there is a corresponding milestone in the `ansible-build-data `_ repository. + + * If there is no milestone, the person creates it. +* Creates an issue in ``ansible-build-data`` that references the topic and adds it to the milestone. +* After it is implemented, adds the ``implemented`` and ``resolved`` tags. Tools ----- -We have some `scripts `_ that can be used to create Ansible community announcements in the Bullhorn and similar places. +There are a few `scripts `_ that can be used to create Ansible community announcements on the Bullhorn and similar locations. + +.. seealso:: + + :ref:`steering committee ` + Ansible Community Steering Committee diff --git a/docs/docsite/rst/community/steering/steering_committee_membership.rst b/docs/docsite/rst/community/steering/steering_committee_membership.rst index d566ebbd821..9c648cc85ab 100644 --- a/docs/docsite/rst/community/steering/steering_committee_membership.rst +++ b/docs/docsite/rst/community/steering/steering_committee_membership.rst @@ -1,7 +1,7 @@ .. THIS DOCUMENT IS OWNED BY THE ANSIBLE COMMUNITY STEERING COMMITTEE. ALL CHANGES MUST BE APPROVED BY THE STEERING COMMITTEE! For small changes (fixing typos, language errors, etc.) create a PR and ping @ansible/steering-committee. - For other changes, create a discussion in https://github.com/ansible-community/community-topics/ to discuss the changes. + For other changes, create a :ref:`community topic` to discuss the changes. (Creating a draft PR for this file and mentioning it in the community topic is also OK.) .. _community_steering_guidelines: @@ -46,10 +46,14 @@ Team membership The Committee can accept a team to be a member. In this case, the team chooses its representative and announces the person in a dedicated `Community Topic `_. -After the announcement is made, the new representative is added to the `SteeringCommittee ` group on the forum, and the previous representative is removed from that group. +After the announcement is made, the new representative is added to the `SteeringCommittee `_ group on the forum, and the previous representative is removed from that group. The team uses the same Community Topic for announcing subsequent representative changes. Representatives should commit to at least two months of membership. +The team representative must still abide by all expectations listed in :ref:`steering_expectations`, including those surrounding participation. +Steering Committee members are generally expected to participate in discussions — asynchronously on the forum and/or synchronously in meetings — and votes, +even if the issue in question does not entirely pertain to the team they represent. + Process ^^^^^^^^ diff --git a/docs/docsite/rst/community/steering/steering_committee_past_members.rst b/docs/docsite/rst/community/steering/steering_committee_past_members.rst index f193c39a230..e1960857483 100644 --- a/docs/docsite/rst/community/steering/steering_committee_past_members.rst +++ b/docs/docsite/rst/community/steering/steering_committee_past_members.rst @@ -1,7 +1,7 @@ .. THIS DOCUMENT IS OWNED BY THE ANSIBLE COMMUNITY STEERING COMMITTEE. ALL CHANGES MUST BE APPROVED BY THE STEERING COMMITTEE! For small changes (fixing typos, language errors, etc.) create a PR and ping @ansible/steering-committee. - For other changes, create a discussion in https://github.com/ansible-community/community-topics/ to discuss the changes. + For other changes, create a :ref:`community topic` to discuss the changes. (Creating a draft PR for this file and mentioning it in the community topic is also OK.) .. _steering_past_members: diff --git a/docs/docsite/rst/community/steering/steering_index.rst b/docs/docsite/rst/community/steering/steering_index.rst index 877324072b7..0a0f04c183f 100644 --- a/docs/docsite/rst/community/steering/steering_index.rst +++ b/docs/docsite/rst/community/steering/steering_index.rst @@ -1,7 +1,7 @@ .. THIS DOCUMENT IS OWNED BY THE ANSIBLE COMMUNITY STEERING COMMITTEE. ALL CHANGES MUST BE APPROVED BY THE STEERING COMMITTEE! For small changes (fixing typos, language errors, etc.) create a PR and ping @ansible/steering-committee. - For other changes, create a discussion in https://github.com/ansible-community/community-topics/ to discuss the changes. + For other changes, create a :ref:`community topic` to discuss the changes. (Creating a draft PR for this file and mentioning it in the community topic is also OK.) .. _community_steering_committee: diff --git a/docs/docsite/rst/conf.py b/docs/docsite/rst/conf.py index 339382948c2..3f66caaa887 100644 --- a/docs/docsite/rst/conf.py +++ b/docs/docsite/rst/conf.py @@ -127,6 +127,7 @@ 'community/collection_contributors/collection_test_pr_locally.rst', 'community/collection_contributors/collection_integration_tests.rst', 'community/collection_contributors/collection_integration_running.rst', + 'community/collection_contributors/collection_package_removal.rst', 'community/collection_contributors/collection_reviewing.rst', 'community/collection_contributors/collection_requirements.rst', 'community/collection_contributors/collection_unit_tests.rst', @@ -239,16 +240,16 @@ 'current_version': version, 'latest_version': ( 'devel' if tags.has('all') else - '2.16' if tags.has('core_lang') or tags.has('core') else - '9' if tags.has('ansible') + '2.17' if tags.has('core_lang') or tags.has('core') else + '10' if tags.has('ansible') else '' ), # list specifically out of order to make latest work 'available_versions': ( ('devel',) if tags.has('all') else ('2.15_ja', '2.14_ja', '2.13_ja',) if tags.has('core_lang') else - ('2.16', '2.15', '2.14', 'devel',) if tags.has('core') else - ('latest', '2.9', 'devel') if tags.has('ansible') + ('2.17', '2.16', '2.15', 'devel',) if tags.has('core') else + ('latest', '9', '2.9', 'devel') if tags.has('ansible') else '' ), } @@ -379,6 +380,7 @@ 'jinja2': ('http://jinja.palletsprojects.com/', None), 'ansible_2_9': ('https://docs.ansible.com/ansible/2.9/', None), 'ansible_9': ('https://docs.ansible.com/ansible/9/', None), + 'ansible_10': ('https://docs.ansible.com/ansible/10/', None), } # linckchecker settings diff --git a/docs/docsite/rst/dev_guide/developing_api.rst b/docs/docsite/rst/dev_guide/developing_api.rst index 3ea552a2132..d7fed9bea78 100644 --- a/docs/docsite/rst/dev_guide/developing_api.rst +++ b/docs/docsite/rst/dev_guide/developing_api.rst @@ -6,33 +6,11 @@ Python API .. contents:: Topics -.. note:: This API is intended for internal Ansible use. Ansible may make changes to this API at any time that could break backward compatibility with older versions of the API. Because of this, external use is not supported by Ansible. If you want to use Python API only for executing playbooks or modules, consider `ansible-runner `_ first. - -There are several ways to use Ansible from an API perspective. You can use -the Ansible Python API to control nodes, you can extend Ansible to respond to various Python events, you can -write plugins, and you can plug in inventory data from external data sources. This document -gives a basic overview and examples of the Ansible execution and playbook API. +.. attention:: The Ansible API is intended for internal Ansible use. Ansible may make changes to this API at any time that could break backward compatibility with older versions of the API. Because of this, external use is not supported by Ansible. If you want to use Python API only for executing playbooks or modules, consider `ansible-runner `_ first. If you would like to use Ansible programmatically from a language other than Python, trigger events asynchronously, or have access control and logging demands, please see the `AWX project `_. -.. note:: Because Ansible relies on forking processes, this API is not thread safe. - -.. _python_api_example: - -Python API example -================== - -This example is a simple demonstration that shows how to minimally run a couple of tasks: - -.. literalinclude:: ../../../../examples/scripts/uptime.py - :language: python - -.. note:: Ansible emits warnings and errors through the display object, which prints directly to stdout, stderr and the Ansible log. - -The source code for the ``ansible`` -command line tools (``lib/ansible/cli/``) is `available on GitHub `_. - .. seealso:: :ref:`developing_inventory` @@ -41,7 +19,5 @@ command line tools (``lib/ansible/cli/``) is `available on GitHub `_ - Mailing list for development topics - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections.rst b/docs/docsite/rst/dev_guide/developing_collections.rst index b507cd3ef1b..6bfbfbb9fb3 100644 --- a/docs/docsite/rst/dev_guide/developing_collections.rst +++ b/docs/docsite/rst/dev_guide/developing_collections.rst @@ -43,9 +43,5 @@ For instructions on developing modules, see :ref:`developing_modules_general`. Learn how to install and use collections in playbooks and roles :ref:`contributing_maintained_collections` Guidelines for contributing to selected collections - `Ansible Collections Overview and FAQ `_ - Current development status of community collections and FAQ - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_changelogs.rst b/docs/docsite/rst/dev_guide/developing_collections_changelogs.rst index 3e164090d2b..334bfd87753 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_changelogs.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_changelogs.rst @@ -76,7 +76,5 @@ If your collection is part of Ansible, use one of the following three options t Learn how to install and use collections. :ref:`contributing_maintained_collections` Guidelines for contributing to selected collections - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_contributing.rst b/docs/docsite/rst/dev_guide/developing_collections_contributing.rst index d1751723eb8..a1e2984b20c 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_contributing.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_contributing.rst @@ -4,7 +4,7 @@ Contributing to collections *************************** -If you want to add functionality to an existing collection, modify a collection you are using to fix a bug, or change the behavior of a module in a collection, clone the git repository for that collection and make changes on a branch. You can combine changes to a collection with a local checkout of Ansible (``source hacking/env-setup``). +If you want to add functionality to an existing collection, modify a collection you are using to fix a bug, or change the behavior of a module in a collection, clone the Git repository for that collection and make changes on a branch. You can combine changes to a collection with a local checkout of Ansible (``source hacking/env-setup``). You should first check the collection repository to see if it has specific contribution guidelines. These are typically listed in the README.md or CONTRIBUTING.md files within the repository. See :ref:`collection_quickstart` for more general guidelines and :ref:`testing_running_locally` for testing guidelines. @@ -60,7 +60,5 @@ You can test your changes by using this checkout of ``community.general`` in pla Learn how to install and use collections. :ref:`contributing_maintained_collections` Guidelines for contributing to selected collections - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_creating.rst b/docs/docsite/rst/dev_guide/developing_collections_creating.rst index deff8fb1b63..af44d273696 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_creating.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_creating.rst @@ -6,7 +6,7 @@ Creating collections To create a collection: -#. Create a :ref:`new collection`, optionally using a custom :ref:`collection template`, with the ``ansible-galaxy collection init`` command. +#. Create a :ref:`new collection`, optionally using a custom :ref:`collection template`, with the ``ansible-galaxy collection init`` command. #. Add modules and other content to the collection. #. Build the collection into a collection artifact with :ref:`ansible-galaxy collection build`. #. Publish the collection artifact to Galaxy with :ref:`ansible-galaxy collection publish`. @@ -26,23 +26,23 @@ Collection names consist of a namespace and a name, separated by a period (``.`` Usually namespaces and names use lower-case letters, digits, and underscores, but no upper-case letters. -You should make sure that the namespace you use is not registered by someone else by checking on `Ansible Galaxy's namespace list `__. If you chose a namespace or even a full collection name that collides with another collection on Galaxy, it can happen that if you or someone else runs ``ansible-galaxy collection install`` with your collection name, you end up with another collection. Even if the namespace currently does not exist, it could be created later by someone else. +You should make sure that the namespace you use is not registered by someone else by checking on `Ansible Galaxy's namespace list `_. If you chose a namespace or even a full collection name that collides with another collection on Galaxy, it can happen that if you or someone else runs ``ansible-galaxy collection install`` with your collection name, you end up with another collection. Even if the namespace currently does not exist, it could be created later by someone else. -If you want to request a new namespace on Ansible Galaxy, `create an issue on github.com/ansible/galaxy `__. +If you want to request a new namespace on Ansible Galaxy, `create an issue on github.com/ansible/galaxy `_. There are a few special namespaces: :ansible: - The `ansible namespace `__ is owned by Red Hat and reserved for official Ansible collections. Two special members are the synthetic ``ansible.builtin`` and ``ansible.legacy`` collections. These cannot be found on Ansible Galaxy, but are built-in into ansible-core. + The `ansible namespace `_ is owned by Red Hat and reserved for official Ansible collections. Two special members are the synthetic ``ansible.builtin`` and ``ansible.legacy`` collections. These cannot be found on Ansible Galaxy, but are built-in into ansible-core. :community: - The `community namespace `__ is owned by the Ansible community. Collections from this namespace generally live in the `GitHub ansible-collection organization `__. If you want to create a collection in this namespace, it is best to `create an issue in github.com/ansible-collections/overview `__. + The `community namespace `_ is owned by the Ansible community. Collections from this namespace generally live in the `GitHub ansible-collection organization `_. If you want to create a collection in this namespace, :ref:`request` it on the forum. :local: - The `local namespace `__ does not contain any collection on Ansible Galaxy, and the intention is that this will never change. You can use the ``local`` namespace for collections that are locally on your machine or locally in your git repositories, without having to fear collisions with actually existing collections on Ansible Galaxy. + The `local namespace `_ does not contain any collection on Ansible Galaxy, and the intention is that this will never change. You can use the ``local`` namespace for collections that are locally on your machine or locally in your Git repositories, without having to fear collisions with actually existing collections on Ansible Galaxy. .. _creating_new_collections: @@ -79,7 +79,7 @@ Currently the ``ansible-galaxy collection`` command implements the following sub To learn more about the ``ansible-galaxy`` command-line tool, see the :ref:`ansible-galaxy` man page. -.. _creating_collection_skeletons: +.. _creating_collection_from_custom_template: Creating a collection from a custom template ============================================ @@ -111,13 +111,29 @@ To initialize a collection using the new template, pass the path to the skeleton The default collection skeleton uses an internal filter ``comment_ify`` that isn't accessibly to ``--collection-skeleton``. Use ``ansible-doc -t filter|test --list`` to see available plugins. +.. _creating_collection_with_ansible-creator: + +Creating collections with ansible-creator +========================================= + +`ansible-creator `_ is designed to quickly scaffold an Ansible collection project. + +.. note:: + + The `Ansible Development Tools `_ package offers a convenient way to install ``ansible-creator`` along with a curated set of tools for developing automation content. + +After `installing `_ ``ansible-creator`` you can initialize a project in one of the following ways: + +* Use the `init `_ subcommand. +* Use ``ansible-creator`` with the `Ansible extension `_ in Visual Studio Code. + .. seealso:: :ref:`collections` Learn how to install and use collections. :ref:`collection_structure` Directories and files included in the collection skeleton - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + `Ansible Development Tools (ADT) `_ + Python package of tools to create and test Ansible content. + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_distributing.rst b/docs/docsite/rst/dev_guide/developing_collections_distributing.rst index 59c08a6d60f..1569d22f83c 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_distributing.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_distributing.rst @@ -301,7 +301,7 @@ Installing your collection locally You have two options for installing your collection locally: * Install your collection locally from the tarball. - * Install your collection locally from your git repository. + * Install your collection locally from your Git repository. Installing your collection locally from the tarball ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -316,10 +316,10 @@ Install the tarball into a directory configured in :ref:`COLLECTIONS_PATHS` so A .. _collections_scm_install: -Installing your collection locally from a git repository +Installing your collection locally from a Git repository ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To install your collection locally from a git repository, specify the repository and the branch you want to install: +To install your collection locally from a Git repository, specify the repository and the branch you want to install: .. code-block:: bash @@ -400,7 +400,5 @@ After Galaxy uploads and accepts a collection, the website shows you the **My Im Learn how to install and use collections. :ref:`collections_galaxy_meta` Table of fields used in the :file:`galaxy.yml` file - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_documenting.rst b/docs/docsite/rst/dev_guide/developing_collections_documenting.rst index f80b75e9384..456fc5c7593 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_documenting.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_documenting.rst @@ -14,6 +14,16 @@ Documenting roles To document a role, you have to add a role argument spec by creating a file ``meta/argument_specs.yml`` in your role. See :ref:`role_argument_spec` for details. As an example, you can look at `the argument specs file `_ of the :ansplugin:`sensu.sensu_go.install role ` on GitHub. + +.. _verify_collection_docs: + +Verifying your collection documentation +======================================= + +You can use ``antsibull-docs`` to lint your collection documentation. +See `Linting collection documentation `_. +for details. + .. _build_collection_docsite: Build a docsite with antsibull-docs diff --git a/docs/docsite/rst/dev_guide/developing_collections_migrating.rst b/docs/docsite/rst/dev_guide/developing_collections_migrating.rst index 5cfa51ae2af..9a5959d7242 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_migrating.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_migrating.rst @@ -4,7 +4,8 @@ Migrating Ansible content to a different collection *************************************************** -When you move content from one collection to another, for example to extract a set of related modules out of ``community.general`` to create a more focused collection, you must make sure the transition is easy for users to follow. +You might decide to move content from one collection to another; for example, to extract a set of related modules out of ``community.general`` or ``community.network`` to create a more focused collection. +When you migrate content between collections, you must take certain steps to ensure users can follow the transition. .. contents:: :local: @@ -13,18 +14,18 @@ When you move content from one collection to another, for example to extract a s Migrating content ================= -Before you start migrating content from one collection to another, look at `Ansible Collection Requirements `_. - -To migrate content from one collection to another, if the collections are parts of `Ansible distribution `_: +If the collection from which you are going to migrate content is included in the `Ansible community package `_, ensure the target collection satisfies the :ref:`collections_requirements`. After you satisfy the requirements, you can migrate the content as follows: #. Copy content from the source (old) collection to the target (new) collection. +#. Change ``M()``, examples, ``seealso``, ``extended_documentation_fragments`` to use actual FQCNs in moved content, old collection, and in other collections that have references to the content. +#. Move all related issues, pull requests, and wiki pages. +#. Look through the ``docs/docsite`` directory of the `ansible-documentation GitHub repository `_ (for example, using the ``grep`` command-line utility) to check if there are examples using the moved modules and plugins so that you can update those FQCNs. #. Deprecate the module/plugin with ``removal_version`` scheduled for the next major version in ``meta/runtime.yml`` of the old collection. The deprecation must be released after the copied content has been included in a release of the new collection. #. When the next major release of the old collection is prepared: * remove the module/plugin from the old collection - * remove the symlink stored in ``plugin/modules`` directory if appropriate (mainly when removing from ``community.general`` and ``community.network``) * remove related unit and integration tests - * remove specific module utils + * remove specific module utils (if they are NOT used by other modules/plugins or ``module_utils``) * remove specific documentation fragments if there are any in the old collection * add a changelog fragment containing entries for ``removed_features`` and ``breaking_changes``; you can see an example of a changelog fragment in this `pull request `_ * change ``meta/runtime.yml`` in the old collection: @@ -130,7 +131,5 @@ Ansibulbot will know how to redirect existing issues and PRs to the new repo. Th Learn how to install and use collections. :ref:`contributing_maintained_collections` Guidelines for contributing to selected collections - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_path.rst b/docs/docsite/rst/dev_guide/developing_collections_path.rst index 2c4d108e070..9f28a639941 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_path.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_path.rst @@ -79,7 +79,7 @@ Publish your collection source code Publish your collection on a platform for software development and version control such as `GitHub `_. It can be your personal repository or your organization's one. -You can also `request `_ a repository under the `ansible-collections `_ organization. +You can also :ref:`request` a repository under the `ansible-collections `_ organization. Make sure your collection contains exhaustive license information. Ansible is an open source project, so we encourage you to license it under one of open source licenses. diff --git a/docs/docsite/rst/dev_guide/developing_collections_shared.rst b/docs/docsite/rst/dev_guide/developing_collections_shared.rst index 34db6aea696..11da101d24f 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_shared.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_shared.rst @@ -72,7 +72,7 @@ Listing collection dependencies We recommend that collections work as standalone, independent units, depending only on ansible-core. However, if your collection must depend on features and functionality from another collection, list the other collection or collections under ``dependencies`` in your collection's :file:`galaxy.yml` file. Use the :file:`meta/runtime.yml` file to set the ansible-core version that your collection depends on. For more information on the :file:`galaxy.yml` file, see :ref:`collections_galaxy_meta`. -You can use git repositories for collection dependencies during local development and testing. For example: +You can use Git repositories for collection dependencies during local development and testing. For example: .. code-block:: yaml @@ -80,7 +80,7 @@ You can use git repositories for collection dependencies during local developmen .. warning:: - Do not use git repositories as dependencies for published collections. Dependencies for published collections must be other published collections. + Do not use Git repositories as dependencies for published collections. Dependencies for published collections must be other published collections. .. seealso:: @@ -88,7 +88,5 @@ You can use git repositories for collection dependencies during local developmen Learn how to install and use collections. :ref:`contributing_maintained_collections` Guidelines for contributing to selected collections - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_structure.rst b/docs/docsite/rst/dev_guide/developing_collections_structure.rst index 4b2139adc75..a75c4a7f29b 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_structure.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_structure.rst @@ -204,7 +204,7 @@ Ansible Collections are tested much like Ansible itself, by using the `ansible-t See :ref:`testing_collections` for specific information on how to test collections with ``ansible-test``. -When reading the :ref:`developing_testing` documentation, there will be content that applies to running Ansible from source code through a git clone, which is typical of an Ansible developer. However, it is not always typical for an Ansible Collection author to be running Ansible from source but instead from a stable release, and to create Collections it is not necessary to run Ansible from source. Therefore, when references of dealing with `ansible-test` binary paths, command completion, or environment variables are presented throughout the :ref:`developing_testing` documentation; keep in mind that it is not needed for Ansible Collection Testing because the act of installing the stable release of Ansible containing `ansible-test` is expected to setup those things for you. +When reading the :ref:`developing_testing` documentation, there will be content that applies to running Ansible from source code through a Git clone, which is typical of an Ansible developer. However, it is not always typical for an Ansible Collection author to be running Ansible from source but instead from a stable release, and to create Collections it is not necessary to run Ansible from source. Therefore, when references of dealing with `ansible-test` binary paths, command completion, or environment variables are presented throughout the :ref:`developing_testing` documentation; keep in mind that it is not needed for Ansible Collection Testing because the act of installing the stable release of Ansible containing `ansible-test` is expected to setup those things for you. meta directory @@ -290,7 +290,7 @@ execution_environments.yml ^^^^^^^^^^^^^^^^^^^^^^^^^^ If your collection has requirements, you can specify them in the ``execution-environment.yml`` file in the ``meta`` directory. -This ensures users do not need to add these requirements manually when building `Execution Environments `_ containing your collection. +This ensures users do not need to add these requirements manually when building :ref:`Execution Environments` containing your collection. See the `collection-level metadata guide `_ for details. .. seealso:: @@ -299,7 +299,5 @@ See the `collection-level metadata guide `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_collections_testing.rst b/docs/docsite/rst/dev_guide/developing_collections_testing.rst index e24495e3d08..f89f5d83234 100644 --- a/docs/docsite/rst/dev_guide/developing_collections_testing.rst +++ b/docs/docsite/rst/dev_guide/developing_collections_testing.rst @@ -102,7 +102,5 @@ You can specify multiple target names. Each target name is the name of a directo More resources on testing Ansible :ref:`contributing_maintained_collections` Guidelines for contributing to selected collections - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_core.rst b/docs/docsite/rst/dev_guide/developing_core.rst index ce8b95ece4a..42cb35a8d16 100644 --- a/docs/docsite/rst/dev_guide/developing_core.rst +++ b/docs/docsite/rst/dev_guide/developing_core.rst @@ -16,7 +16,5 @@ Although ``ansible-core`` (the code hosted in the `ansible/ansible repository `_ - The development mailing list - `irc.libera.chat `_ - #ansible-devel IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_inventory.rst b/docs/docsite/rst/dev_guide/developing_inventory.rst index 3558e1326c4..dfef1c3b260 100644 --- a/docs/docsite/rst/dev_guide/developing_inventory.rst +++ b/docs/docsite/rst/dev_guide/developing_inventory.rst @@ -508,7 +508,5 @@ An easy way to see how this should look is using :ref:`ansible-inventory`, which How to develop plugins `AWX `_ REST API endpoint and GUI for Ansible, syncs with dynamic inventory - `Development Mailing List `_ - Mailing list for development topics - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_locally.rst b/docs/docsite/rst/dev_guide/developing_locally.rst index e39ff154008..73cc7138151 100644 --- a/docs/docsite/rst/dev_guide/developing_locally.rst +++ b/docs/docsite/rst/dev_guide/developing_locally.rst @@ -137,6 +137,10 @@ Ansible automatically loads all plugins from certain directories adjacent to you Roles contained in collections cannot contain any plugins. All plugins in a collection must live in the collection ``plugins`` directory tree. All plugins in that tree are accessible to all roles in the collection. If you are developing new plugins, we recommend distributing them in :ref:`collections `, not in roles. +.. warning:: + + Some plugin types are needed early during Ansible execution, such as callbacks, inventory, and cache. These plugin types cannot be loaded dynamically and must exist in configured paths or be referenced by FQCN in configuration. + .. _ansible.legacy.custom: Using ``ansible.legacy`` to access custom versions of an ``ansible.builtin`` module diff --git a/docs/docsite/rst/dev_guide/developing_modules.rst b/docs/docsite/rst/dev_guide/developing_modules.rst index d8eb2a56189..42d6d6fa3cd 100644 --- a/docs/docsite/rst/dev_guide/developing_modules.rst +++ b/docs/docsite/rst/dev_guide/developing_modules.rst @@ -45,7 +45,5 @@ If your use case isn't covered by an existing module, an action plugin, or a rol :ref:`list_of_collections` Browse existing collections, modules, and plugins - `Mailing List `_ - Development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/developing_modules_checklist.rst b/docs/docsite/rst/dev_guide/developing_modules_checklist.rst index c64f3f4170d..405389750e6 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_checklist.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_checklist.rst @@ -31,7 +31,7 @@ To contribute a module to most Ansible collections, you must: Additional requirements may apply for certain collections. Review the individual collection repositories for more information. -Please make sure your module meets these requirements before you submit your PR/proposal. If you have questions, reach out by using the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) or the `Ansible development mailing list `_. +Please make sure your module meets these requirements before you submit your PR/proposal. If you have questions, visit the :ref:`Ansible communication guide` for information on how to reach out to the community. Contributing to Ansible: subjective requirements ================================================ diff --git a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst index 9f0271afb9e..c0494161831 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst @@ -32,7 +32,9 @@ Python shebang & UTF-8 coding Begin your Ansible module with ``#!/usr/bin/python`` - this "shebang" allows ``ansible_python_interpreter`` to work. Follow the shebang immediately with ``# -*- coding: utf-8 -*-`` to clarify that the file is UTF-8 encoded. -.. note:: Using ``#!/usr/bin/env``, makes ``env`` the interpreter and bypasses ``ansible__interpreter`` logic. +.. warning:: + - Using ``#!/usr/bin/env`` makes ``env`` the interpreter and bypasses ``ansible__interpreter`` logic. + - Passing arguments to the interpreter in the shebang does not work (for example, ``#!/usr/bin/env python``) . .. note:: If you develop the module using a different scripting language, adjust the interpreter accordingly (``#!/usr/bin/``) so ``ansible__interpreter`` can work for that specific language. .. note:: Binary modules do not require a shebang or an interpreter. @@ -336,11 +338,12 @@ The parameters for these formatting functions can use escaping with backslashes: Rules for using ``O()`` and ``RV()`` are very strict. You must follow syntax rules so that documentation renderers can create hyperlinks for the options and return values, respectively. The allowed syntaxes are as follows: -- To reference an option for the current plugin/module, or the entrypoint of the current role (inside role entrypoint documentation), use ``O(option)`` and ``O(option=name)``. -- To reference an option for another entrypoint ``entrypoint`` from inside role documentation, use ``O(entrypoint:option)`` and ``O(entrypoint:option=name)``. The entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. -- To reference an option for *another* plugin/module ``plugin.fqcn.name`` of type ``type``, use ``O(plugin.fqcn.name#type:option)`` and ``O(plugin.fqcn.name#type:option=name)``. For modules, use ``type=module``. The FQCN and plugin type can be ignored by the documentation renderer, turned into a link to that plugin, or even directly to the option of that plugin. -- To reference an option for entrypoint ``entrypoint`` of *another* role ``role.fqcn.name``, use ``O(role.fqcn.name#role:entrypoint:option)`` and ``O(role.fqcn.name#role:entrypoint:option=name)``. The FQCN and entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. -- To reference options that do not exist (for example, options that were removed in an earlier version), use ``O(ignore:option)`` and ``O(ignore:option=name)``. The ``ignore:`` part will not be shown to the user by documentation rendering. + +* To reference an option for the current plugin/module, or the entrypoint of the current role (inside role entrypoint documentation), use ``O(option)`` and ``O(option=name)``. +* To reference an option for another entrypoint ``entrypoint`` from inside role documentation, use ``O(entrypoint:option)`` and ``O(entrypoint:option=name)``. The entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. +* To reference an option for *another* plugin/module ``plugin.fqcn.name`` of type ``type``, use ``O(plugin.fqcn.name#type:option)`` and ``O(plugin.fqcn.name#type:option=name)``. For modules, use ``type=module``. The FQCN and plugin type can be ignored by the documentation renderer, turned into a link to that plugin, or even directly to the option of that plugin. +* To reference an option for entrypoint ``entrypoint`` of *another* role ``role.fqcn.name``, use ``O(role.fqcn.name#role:entrypoint:option)`` and ``O(role.fqcn.name#role:entrypoint:option=name)``. The FQCN and entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. +* To reference options that do not exist (for example, options that were removed in an earlier version), use ``O(ignore:option)`` and ``O(ignore:option=name)``. The ``ignore:`` part will not be shown to the user by documentation rendering. Option names can refer to suboptions by listing the path to the option separated by dots. For example, if you have an option ``foo`` with suboption ``bar``, then you must use ``O(foo.bar)`` to reference that suboption. You can add array indications like ``O(foo[].bar)`` or even ``O(foo[-1].bar)`` to indicate specific list elements. Everything between ``[`` and ``]`` pairs will be ignored to determine the real name of the option. For example, ``O(foo[foo | length - 1].bar[])`` results in the same link as ``O(foo.bar)``, but the text ``foo[foo | length - 1].bar[]`` displays instead of ``foo.bar``. diff --git a/docs/docsite/rst/dev_guide/developing_modules_general.rst b/docs/docsite/rst/dev_guide/developing_modules_general.rst index be0b5030e00..44db07f92b4 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_general.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_general.rst @@ -173,11 +173,7 @@ The :ref:`Community Guide ` covers how to open a pull r Communication and development support ===================================== -Join the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) for discussions surrounding Ansible development. - -For questions and discussions pertaining to using the Ansible product, join the ``#ansible`` channel. - -To find other topic-specific chat channels, look at :ref:`Community Guide, Communicating `. +Visit the :ref:`Ansible communication guide` for information on how to join the conversation. Credit ====== diff --git a/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst b/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst index 1ad3365e1ab..6c74ffc44d3 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst @@ -738,7 +738,4 @@ idempotent and does not report changes. For example: Windows communication and development support ============================================= -Join the ``#ansible-devel`` or ``#ansible-windows`` chat channels (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) for discussions about Ansible development for Windows. - -For questions and discussions pertaining to using the Ansible product, -use the ``#ansible`` channel. +Join the :ref:`Ansible Forum` and use the `windows` tag for discussions about Ansible development for Windows. diff --git a/docs/docsite/rst/dev_guide/developing_modules_in_groups.rst b/docs/docsite/rst/dev_guide/developing_modules_in_groups.rst index 0091159cf6c..4eed09ada40 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_in_groups.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_in_groups.rst @@ -43,20 +43,14 @@ It is convenient if the organization and repository names on GitHub (or elsewher Speak to us =========== -Circulating your ideas before coding helps you adopt good practices and avoid common mistakes. After reading the "Before you start coding" section you should have a reasonable idea of the structure of your modules. Write a list of your proposed plugin and/or module names, with a short description of what each one does. Circulate that list on IRC or a mailing list so the Ansible community can review your ideas for consistency and familiarity. Names and functionality that are consistent, predictable, and familiar make your collection easier to use. +Circulating your ideas before coding helps you adopt good practices and avoid common mistakes. After reading the "Before you start coding" section you should have a reasonable idea of the structure of your modules. Write a list of your proposed plugin and/or module names, with a short description of what each one does. Circulate that list on the :ref:`Ansible Forum` so the Ansible community can review your ideas for consistency and familiarity. Names and functionality that are consistent, predictable, and familiar make your collection easier to use. .. _developing_in_groups_support: Where to get support ==================== -Ansible has a thriving and knowledgeable community of module developers that is a great resource for getting your questions answered. - -In the :ref:`ansible_community_guide` you can find how to: - -* Subscribe to the Mailing Lists - We suggest "Ansible Development List" and "Ansible Announce list" -* ``#ansible-devel`` - We have found that communicating on the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) works best for developers so we can have an interactive dialog. -* Working group and other chat channel meetings - Join the various weekly meetings `meeting schedule page `_ +Ansible has a thriving and knowledgeable community of module developers that is a great resource for getting your questions answered. Visit the :ref:`Ansible communication guide` for details. Required files ============== @@ -70,9 +64,7 @@ Your collection should include the following files to be usable: When you have these files ready, review the :ref:`developing_modules_checklist` again. If you are creating a new collection, you are responsible for all procedures related to your repository, including setting rules for contributions, finding reviewers, and testing and maintaining the code in your collection. -If you need help or advice, consider joining the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_). For more information, see :ref:`developing_in_groups_support` and :ref:`communication`. - -New to git or GitHub +New to Git or GitHub ==================== We realize this may be your first use of Git or GitHub. The following guides may be of use: diff --git a/docs/docsite/rst/dev_guide/developing_plugins.rst b/docs/docsite/rst/dev_guide/developing_plugins.rst index cf29d066be7..d45ac41a397 100644 --- a/docs/docsite/rst/dev_guide/developing_plugins.rst +++ b/docs/docsite/rst/dev_guide/developing_plugins.rst @@ -568,9 +568,7 @@ For example vars plugins, see the source code for the `vars plugins included wit Learn about how to develop dynamic inventory sources :ref:`developing_modules_general` Learn about how to write Ansible modules - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide :ref:`adjacent_yaml_doc` Alternate YAML files as documentation diff --git a/docs/docsite/rst/dev_guide/developing_program_flow_modules.rst b/docs/docsite/rst/dev_guide/developing_program_flow_modules.rst index 9e4cca27124..bb76a79b4d4 100644 --- a/docs/docsite/rst/dev_guide/developing_program_flow_modules.rst +++ b/docs/docsite/rst/dev_guide/developing_program_flow_modules.rst @@ -660,7 +660,7 @@ This section will discuss the behavioral attributes for arguments: :aliases: - ``aliases`` accepts a list of alternative argument names for the argument, such as the case where the argument is ``name`` but the module accepts ``aliases=['pkg']`` to allow ``pkg`` to be interchangeably with ``name`` + ``aliases`` accepts a list of alternative argument names for the argument, such as the case where the argument is ``name`` but the module accepts ``aliases=['pkg']`` to allow ``pkg`` to be interchangeably with ``name``. Use of aliases can make module interfaces confusing, so we recommend adding them only when necessary. If you are updating argument names to fix a typo or improve the interface, consider moving the old names to ``deprecated_aliases`` rather than keeping them around indefinitely. :options: diff --git a/docs/docsite/rst/dev_guide/developing_rebasing.rst b/docs/docsite/rst/dev_guide/developing_rebasing.rst index dcd1fb07c43..038f88eed94 100644 --- a/docs/docsite/rst/dev_guide/developing_rebasing.rst +++ b/docs/docsite/rst/dev_guide/developing_rebasing.rst @@ -77,7 +77,7 @@ Updating your pull request Now that you've rebased your branch, you need to push your changes to GitHub to update your PR. -Since rebasing re-writes git history, you will need to use a force push: +Since rebasing re-writes Git history, you will need to use a force push: .. code-block:: shell-session @@ -89,7 +89,7 @@ You should check in on the status of your PR after tests have completed to see i Getting help rebasing ===================== -For help with rebasing your PR, or other development related questions, join us on the #ansible-devel chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_). +If you need any help with rebasing your PR, or you have other development related questions, visit the :ref:`Ansible communication guide` for information on how to reach out to the community. .. seealso:: diff --git a/docs/docsite/rst/dev_guide/overview_architecture.rst b/docs/docsite/rst/dev_guide/overview_architecture.rst index fb78da60512..66568364929 100644 --- a/docs/docsite/rst/dev_guide/overview_architecture.rst +++ b/docs/docsite/rst/dev_guide/overview_architecture.rst @@ -44,7 +44,6 @@ Here's what a plain text inventory file looks like: .. code-block:: text - --- [webservers] www1.example.com www2.example.com diff --git a/docs/docsite/rst/dev_guide/sidecar.rst b/docs/docsite/rst/dev_guide/sidecar.rst index ccf3aa75efa..3b1621f29c4 100644 --- a/docs/docsite/rst/dev_guide/sidecar.rst +++ b/docs/docsite/rst/dev_guide/sidecar.rst @@ -94,7 +94,5 @@ YAML documentation is mainly intended for filters, tests and modules. While it i Learn about how to develop dynamic inventory sources :ref:`developing_modules_general` Learn about how to write Ansible modules - `Mailing List `_ - The development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/style_guide/index.rst b/docs/docsite/rst/dev_guide/style_guide/index.rst index cb0a1f10c9f..59fdb400caf 100644 --- a/docs/docsite/rst/dev_guide/style_guide/index.rst +++ b/docs/docsite/rst/dev_guide/style_guide/index.rst @@ -183,7 +183,7 @@ Long pages, or pages with multiple levels of headings, can also include a local .. note:: - Avoid raw URLs. RST and sphinx allow ::code:`https://my.example.com`, but this is unhelpful for those using screen readers. ``:ref:`` links automatically pick up the heading from the anchor, but for external links, always use the ::code:`link title `_` format. + Avoid raw URLs. RST and sphinx allow :code:`https://my.example.com`, but this is unhelpful for those using screen readers. ``:ref:`` links automatically pick up the heading from the anchor, but for external links, always use the :code:`\`link title \`_` format. .. _adding_anchors_rst: @@ -481,5 +481,5 @@ These pages offer more help with grammatical, stylistic, and technical rules for How to contribute to the Ansible documentation :ref:`testing_documentation_locally` How to build the Ansible documentation - `irc.libera.chat `_ - #ansible-docs IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/dev_guide/style_guide/resources.rst b/docs/docsite/rst/dev_guide/style_guide/resources.rst index 64dc0c1dd57..c5b94ac5b18 100644 --- a/docs/docsite/rst/dev_guide/style_guide/resources.rst +++ b/docs/docsite/rst/dev_guide/style_guide/resources.rst @@ -1,7 +1,7 @@ Resources ^^^^^^^^^ * Follow the style of the :ref:`Ansible Documentation` -* Ask for advice on the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) +* Ask the community for advice. Visit the :ref:`Ansible communication guide` for details. * Review these online style guides: * `AP Stylebook `_ diff --git a/docs/docsite/rst/dev_guide/testing.rst b/docs/docsite/rst/dev_guide/testing.rst index e7d33db9552..6e743a6f338 100644 --- a/docs/docsite/rst/dev_guide/testing.rst +++ b/docs/docsite/rst/dev_guide/testing.rst @@ -11,9 +11,9 @@ Testing Ansible Why test your Ansible contributions? ==================================== -If you're a developer, one of the most valuable things you can do is to look at GitHub issues and help fix bugs, since bug-fixing is almost always prioritized over feature development. Even for non-developers, helping to test pull requests for bug fixes and features is still immensely valuable. +If you're a developer, one of the most valuable things you can do is to look at GitHub issues and help fix bugs, since bug-fixing is almost always prioritized over feature development. Even for non-developers, helping to test pull requests for bug fixes and features is still immensely valuable. -Ansible users who understand how to write playbooks and roles should be able to test their work. GitHub pull requests will automatically run a variety of tests (for example, Azure Pipelines) that show bugs in action. However, contributors must also test their work outside of the automated GitHub checks and show evidence of these tests in the PR to ensure that their work will be more likely to be reviewed and merged. +Ansible users who understand how to write playbooks and roles should be able to test their work. GitHub pull requests will automatically run a variety of tests (for example, Azure Pipelines) that show bugs in action. However, contributors must also test their work outside of the automated GitHub checks and show evidence of these tests in the pull request to ensure that their work will be more likely to be reviewed and merged. Read on to learn how Ansible is tested, how to test your contributions locally, and how to extend testing capabilities. @@ -24,7 +24,7 @@ If you want to learn about testing collections, read :ref:`testing_collections` Types of tests ============== -At a high level we have the following classifications of tests: +At a high level, we have the following classifications of tests: :sanity: * :ref:`testing_sanity` @@ -80,25 +80,31 @@ Rerunning a failing CI job Occasionally you may find your PR fails due to a reason unrelated to your change. This could happen for several reasons, including: -* a temporary issue accessing an external resource, such as a yum or git repo +* a temporary issue accessing an external resource, such as a yum or Git repo * a timeout creating a virtual machine to run the tests on -If either of these issues appear to be the case, you can rerun the Azure Pipelines test by: +If either issue appears to be the case, you can rerun the Azure Pipelines test by: -* adding a comment with ``/rebuild`` (full rebuild) or ``/rebuild_failed`` (rebuild only failed CI nodes) to the PR -* closing and re-opening the PR (full rebuild) -* making another change to the PR and pushing to GitHub - -If the issue persists, please contact us in the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_). +* adding a comment with ``/rebuild`` (full rebuild) or ``/rebuild_failed`` (rebuild only failed CI nodes) to the pull request +* closing and re-opening the pull request (full rebuild) +* making another change to the branch and pushing to GitHub +If the issue persists, please contact the community. Visit the :ref:`Ansible communication guide` for details. How to test a PR ================ -Ideally, code should add tests that prove that the code works. That's not always possible and tests are not always comprehensive, especially when a user doesn't have access to a wide variety of platforms, or is using an API or web service. In these cases, live testing against real equipment can be more valuable than automation that runs against simulated interfaces. In any case, things should always be tested manually the first time as well. +Ideally, the code should add tests that prove that the code works. That's not always possible and tests are not always comprehensive, especially when a user doesn't have access to a wide variety of platforms, or is using an API or web service. In these cases, live testing against real equipment can be more valuable than automation that runs against simulated interfaces. In any case, things should always be tested manually the first time as well. Thankfully, helping to test Ansible is pretty straightforward, assuming you are familiar with how Ansible works. +Setup: Installing Pytest and required Pytest libraries +------------------------------------------------------ + +Ansible's unit testing framework leverages the pytest library. Before diving into testing, ensure you have ``pytest`` installed alongside any additional pytest libraries such as ``pytest-mock`` and ``pytest-xdist``. + +Refer to the documentation for more information: :ref:`testing_units`. + Setup: Checking out a Pull Request ---------------------------------- @@ -126,7 +132,7 @@ Create a fresh area to work: git clone https://github.com/ansible/ansible.git ansible-pr-testing cd ansible-pr-testing -Next, find the pull request you'd like to test and make note of its number. It will look something like this: +Next, find the pull request you'd like to test and make a note of its number. It will look something like this: .. code-block:: text @@ -146,7 +152,7 @@ Use the pull request number when you fetch the proposed changes and create your The first command fetches the proposed changes from the pull request and creates a new branch named ``testing_PRXXXX``, where the XXXX is the actual number associated with the pull request (for example, 65381). The second command checks out the newly created branch. .. note:: - If the GitHub user interface shows that the pull request will not merge cleanly, we do not recommend proceeding if you are not somewhat familiar with git and coding, as you will have to resolve a merge conflict. This is the responsibility of the original pull request contributor. + If the GitHub user interface shows that the pull request will not merge cleanly, we do not recommend proceeding if you are not somewhat familiar with Git and coding, as you will have to resolve a merge conflict. This is the responsibility of the original pull request contributor. .. note:: Some users do not create feature branches, which can cause problems when they have multiple, unrelated commits in their version of ``devel``. If the source looks like ``someuser:devel``, make sure there is only one commit listed on the pull request. @@ -224,11 +230,11 @@ If the PR does not resolve the issue, or if you see any failures from the unit/i Code Coverage Online ^^^^^^^^^^^^^^^^^^^^ -`The online code coverage reports `_ are a good way +`The online code coverage reports `_ is a good way to identify areas for testing improvement in Ansible. By following red colors you can -drill down through the reports to find files which have no tests at all. Adding both -integration and unit tests which show clearly how code should work, verify important -Ansible functions and increase testing coverage in areas where there is none is a valuable +drill down through the reports to find files that have no tests at all. Adding both +integration and unit tests that show clearly how code should work, verify important +Ansible functions and increases testing coverage in areas where there is none is a valuable way to help improve Ansible. The code coverage reports only cover the ``devel`` branch of Ansible where new feature diff --git a/docs/docsite/rst/dev_guide/testing/sanity/integration-aliases.rst b/docs/docsite/rst/dev_guide/testing/sanity/integration-aliases.rst index 08e6e65c3e0..02c7397847a 100644 --- a/docs/docsite/rst/dev_guide/testing/sanity/integration-aliases.rst +++ b/docs/docsite/rst/dev_guide/testing/sanity/integration-aliases.rst @@ -55,7 +55,7 @@ Some test dependencies are automatically discovered: Aliases can be used to declare dependencies that are not handled automatically: - ``needs/target/TARGET`` - Requires use of the test target ``TARGET``. -- ``needs/file/PATH`` - Requires use of the file ``PATH`` relative to the git root. +- ``needs/file/PATH`` - Requires use of the file ``PATH`` relative to the Git root. Skipping -------- @@ -182,4 +182,4 @@ Each issue will be assigned to one of the following projects: Questions --------- -For questions about integration tests reach out to @mattclay or @gundalow on GitHub or the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_). +For questions about integration tests reach out to the community on the :ref:`Ansible Forum` by creating a topic tagged with ``ansible-test``, ``testing`` and other appropriate tags. diff --git a/docs/docsite/rst/dev_guide/testing_httptester.rst b/docs/docsite/rst/dev_guide/testing_httptester.rst index c9d364cf853..09f6fedbab2 100644 --- a/docs/docsite/rst/dev_guide/testing_httptester.rst +++ b/docs/docsite/rst/dev_guide/testing_httptester.rst @@ -9,7 +9,7 @@ httptester Overview ======== -``httptester`` is a docker container used to host certain resources required by :ref:`testing_integration`. This is to avoid CI tests requiring external resources (such as git or package repos) which, if temporarily unavailable, would cause tests to fail. +``httptester`` is a docker container used to host certain resources required by :ref:`testing_integration`. This is to avoid CI tests requiring external resources (such as Git or package repos) which, if temporarily unavailable, would cause tests to fail. HTTP Testing endpoint which provides the following capabilities: diff --git a/docs/docsite/rst/dev_guide/testing_integration.rst b/docs/docsite/rst/dev_guide/testing_integration.rst index 3667e8a39b3..13988e0059e 100644 --- a/docs/docsite/rst/dev_guide/testing_integration.rst +++ b/docs/docsite/rst/dev_guide/testing_integration.rst @@ -58,7 +58,7 @@ files in the ``tests/integration/`` directory. Prerequisites ============= -Some tests assume things like hg, svn, and git are installed, and in path. Some tests +Some tests assume things like ``hg``, ``svn``, and ``git`` are installed, and in path. Some tests (such as those for Amazon Web Services) need separate definitions, which will be covered later in this document. @@ -72,7 +72,7 @@ outside of those test subdirectories. They will also not reconfigure or bounce .. note:: Running integration tests within containers - To protect your system from any potential changes caused by integration tests, and to ensure a sensible set of dependencies are available we recommend that you always run integration tests with the ``--docker`` option, for example ``--docker ubuntu2004``. See the `list of supported container images `_ for options (the ``default`` image is used for sanity and unit tests, as well as for platform independent integration tests such as those for cloud modules). + To protect your system from any potential changes caused by integration tests, and to ensure a sensible set of dependencies are available we recommend that you always run integration tests with the ``--docker`` option, for example ``--docker ubuntu2204``. Get the list of supported container images by running ``ansible-test integration --help``. You can find them in the *target docker images* section of the output. The ``default`` image is used for sanity and unit tests, as well as for platform independent integration tests such as those for cloud modules. Run as follows for all POSIX platform tests executed by our CI system in a Fedora 34 container: @@ -245,4 +245,4 @@ Where to find out more ====================== If you'd like to know more about the plans for improving testing Ansible, join the -`Ansible community forum `_ \ No newline at end of file +`Ansible community forum `_ diff --git a/docs/docsite/rst/dev_guide/testing_running_locally.rst b/docs/docsite/rst/dev_guide/testing_running_locally.rst index 0d03189bf41..86fac4a62b2 100644 --- a/docs/docsite/rst/dev_guide/testing_running_locally.rst +++ b/docs/docsite/rst/dev_guide/testing_running_locally.rst @@ -27,7 +27,7 @@ Before running ``ansible-test``, set up your environment for :ref:`testing_an_an Testing an Ansible Collection ----------------------------- -If you are testing an Ansible Collection, you need a copy of the collection, preferably a git clone. +If you are testing an Ansible Collection, you need a copy of the collection, preferably a Git clone. For example, to work with the ``community.windows`` collection, follow these steps: 1. Clone the collection you want to test into a valid collection root: @@ -67,7 +67,7 @@ For example, to work with the ``community.windows`` collection, follow these ste Testing ``ansible-core`` ------------------------ -If you are testing ``ansible-core`` itself, you need a copy of the ``ansible-core`` source code, preferably a git clone. +If you are testing ``ansible-core`` itself, you need a copy of the ``ansible-core`` source code, preferably a Git clone. Having an installed copy of ``ansible-core`` is not sufficient or required. For example, to work with the ``ansible-core`` source cloned from GitHub, follow these steps: diff --git a/docs/docsite/rst/dev_guide/testing_units_modules.rst b/docs/docsite/rst/dev_guide/testing_units_modules.rst index 9296da6b0e6..520d2981c1d 100644 --- a/docs/docsite/rst/dev_guide/testing_units_modules.rst +++ b/docs/docsite/rst/dev_guide/testing_units_modules.rst @@ -18,7 +18,7 @@ The document doesn't apply to other parts of Ansible for which the recommendatio normally closer to the Python standard. There is basic documentation for Ansible unit tests in the developer guide :ref:`testing_units`. This document should be readable for a new Ansible module author. If you find it incomplete or confusing, -please open a bug or ask for help on the #ansible-devel chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_). +please open a bug or ask for help on the :ref:`Ansible Forum`. What Are Unit Tests? ==================== @@ -279,8 +279,7 @@ Ansible special cases for unit testing There are a number of special cases for unit testing the environment of an Ansible module. The most common are documented below, and suggestions for others can be found by looking -at the source code of the existing unit tests or asking on the Ansible chat channel or mailing -lists. For more information on joining chat channels and subscribing to mailing lists, see :ref:`communication`. +at the source code of the existing unit tests or :ref:`asking the community`. Module argument processing -------------------------- @@ -564,6 +563,8 @@ the code in Ansible to trigger that failure. .. seealso:: + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide :ref:`testing_units` Ansible unit tests documentation :ref:`testing_running_locally` @@ -576,8 +577,6 @@ the code in Ansible to trigger that failure. The documentation of the earliest supported unittest framework - from Python 2.6 `pytest: helps you write better programs `_ The documentation of pytest - the framework actually used to run Ansible unit tests - `Development Mailing List `_ - Mailing list for development topics `Testing Your Code (from The Hitchhiker's Guide to Python!) `_ General advice on testing Python code `Uncle Bob's many videos on YouTube `_ diff --git a/docs/docsite/rst/galaxy/dev_guide.rst b/docs/docsite/rst/galaxy/dev_guide.rst index 2ff284160e7..43193a0dd61 100644 --- a/docs/docsite/rst/galaxy/dev_guide.rst +++ b/docs/docsite/rst/galaxy/dev_guide.rst @@ -206,11 +206,9 @@ Provide the ID of the integration to be disabled. You can find the ID by using t .. seealso:: - :ref:`collections` - Shareable collections of modules, playbooks and roles - :ref:`playbooks_reuse_roles` - All about ansible roles - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`collections` + Shareable collections of modules, playbooks and roles + :ref:`playbooks_reuse_roles` + All about ansible roles + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/galaxy/user_guide.rst b/docs/docsite/rst/galaxy/user_guide.rst index aaa400334c2..fd447fa7520 100644 --- a/docs/docsite/rst/galaxy/user_guide.rst +++ b/docs/docsite/rst/galaxy/user_guide.rst @@ -108,7 +108,7 @@ This returns everything found in Galaxy for the role: Installing roles from Galaxy ============================ -The ``ansible-galaxy`` command comes bundled with Ansible, and you can use it to install roles from Galaxy or directly from a git based SCM. You can +The ``ansible-galaxy`` command comes bundled with Ansible, and you can use it to install roles from Galaxy or directly from a Git based SCM. You can also use it to create a new role, remove roles, or perform tasks on the Galaxy website. The command line tool by default communicates with the Galaxy website API using the server address *https://galaxy.ansible.com*. If you run your own internal Galaxy server @@ -150,7 +150,7 @@ The following provides an example of using ``--roles-path`` to install the role Installing a specific version of a role --------------------------------------- -When the Galaxy server imports a role, it imports any git tags matching the `Semantic Version `_ format as versions. +When the Galaxy server imports a role, it imports any Git tags matching the `Semantic Version `_ format as versions. In turn, you can download a specific version of a role by specifying one of the imported tags. To see the available versions for a role: @@ -165,7 +165,7 @@ To install a specific version of a role from Galaxy, append a comma and the valu $ ansible-galaxy role install geerlingguy.apache,3.2.0 -It is also possible to point directly to the git repository and specify a branch name or commit hash as the version. For example, the following will +It is also possible to point directly to the Git repository and specify a branch name or commit hash as the version. For example, the following will install a specific commit: .. code-block:: bash @@ -191,7 +191,7 @@ Each role in the file will have one or more of the following attributes: src The source of the role. Use the format *namespace.role_name*, if downloading from Galaxy; otherwise, provide a URL pointing - to a repository within a git based SCM. See the examples below. This is a required attribute. + to a repository within a Git based SCM. See the examples below. This is a required attribute. scm Specify the SCM. As of this writing only *git* or *hg* are allowed. See the examples below. Defaults to *git*. version: @@ -207,7 +207,7 @@ Use the following example as a guide for specifying roles in *requirements.yml*: # from galaxy - name: yatesr.timezone - # from locally cloned git repository (git+file:// requires full paths) + # from locally cloned Git repository (git+file:// requires full paths) - src: git+file:///home/bennojoy/nginx # from GitHub @@ -347,16 +347,6 @@ The following shows an example ``meta/main.yml`` file with dependent roles: company: "Midwestern Mac, LLC" license: "license (BSD, MIT)" min_ansible_version: 2.4 - platforms: - - name: EL - versions: - - all - - name: Debian - versions: - - all - - name: Ubuntu - versions: - - all galaxy_tags: - web - system diff --git a/docs/docsite/rst/getting_started/introduction.rst b/docs/docsite/rst/getting_started/introduction.rst index a542bd16ea4..ae7dcc4996a 100644 --- a/docs/docsite/rst/getting_started/introduction.rst +++ b/docs/docsite/rst/getting_started/introduction.rst @@ -23,7 +23,7 @@ Agent-less architecture Low maintenance overhead by avoiding the installation of additional software across IT infrastructure. Simplicity - Automation playbooks use straightforward YAML syntax for code that reads like documentation. Ansible is also decentralized, using SSH existing OS credentials to access to remote machines. + Automation playbooks use straightforward YAML syntax for code that reads like documentation. Ansible is also decentralized, using SSH with existing OS credentials to access to remote machines. Scalability and flexibility Easily and quickly scale the systems you automate through a modular design that supports a large range of operating systems, cloud platforms, and network devices. diff --git a/docs/docsite/rst/getting_started/yaml/first_playbook.yaml b/docs/docsite/rst/getting_started/yaml/first_playbook.yaml index d3ede278f3a..c7320bb3f02 100644 --- a/docs/docsite/rst/getting_started/yaml/first_playbook.yaml +++ b/docs/docsite/rst/getting_started/yaml/first_playbook.yaml @@ -6,4 +6,4 @@ - name: Print message ansible.builtin.debug: - msg: Hello world + msg: Hello world diff --git a/docs/docsite/rst/getting_started_ee/build_execution_environment.rst b/docs/docsite/rst/getting_started_ee/build_execution_environment.rst new file mode 100644 index 00000000000..5d8bb684dc1 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/build_execution_environment.rst @@ -0,0 +1,59 @@ +.. _building_execution_environment: + +***************************************** +Building your first Execution Environment +***************************************** + +We are going to build an EE that represents an Ansible control node containing standard packages such as ``ansible-core`` and Python in addition to an Ansible collection (``community.postgresql``) and its dependency (the ``psycopg2-binary`` Python connector). + +To build your first EE: + +#. Create a project folder on your filesystem. + + .. code-block:: bash + + mkdir my_first_ee && cd my_first_ee + +#. Create a ``execution-environment.yml`` file that specifies dependencies to include in the image. + + .. literalinclude:: yaml/execution-environment.yml + :language: yaml + + .. note:: + + The `psycopg2-binary` Python package is included in the `requirements.txt` file for the collection. + For collections that do not include `requirements.txt` files, you need to specify Python dependencies explicitly. + See the `Ansible Builder documentation `_ for details. + +#. Build a EE container image called ``postgresql_ee``. + + If you use docker, add the ``--container-runtime docker`` argument. + + .. code-block:: bash + + ansible-builder build --tag postgresql_ee + +#. List container images to verify that you built it successfully. + + .. code-block:: bash + + podman image list + + localhost/postgresql_ee latest 2e866777269b 6 minutes ago 1.11 GB + +You can verify the image you created by inspecting the ``Containerfile`` or ``Dockerfile`` in the ``context`` directory to view its configuration. + +.. code-block:: bash + + less context/Containerfile + +You can also use Ansible Navigator to view detailed information about the image. + +Run the `ansible-navigator` command, type ``:images`` in the TUI, and then choose ``postgresql_ee``. + +Proceed to :ref:`running_custom_execution_environment` and test the EE you just built. + +.. seealso:: + + `Running a local container registry for Execution Environments `_ + This guide in the Ansible community forum explains how to set up a local registry for your Execution Environment images. diff --git a/docs/docsite/rst/getting_started_ee/index.rst b/docs/docsite/rst/getting_started_ee/index.rst index 3e3d38edcb8..02c5c384dad 100644 --- a/docs/docsite/rst/getting_started_ee/index.rst +++ b/docs/docsite/rst/getting_started_ee/index.rst @@ -4,29 +4,34 @@ Getting started with Execution Environments ******************************************* -Execution Environments (EEs) are Ansible control nodes packaged as container images. +You can run Ansible automation in containers, like any other modern software application. +Ansible uses container images known as Execution Environments (EE) that act as control nodes. EEs remove complexity to scale out automation projects and make things like deployment operations much more straightforward. -EEs provide you with: +An Execution Environment image contains the following packages as standard: -* Software dependency isolation -* Portability across teams and environments -* Separation from other automation content and tooling +* ``ansible-core`` +* ``ansible-runner`` +* Python +* Ansible content dependencies -You can use Ansible community EEs to get up and running. -Or you can easily build and deploy custom EEs with whatever packages and Ansible community collections you need for your project. +In addition to the standard packages, an EE can also contain: -Visit `Getting started with Execution Environments `_ in the Ansible ecosystem documentation. +* one or more Ansible collections and their dependencies +* other custom components -Ansible ecosystem ------------------ +This getting started guide shows you how to build and test a simple Execution Environment. +The resulting container image represents an Ansible control node that contains: -Using EEs with projects in the Ansible ecosystem lets you expand automation to lots of use cases: +* standard EE packages +* ``community.postgresql`` collection +* ``psycopg2-binary`` Python package -* `Ansible Builder `_ -* `Ansible Navigator `_ -* `Ansible AWX `_ -* `Ansible Runner `_ -* VS Code `Ansible `_ and `Dev Containers `_ extensions +.. toctree:: + :maxdepth: 1 -Visit the `Ansible ecosystem documentation `_ to find How Tos and tutorials for using EEs with Ansible projects. + introduction + setup_environment + build_execution_environment + run_execution_environment + run_community_ee_image diff --git a/docs/docsite/rst/getting_started_ee/introduction.rst b/docs/docsite/rst/getting_started_ee/introduction.rst new file mode 100644 index 00000000000..34e73728655 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/introduction.rst @@ -0,0 +1,65 @@ +.. _introduction_execution_environment: + +************************************** +Introduction to Execution Environments +************************************** + +Ansible Execution Environments aim to resolve complexity issues and provide all the benefits you can get from containerization. + +Reducing complexity +=================== + +There are three main areas where EEs can reduce complexity: + +* software dependencies +* portability +* content separation + +Dependencies +------------ + +Software applications typically have dependencies, and Ansible is no exception. +These dependencies can include software libraries, configuration files or other services, to name a few. + +Traditionally, administrators install application dependencies on top of an operating system using packaging management tools such as RPM or Python-pip. +The major drawback of such an approach is that an application might require versions of dependencies different from those provided by default. +For Ansible, a typical installation consists of `ansible-core` and a set of Ansible collections. +Many of them have dependencies for the plugins, modules, roles and playbooks they provide. + +The Ansible collections can depend on the following pieces of software and their versions: + +* ``ansible-core`` +* Python +* Python packages +* System packages +* Other Ansible collections + +The dependencies have to be installed and sometimes can conflict with each other. + +One way to **partially** resolve the dependency issue is to use Python virtual environments on Ansible control nodes. +However, applied to Ansible, virtual environments have drawbacks and natural limitations. + +Portability +----------- + +An Ansible user writes content for Ansible locally and wants to leverage the container technology to make their automation runtimes portable, shareable and easily deployable to testing and production environments. + +Content separation +------------------ + +In situations when there is an Ansible control node or a tool such as Ansible AWX/Controller used by several users, they might want separate +their content to avoid configuration and dependency conflicts. + +Ansible tooling for EEs +======================= + +Projects in the Ansible ecosystem also provide several tools that you can use with EEs, such as: + +* `Ansible Builder `_ +* `Ansible Navigator `_ +* `Ansible AWX `_ +* `Ansible Runner `_ +* `VS Code Ansible `_ +* `Dev Containers extensions `_ + +Ready to get started with EEs? Proceed to :ref:`setting_up_ee_environment`. diff --git a/docs/docsite/rst/getting_started_ee/run_community_ee_image.rst b/docs/docsite/rst/getting_started_ee/run_community_ee_image.rst new file mode 100644 index 00000000000..806272fe59b --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/run_community_ee_image.rst @@ -0,0 +1,35 @@ +.. _running_community_execution_environment: + +******************************************* +Running Ansible with the community EE image +******************************************* + +You can run ansible without the need to build a custom EE using community images. + +Use the ``community-ee-minimal`` image that includes only ``ansible-core`` or the ``community-ee-base`` image that also includes several base collections. +Run the following command to see the collections included in the ``community-ee-base`` image: + +.. code-block:: bash + + ansible-navigator collections --execution-environment-image ghcr.io/ansible-community/community-ee-base:latest + +Run the following Ansible ad-hoc command against localhost inside the ``community-ee-minimal`` container: + +.. code-block:: bash + + ansible-navigator exec "ansible localhost -m setup" --execution-environment-image ghcr.io/ansible-community/community-ee-minimal:latest --mode stdout + +Now, create a simple test playbook and run it against ``localhost`` inside the container: + +.. literalinclude:: yaml/test_localhost.yml + :language: yaml + +.. code-block:: bash + + ansible-navigator run test_localhost.yml --execution-environment-image ghcr.io/ansible-community/community-ee-minimal:latest --mode stdout + +.. seealso:: + + * :ref:`building_execution_environment` + * :ref:`running_custom_execution_environment` + * `Ansible Navigator documentation `_ diff --git a/docs/docsite/rst/getting_started_ee/run_execution_environment.rst b/docs/docsite/rst/getting_started_ee/run_execution_environment.rst new file mode 100644 index 00000000000..5021c74cec9 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/run_execution_environment.rst @@ -0,0 +1,73 @@ +.. _running_custom_execution_environment: + +*************** +Running your EE +*************** + +You can run your EE on the command line against ``localhost`` or a remote target using ``ansible-navigator``. + +> There are other tools besides ``ansible-navigator`` you can run EEs with. + +Run against localhost +===================== + +#. Create a ``test_localhost.yml`` playbook. + + .. literalinclude:: yaml/test_localhost.yml + :language: yaml + +#. Run the playbook inside the ``postgresql_ee`` EE. + + .. code-block:: bash + + ansible-navigator run test_localhost.yml --execution-environment-image postgresql_ee --mode stdout --pull-policy missing --container-options='--user=0' + +You may notice the facts being gathered are about the container and not the developer machine. +This is because the ansible playbook was run inside the container. + +Run against a remote target +=========================== + +Before you start, ensure you have the following: + + * At least one IP address or resolvable hostname for a remote target. + * Valid credentials for the remote host. + * A user with `sudo` permissions on the remote host. + +Execute a playbook inside the ``postgresql_ee`` EE against a remote host machine as in the following example: + +#. Create a directory for inventory files. + + .. code-block:: bash + + mkdir inventory + +#. Create the ``hosts.yml`` inventory file in the ``inventory`` directory. + + .. literalinclude:: yaml/hosts.yml + :language: yaml + +#. Create a ``test_remote.yml`` playbook. + + .. literalinclude:: yaml/test_remote.yml + :language: yaml + +#. Run the playbook inside the ``postgresql_ee`` EE. + + Replace ``student`` with the appropriate username. + Some arguments in the command can be optional depending on your target host authentication method. + + .. code-block:: bash + + ansible-navigator run test_remote.yml -i inventory --execution-environment-image postgresql_ee:latest --mode stdout --pull-policy missing --enable-prompts -u student -k -K + +.. seealso:: + + `Execution Environment Definition `_ + Provides information about the about Execution Environment definition file and available options. + `Ansible Builder CLI usage `_ + Provides details about using Ansible Builder. + `Ansible Navigator documentation `_ + Provides details about using Ansible Navigator. + `Running a local container registry for EEs `_ + This guide in the Ansible community forum explains how to set up a local registry for your Execution Environment images. diff --git a/docs/docsite/rst/getting_started_ee/setup_environment.rst b/docs/docsite/rst/getting_started_ee/setup_environment.rst new file mode 100644 index 00000000000..5b18e42a020 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/setup_environment.rst @@ -0,0 +1,44 @@ +.. _setting_up_ee_environment: + +*************************** +Setting up your environment +*************************** + +Complete the following steps to set up a local environment for your first Execution Environment: + +#. Ensure the following packages are installed on your system: + + * ``podman`` or ``docker`` + * ``python3`` + + If you use the DNF package manager, install these prerequisites as follows: + + .. code-block:: bash + + sudo dnf install -y podman python3 + +#. Install ``ansible-navigator``: + + .. code-block:: bash + + pip3 install ansible-navigator + + Installing ``ansible-navigator`` lets you run EEs on the command line. + It includes the ``ansible-builder`` package to build EEs. + + If you want to build EEs without testing, install only ``ansible-builder``: + + .. code-block:: bash + + pip3 install ansible-builder + +#. Verify your environment with the following commands: + + .. code-block:: bash + + ansible-navigator --version + ansible-builder --version + +Ready to build an EE in a few easy steps? Proceed to :ref:`building_execution_environment`. + +Want to try an EE without having to build one? Proceed to :ref:`running_community_execution_environment`. diff --git a/docs/docsite/rst/getting_started_ee/yaml/execution-environment.yml b/docs/docsite/rst/getting_started_ee/yaml/execution-environment.yml new file mode 100644 index 00000000000..35668c4bd8e --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/yaml/execution-environment.yml @@ -0,0 +1,17 @@ +version: 3 + +images: + base_image: + name: quay.io/fedora/fedora:latest + +dependencies: + ansible_core: + package_pip: ansible-core + ansible_runner: + package_pip: ansible-runner + system: + - openssh-clients + - sshpass + galaxy: + collections: + - name: community.postgresql diff --git a/docs/docsite/rst/getting_started_ee/yaml/hosts.yml b/docs/docsite/rst/getting_started_ee/yaml/hosts.yml new file mode 100644 index 00000000000..3fb711e9c71 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/yaml/hosts.yml @@ -0,0 +1,3 @@ +all: + hosts: + 192.168.0.2 # Replace with the IP of your target host \ No newline at end of file diff --git a/docs/docsite/rst/getting_started_ee/yaml/test_localhost.yml b/docs/docsite/rst/getting_started_ee/yaml/test_localhost.yml new file mode 100644 index 00000000000..9be3ab10425 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/yaml/test_localhost.yml @@ -0,0 +1,9 @@ +- name: Gather and print local facts + hosts: localhost + become: true + gather_facts: true + tasks: + + - name: Print facts + ansible.builtin.debug: + var: ansible_facts diff --git a/docs/docsite/rst/getting_started_ee/yaml/test_remote.yml b/docs/docsite/rst/getting_started_ee/yaml/test_remote.yml new file mode 100644 index 00000000000..08b5517db02 --- /dev/null +++ b/docs/docsite/rst/getting_started_ee/yaml/test_remote.yml @@ -0,0 +1,9 @@ +- name: Gather and print facts + hosts: all + become: true + gather_facts: true + tasks: + + - name: Print facts + ansible.builtin.debug: + var: ansible_facts diff --git a/docs/docsite/rst/installation_guide/installation_distros.rst b/docs/docsite/rst/installation_guide/installation_distros.rst index 26a69f5fc7f..da4b4b94a9b 100644 --- a/docs/docsite/rst/installation_guide/installation_distros.rst +++ b/docs/docsite/rst/installation_guide/installation_distros.rst @@ -68,7 +68,7 @@ Installing Ansible on OpenSUSE Tumbleweed/Leap .. code-block:: bash $ sudo zypper install ansible - + See `OpenSUSE Support Portal `_ for additional help with Ansible on OpenSUSE. .. _from_apt: @@ -170,7 +170,7 @@ Please `open an issue `_ for details. +See :ref:`getting_started_ee_index` for details. .. _development_install: @@ -346,7 +346,7 @@ If you do not have bash 4.2, you must register each script independently. $ eval $(register-python-argcomplete ansible-pull) $ eval $(register-python-argcomplete ansible-vault) -You should place the above commands into your shells profile file such as ``~/.profile`` or ``~/.bash_profile``. +You should place the above commands into your shell's profile file such as ``~/.profile`` or ``~/.bash_profile``. Using ``argcomplete`` with zsh or tcsh ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/docsite/rst/inventory_guide/connection_details.rst b/docs/docsite/rst/inventory_guide/connection_details.rst index 2c462e32b4d..d7ef373449e 100644 --- a/docs/docsite/rst/inventory_guide/connection_details.rst +++ b/docs/docsite/rst/inventory_guide/connection_details.rst @@ -120,4 +120,4 @@ Other connection methods ------------------------ Ansible can use a variety of connection methods beyond SSH. You can select any connection plugin, including managing things locally and managing chroot, lxc, and jail containers. -A mode called 'ansible-pull' can also invert the system and have systems 'phone home' with scheduled git checkouts to pull configuration directives from a central repository. +A mode called 'ansible-pull' can also invert the system and have systems 'phone home' with scheduled Git checkouts to pull configuration directives from a central repository. diff --git a/docs/docsite/rst/inventory_guide/intro_dynamic_inventory.rst b/docs/docsite/rst/inventory_guide/intro_dynamic_inventory.rst index a9583dfffab..cd8ee99b180 100644 --- a/docs/docsite/rst/inventory_guide/intro_dynamic_inventory.rst +++ b/docs/docsite/rst/inventory_guide/intro_dynamic_inventory.rst @@ -164,7 +164,5 @@ the dynamic groups as empty in the static inventory file. For example: :ref:`intro_inventory` All about static inventory files - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/inventory_guide/intro_inventory.rst b/docs/docsite/rst/inventory_guide/intro_inventory.rst index 0a3300f061c..11aa6cec56a 100644 --- a/docs/docsite/rst/inventory_guide/intro_inventory.rst +++ b/docs/docsite/rst/inventory_guide/intro_inventory.rst @@ -508,7 +508,7 @@ file gets too big, or when you want to use :ref:`Ansible Vault` For ``ansible-playbook`` you can also add ``group_vars/`` and ``host_vars/`` directories to your playbook directory. Other Ansible commands (for example, ``ansible``, ``ansible-console``, and so on) will only look for ``group_vars/`` and ``host_vars/`` in the inventory directory. If you want other commands to load group and host variables from a playbook directory, you must provide the ``--playbook-dir`` option on the command line. If you load inventory files from both the playbook directory and the inventory directory, variables in the playbook directory will override variables set in the inventory directory. -Keeping your inventory file and variables in a git repo (or other version control) +Keeping your inventory file and variables in a Git repo (or other version control) is an excellent way to track changes to your inventory and host variables. .. _how_we_merge: @@ -587,7 +587,7 @@ ansible_connection General for all connections: ansible_host - The name of the host to connect to, if different from the alias you wish to give to it. + The name of the host to connect to, if different from the alias you wish to give to it. Never set it to depend on ``inventory_hostname`` if you use delegation. ansible_port The connection port number, if not the default (22 for ssh) ansible_user @@ -789,7 +789,5 @@ their location. Examples of basic commands :ref:`working_with_playbooks` Learning Ansible's configuration, deployment, and orchestration language. - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/inventory_guide/intro_patterns.rst b/docs/docsite/rst/inventory_guide/intro_patterns.rst index 039a41b4d90..ac75090a33f 100644 --- a/docs/docsite/rst/inventory_guide/intro_patterns.rst +++ b/docs/docsite/rst/inventory_guide/intro_patterns.rst @@ -276,7 +276,5 @@ To apply your knowledge of patterns with Ansible commands and playbooks, read :r Examples of basic commands :ref:`working_with_playbooks` Learning the Ansible configuration management language - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/module_plugin_guide/modules_intro.rst b/docs/docsite/rst/module_plugin_guide/modules_intro.rst index 486202cb37b..3a6411715fd 100644 --- a/docs/docsite/rst/module_plugin_guide/modules_intro.rst +++ b/docs/docsite/rst/module_plugin_guide/modules_intro.rst @@ -56,10 +56,7 @@ For a list of all available modules, see the :ref:`Collection docs `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide :ref:`all_modules_and_plugins` All modules and plugins available - diff --git a/docs/docsite/rst/module_plugin_guide/modules_support.rst b/docs/docsite/rst/module_plugin_guide/modules_support.rst index 566ae438834..fdb1c210699 100644 --- a/docs/docsite/rst/module_plugin_guide/modules_support.rst +++ b/docs/docsite/rst/module_plugin_guide/modules_support.rst @@ -47,7 +47,7 @@ If you find a bug that affects a plugin in a Galaxy collection: Some partner collections may be hosted in private repositories. -If you are not sure whether the behavior you see is a bug, if you have questions, if you want to discuss development-oriented topics, or if you just want to get in touch, use one of our Google mailing lists or chat channels (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) to :ref:`communicate with Ansiblers `. +If you are not sure whether the behavior you see is a bug, if you have questions, if you want to discuss development-oriented topics, or if you just want to get in touch, visit the :ref:`Ansible communication guide` for information on how to join the community. If you find a bug that affects a module in an Automation Hub collection: @@ -64,7 +64,5 @@ All plugins that remain in ``ansible-core`` and all collections hosted in Automa Examples of using modules in /usr/bin/ansible :ref:`working_with_playbooks` Examples of using modules with /usr/bin/ansible-playbook - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/network/dev_guide/developing_resource_modules_network.rst b/docs/docsite/rst/network/dev_guide/developing_resource_modules_network.rst index 7ed80ce1d51..3df7870ac9f 100644 --- a/docs/docsite/rst/network/dev_guide/developing_resource_modules_network.rst +++ b/docs/docsite/rst/network/dev_guide/developing_resource_modules_network.rst @@ -718,7 +718,7 @@ For more options: ansible-test network-integration --help -If you need additional help or feedback, reach out in the ``#ansible-network`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_). +If you need additional help or feedback, reach out to the community. Visit the :ref:`Ansible communication guide` for details. Unit test requirements ----------------------- diff --git a/docs/docsite/rst/network/getting_started/network_connection_options.rst b/docs/docsite/rst/network/getting_started/network_connection_options.rst index bdfb93cb97b..a7aba656373 100644 --- a/docs/docsite/rst/network/getting_started/network_connection_options.rst +++ b/docs/docsite/rst/network/getting_started/network_connection_options.rst @@ -29,8 +29,8 @@ Using vars (per task): - name: save running-config cisco.ios.ios_command: commands: copy running-config startup-config - vars: - ansible_command_timeout: 30 + vars: + ansible_command_timeout: 30 Using the environment variable: diff --git a/docs/docsite/rst/network/getting_started/network_resources.rst b/docs/docsite/rst/network/getting_started/network_resources.rst index a69aba905d7..fd636506175 100644 --- a/docs/docsite/rst/network/getting_started/network_resources.rst +++ b/docs/docsite/rst/network/getting_started/network_resources.rst @@ -8,6 +8,11 @@ Resources and next steps .. contents:: :local: +Community +========= + +Visit the :ref:`Ansible communication guide` for information on how to join the community. + Documents ========= @@ -35,13 +40,7 @@ Ansible hosts module code, examples, demonstrations, and other content on GitHub - `Ansible collections `_ is the main repository for Ansible-maintained and community collections, including collections for network devices. - - Chat channels ============= -Got questions? Chat with us on: - -* the ``#ansible-network`` channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) - -* `Ansible Network Slack `_ - Network & Security Automation Slack community. Check out the #devel channel for discussions on module and plugin development. +Visit the :ref:`Ansible communication guide` for information on how to join the conversation including available chat options. diff --git a/docs/docsite/rst/network/user_guide/platform_nxos.rst b/docs/docsite/rst/network/user_guide/platform_nxos.rst index de461aea300..78cee682768 100644 --- a/docs/docsite/rst/network/user_guide/platform_nxos.rst +++ b/docs/docsite/rst/network/user_guide/platform_nxos.rst @@ -87,10 +87,10 @@ Before you can use NX-API to connect to a switch, you must enable NX-API. To ena .. code-block:: yaml - name: Enable NX-API - cisco.nxos.nxos_nxapi: - enable_http: yes - enable_https: yes - when: ansible_network_os == 'cisco.nxos.nxos' + cisco.nxos.nxos_nxapi: + enable_http: yes + enable_https: yes + when: ansible_network_os == 'cisco.nxos.nxos' To find out more about the options for enabling HTTP/HTTPS and local http see the :ref:`nxos_nxapi ` module documentation. diff --git a/docs/docsite/rst/network/user_guide/validate.rst b/docs/docsite/rst/network/user_guide/validate.rst index 5837a2b85f6..3d91bf3a695 100644 --- a/docs/docsite/rst/network/user_guide/validate.rst +++ b/docs/docsite/rst/network/user_guide/validate.rst @@ -52,7 +52,6 @@ The following example fetches the operational state of some network (Cisco NXOS) - name: print structured interface state data ansible.builtin.debug: msg: "{{ nxos_pyats_show_interface['parsed'] }}" - ---- This results in the following structured data. diff --git a/docs/docsite/rst/os_guide/index.rst b/docs/docsite/rst/os_guide/index.rst index e073eabadb1..4ec283c455c 100644 --- a/docs/docsite/rst/os_guide/index.rst +++ b/docs/docsite/rst/os_guide/index.rst @@ -18,10 +18,5 @@ Find out everything you need to know about using Ansible on Windows and with BSD .. toctree:: :maxdepth: 2 - windows_setup - windows_usage - windows_winrm - windows_dsc - windows_performance - windows_faq - intro_bsd \ No newline at end of file + intro_bsd + intro_windows diff --git a/docs/docsite/rst/os_guide/intro_bsd.rst b/docs/docsite/rst/os_guide/intro_bsd.rst index 36ae0c9876b..18a3eb3ddc4 100644 --- a/docs/docsite/rst/os_guide/intro_bsd.rst +++ b/docs/docsite/rst/os_guide/intro_bsd.rst @@ -272,7 +272,5 @@ Please feel free to report any issues or incompatibilities you discover with BSD Learning Ansible's configuration management language :ref:`developing_modules` How to write modules - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/os_guide/intro_windows.rst b/docs/docsite/rst/os_guide/intro_windows.rst new file mode 100644 index 00000000000..fd626737b23 --- /dev/null +++ b/docs/docsite/rst/os_guide/intro_windows.rst @@ -0,0 +1,173 @@ +.. _working_with_windows: + +Managing Windows hosts with Ansible +=================================== + +Managing Windows hosts is different from managing POSIX hosts. If you have managed nodes running Windows, review these topics. + +.. contents:: + :local: + +This is an index of all the topics covered in this guide. + +.. toctree:: + :maxdepth: 1 + + windows_dsc + windows_performance + windows_ssh + windows_usage + windows_winrm + windows_winrm_certificate + windows_winrm_kerberos + + +Bootstrapping Windows +--------------------- + +Windows nodes must be running Windows Server 2016 or Windows 10 or newer. As these versions of Windows ship with PowerShell 5.1 by default there are no additional requirements to bootstrap a Windows node. + +Support for each Windows version is tied to the extended support lifecycle of each operating system, which is typically 10 years from the date of release. Ansible is tested against the server variants of Windows but should still be compatible with the desktop variants like Windows 10 and 11. + +Connecting to Windows nodes +--------------------------- + +Ansible connects to POSIX managed nodes using OpenSSH by default. Windows nodes can also use SSH but historically they use WinRM as the connection transport. The supported connection plugins that can be used with Windows nodes are: + +* PowerShell Remoting over WinRM - :ref:`psrp ` +* SSH - :ref:`ssh ` +* Windows Remote Management - :ref:`winrm ` + +PSRP and WinRM +"""""""""""""" + +Historically Ansible used Windows Remote Management (``WinRM``) as the connection protocol to manage Windows nodes. The ``psrp`` and ``winrm`` connection plugins both operate over WinRM and can be used as the connection plugin for Windows nodes. The ``psrp`` connection plugin is a newer connection plugin that offers a few benefits over the ``winrm`` connection plugin, for example: + +* Can be slightly faster +* Less susceptible to timeout issues when the Windows node is under load +* Better support for proxy servers + +See :ref:`windows_winrm` for more information on how WinRM is configured and how to use the ``psrp`` and ``winrm`` connection plugins in Ansible. + +SSH +""" + +SSH is the traditional connection plugin used with POSIX nodes but it can also be used to manage Windows nodes instead of the traditional ``psrp`` or ``winrm`` connection plugins. + +.. note:: + While Ansible has supported using the SSH connection plugin with Windows nodes since Ansible 2.8, official support was only added in version 2.18. + +Some of the benefits of using SSH over the WinRM based transports are: + +* SSH can be easier to configure in non-domain environments +* SSH supports key based authentication which is simpler to manage than certificates +* SSH file transfers are faster than WinRM + +See :ref:`windows_ssh` for more information on how to configure SSH for Windows nodes. + +Which modules are available? +---------------------------- + +The majority of the core Ansible modules are written for a combination of Unix-like machines and other generic services. As these modules are written in Python and use APIs not present on Windows they will not work. + +There are dedicated Windows modules that are written in PowerShell and are meant to be run on Windows hosts. A list of these modules can be in the :ref:`plugins_in_ansible.windows`, :ref:`plugins_in_community.windows`, :ref:`plugins_in_microsoft.ad`, :ref:`plugins_in_chocolatey.chocolatey`, and other collections. + +In addition, the following Ansible Core modules/action-plugins work with Windows: + +* add_host +* assert +* async_status +* debug +* fail +* fetch +* group_by +* include +* include_role +* include_vars +* meta +* pause +* raw +* script +* set_fact +* set_stats +* setup +* slurp +* template (also: win_template) +* wait_for_connection + +.. _windows_control_node: + +Using Windows as the control node +--------------------------------- + +Ansible cannot run on Windows as the control node due to API limitations on the platform. However, you can run Ansible on Windows using the Windows Subsystem for Linux (``WSL``) or in a container. + +.. note:: + The Windows Subsystem for Linux is not supported by Ansible and should not be used for production systems. + +Windows facts +------------- + +Ansible gathers facts from Windows in a similar manner to other POSIX hosts but with some differences. Some facts may be in a different format for backwards compatibility or may not be available at all. + +To see the facts that Ansible gathers from Windows hosts, run the ``setup`` module. + +.. code-block:: bash + + ansible windows -m setup + +Common Windows problems +----------------------- + +Command works locally but not under Ansible +""""""""""""""""""""""""""""""""""""""""""" + +Ansible executes commands through a network logon which can change how Windows authorizes actions. This can cause commands that work locally to fail under Ansible. Some examples of these failures are: + +* the process cannot delegate the user's credentials to a network resource, causing ``Access is Denied`` or ``Resource Unavailable`` errors +* applications that require an interactive session will not work +* some Windows APIs are restricted when running through a network logon +* some tasks require access to the ``DPAPI`` secrets store which is typically not available on a network logon + +The common way is to use :ref:`become` to run a command with explicit credentials. Using ``become`` on Windows will change the network logon to an interactive one and, if explicit credentials are provided to the become identity, the command will be able to access network resources and unlock the ``DPAPI`` store. + +Another option is to use an authentication option on the connection plugin that allows for credential delegation. For SSH this can be done with an explicit username and password or through a Kerberos/GSSAPI logon with delegation enabled. For WinRM based connections, the CredSSP or Kerberos with delegation can be used. See the connection specific documentation for more information. + +Credentials are rejected +"""""""""""""""""""""""" + +There are a few reasons why credentials might be rejected when connecting to the Windows host. Some common reasons are: + +* the username or password is incorrect +* the user account is locked out, disabled, not allowed to log onto that server +* the user account is not allowed to log on through the network +* the user account is not a member of the local Administrators group +* the user account is a local user and the ``LocalAccountTokenFilterPolicy`` is not set + +To verify whether the credentials are correct or the user is allowed to log onto the host you can run the below PowerShell command on the Windows host to see the last failed logon attempt. This will output event details including the ``Status`` and ``Sub Status`` error code indicating why the logon failed. + +.. code-block:: powershell + + Get-WinEvent -FilterHashtable @{LogName = 'Security'; Id = 4625} | + Select-Object -First 1 -ExpandProperty Message + +While not all connection plugins require the connection user to be a member of the local Administrators group, this is typically the default configuration. If the user is not a member of the local Administrators group or is a local user without ``LocalAccountTokenFilterPolicy`` set, the authentication will fail. + +.. seealso:: + + :ref:`intro_adhoc` + Examples of basic commands + :ref:`working_with_playbooks` + Learning Ansible's configuration management language + :ref:`developing_modules` + How to write modules + :ref:`windows_dsc` + Using Ansible with Windows Desired State Configuration + :ref:`windows_performance` + Performance considerations for managing Windows hosts + :ref:`windows_usage` + Windows usage guide + `Mailing List `_ + Questions? Help? Ideas? Stop by the list on Google Groups + :ref:`communication_irc` + How to join Ansible chat channels diff --git a/docs/docsite/rst/os_guide/windows_dsc.rst b/docs/docsite/rst/os_guide/windows_dsc.rst index f140bf43f35..59b05f55313 100644 --- a/docs/docsite/rst/os_guide/windows_dsc.rst +++ b/docs/docsite/rst/os_guide/windows_dsc.rst @@ -203,7 +203,7 @@ For example, to define a ``[CimInstance]`` value in Ansible: .. code-block:: yaml+jinja - # [CimInstance]AuthenticationInfo == MSFT_xWebAuthenticationInformation + # [CimInstance]AuthenticationInfo == DSC_WebAuthenticationInformation AuthenticationInfo: Anonymous: false Basic: true @@ -211,7 +211,7 @@ For example, to define a ``[CimInstance]`` value in Ansible: Windows: true In the above example, the CIM instance is a representation of the class -`MSFT_xWebAuthenticationInformation `_. +`DSC_WebAuthenticationInformation `_. This class accepts four boolean variables, ``Anonymous``, ``Basic``, ``Digest``, and ``Windows``. The keys to use in a ``[CimInstance]`` depend on the class it represents. Please read through the documentation of the resource @@ -253,7 +253,7 @@ like this example: .. code-block:: yaml+jinja - # [CimInstance[]]BindingInfo == MSFT_xWebBindingInformation + # [CimInstance[]]BindingInfo == DSC_WebBindingInformation BindingInfo: - Protocol: https Port: 443 @@ -266,7 +266,7 @@ like this example: Port: 80 IPAddress: '*' -The above example is an array with two values of the class `MSFT_xWebBindingInformation `_. +The above example is an array with two values of the class `DSC_WebBindingInformation `_. When defining a ``[CimInstance[]]``, be sure to read the resource documentation to find out what keys to use in the definition. @@ -502,7 +502,5 @@ Setup IIS Website Tips and tricks for playbooks :ref:`List of Windows Modules ` Windows-specific module list, all implemented in PowerShell - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/os_guide/windows_faq.rst b/docs/docsite/rst/os_guide/windows_faq.rst index 231b5c661ed..ec937f8d13b 100644 --- a/docs/docsite/rst/os_guide/windows_faq.rst +++ b/docs/docsite/rst/os_guide/windows_faq.rst @@ -1,249 +1,6 @@ -.. _windows_faq: +:orphan: Windows Frequently Asked Questions ================================== -Here are some commonly asked questions in regard to Ansible and Windows and -their answers. - -.. note:: This document covers questions about managing Microsoft Windows servers with Ansible. - For questions about Ansible Core, please see the - :ref:`general FAQ page `. - -Does Ansible work with Windows XP or Server 2003? -`````````````````````````````````````````````````` -Ansible does not work with Windows XP or Server 2003 hosts. Ansible does work with these Windows operating system versions: - -* Windows Server 2016 -* Windows Server 2019 -* Windows Server 2022 -* Windows 10 -* Windows 11 - -Support for Windows Server 2008, 2008 R2, and Windows 7 ended in the 2.10 -release. Support for Windows Server 2012, 2012 R2, Windows 8, and 8.1 ended in -the 2.16 release. - -Ansible also has minimum PowerShell version requirements - please see -:ref:`windows_setup` for the latest information. - -Can I manage Windows Nano Server with Ansible? -`````````````````````````````````````````````` -Ansible does not currently work with Windows Nano Server, since it does -not have access to the full .NET Framework that is used by the majority of the -modules and internal components. - -.. _windows_faq_ansible: - -Can Ansible run on Windows? -``````````````````````````` -No, Ansible can only manage Windows hosts. Ansible cannot run on a Windows host -natively, though it can run under the Windows Subsystem for Linux (WSL). - -.. note:: The Windows Subsystem for Linux is not supported by Ansible and - should not be used for production systems. - -To install Ansible on WSL, the following commands -can be run in the bash terminal: - -.. code-block:: shell - - sudo apt-get update - sudo apt-get install python3-pip git libffi-dev libssl-dev -y - pip install --user ansible pywinrm - -To run Ansible from source instead of a release on the WSL, simply uninstall the pip -installed version and then clone the git repo. - -.. code-block:: shell - - pip uninstall ansible -y - git clone https://github.com/ansible/ansible.git - source ansible/hacking/env-setup - - # To enable Ansible on login, run the following - echo ". ~/ansible/hacking/env-setup -q' >> ~/.bashrc - -If you encounter timeout errors when running Ansible on the WSL, this may be due to an issue -with ``sleep`` not returning correctly. The following workaround may resolve the issue: - -.. code-block:: shell - - mv /usr/bin/sleep /usr/bin/sleep.orig - ln -s /bin/true /usr/bin/sleep - -Another option is to use WSL 2 if running Windows 10 later than build 2004. - -.. code-block:: shell - - wsl --set-default-version 2 - - -Can I use SSH keys to authenticate to Windows hosts? -```````````````````````````````````````````````````` -You cannot use SSH keys with the WinRM or PSRP connection plugins. -These connection plugins use X509 certificates for authentication instead -of the SSH key pairs that SSH uses. - -The way X509 certificates are generated and mapped to a user is different -from the SSH implementation; consult the :ref:`windows_winrm` documentation for -more information. - -Ansible 2.8 has added an experimental option to use the SSH connection plugin, -which uses SSH keys for authentication, for Windows servers. See :ref:`this question ` -for more information. - -.. _windows_faq_winrm: - -Why can I run a command locally that does not work under Ansible? -````````````````````````````````````````````````````````````````` -Ansible executes commands through WinRM. These processes are different from -running a command locally in these ways: - -* Unless using an authentication option like CredSSP or Kerberos with - credential delegation, the WinRM process cannot - delegate the user's credentials to a network resource, causing ``Access is - Denied`` errors. - -* All processes run under WinRM are in a non-interactive session. Applications - that require an interactive session will not work. - -* When running through WinRM, Windows restricts access to internal Windows - APIs like the Windows Update API and DPAPI, which some installers and - programs rely on. - -Some ways to bypass these restrictions are to: - -* Use ``become``, which runs a command as it would when run locally. This will - bypass most WinRM restrictions, as Windows is unaware the process is running - under WinRM when ``become`` is used. See the :ref:`become` documentation for more - information. - -* Use a scheduled task, which can be created with ``win_scheduled_task``. Like - ``become``, it will bypass all WinRM restrictions, but it can only be used to run - commands, not modules. - -* Use ``win_psexec`` to run a command on the host. PSExec does not use WinRM - and so will bypass any of the restrictions. - -* To access network resources without any of these workarounds, you can use - CredSSP or Kerberos with credential delegation enabled. - -See :ref:`become` more info on how to use become. The limitations section at -:ref:`windows_winrm` has more details about WinRM limitations. - -This program won't install on Windows with Ansible -`````````````````````````````````````````````````` -See :ref:`this question ` for more information about WinRM limitations. - -What Windows modules are available? -``````````````````````````````````` -Most of the Ansible modules in Ansible Core are written for a combination of -Linux/Unix machines and arbitrary web services. These modules are written in -Python and most of them do not work on Windows. - -Because of this, there are dedicated Windows modules that are written in -PowerShell and are meant to be run on Windows hosts. A list of these modules -can be found :ref:`here `. - -In addition, the following Ansible Core modules/action-plugins work with Windows: - -* add_host -* assert -* async_status -* debug -* fail -* fetch -* group_by -* include -* include_role -* include_vars -* meta -* pause -* raw -* script -* set_fact -* set_stats -* setup -* slurp -* template (also: win_template) -* wait_for_connection - -Ansible Windows modules exist in the :ref:`plugins_in_ansible.windows`, :ref:`plugins_in_community.windows`, and :ref:`plugins_in_chocolatey.chocolatey` collections. - -Can I run Python modules on Windows hosts? -`````````````````````````````````````````` -No, the WinRM connection protocol is set to use PowerShell modules, so Python -modules will not work. A way to bypass this issue is to use -``delegate_to: localhost`` to run a Python module on the Ansible control node. -This is useful if during a playbook, an external service needs to be contacted -and there is no equivalent Windows module available. - -.. _windows_faq_ssh: - -Can I connect to Windows hosts over SSH? -```````````````````````````````````````` -Ansible 2.8 has added an experimental option to use the SSH connection plugin -to manage Windows hosts. To connect to Windows hosts over SSH, you must install and configure the `Win32-OpenSSH `_ -fork that is in development with Microsoft on -the Windows host(s). While most of the basics should work with SSH, -``Win32-OpenSSH`` is rapidly changing, with new features added and bugs -fixed in every release. It is highly recommend you `install `_ the latest release -of ``Win32-OpenSSH`` from the GitHub Releases page when using it with Ansible -on Windows hosts. - -To use SSH as the connection to a Windows host, set the following variables in -the inventory: - -.. code-block:: shell - - ansible_connection=ssh - - # Set either cmd or powershell not both - ansible_shell_type=cmd - # ansible_shell_type=powershell - -The value for ``ansible_shell_type`` should either be ``cmd`` or ``powershell``. -Use ``cmd`` if the ``DefaultShell`` has not been configured on the SSH service -and ``powershell`` if that has been set as the ``DefaultShell``. - -Why is connecting to a Windows host through SSH failing? -```````````````````````````````````````````````````````` -Unless you are using ``Win32-OpenSSH`` as described above, you must connect to -Windows hosts using :ref:`windows_winrm`. If your Ansible output indicates that -SSH was used, either you did not set the connection vars properly or the host is not inheriting them correctly. - -Make sure ``ansible_connection: winrm`` is set in the inventory for the Windows -host(s). - -Why are my credentials being rejected? -`````````````````````````````````````` -This can be due to a myriad of reasons unrelated to incorrect credentials. - -See HTTP 401/Credentials Rejected at :ref:`windows_setup` for a more detailed -guide of this could mean. - -Why am I getting an error SSL CERTIFICATE_VERIFY_FAILED? -```````````````````````````````````````````````````````` -When the Ansible control node is running on Python 2.7.9+ or an older version of Python that -has backported SSLContext (like Python 2.7.5 on RHEL 7), the control node will attempt to -validate the certificate WinRM is using for an HTTPS connection. If the -certificate cannot be validated (such as in the case of a self-signed cert), it will -fail the verification process. - -To ignore certificate validation, add -``ansible_winrm_server_cert_validation: ignore`` to inventory for the Windows -host. - -.. seealso:: - - :ref:`windows` - The Windows documentation index - :ref:`about_playbooks` - An introduction to playbooks - :ref:`playbooks_best_practices` - Tips and tricks for playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels +This page has moved to :ref:`working_with_windows`. \ No newline at end of file diff --git a/docs/docsite/rst/os_guide/windows_setup.rst b/docs/docsite/rst/os_guide/windows_setup.rst index c31d20138f4..2ae30b78b25 100644 --- a/docs/docsite/rst/os_guide/windows_setup.rst +++ b/docs/docsite/rst/os_guide/windows_setup.rst @@ -1,507 +1,6 @@ -.. _windows_setup: +:orphan: -Setting up a Windows Host +Setting up a windows Host ========================= -This document discusses the setup that is required before Ansible can communicate with a Microsoft Windows host. -.. contents:: - :local: - -Host Requirements -````````````````` -For Ansible to communicate with a Windows host and use Windows modules, the -Windows host must meet these base requirements for connectivity: - -* With Ansible you can generally manage Windows versions under the current and extended support from Microsoft. You can also manage desktop OSs including Windows 10 and 11, and server OSs including Windows Server 2016, 2019, and 2022. - -* You need to install PowerShell 5.1 or newer and at least .NET 4.0 on the Windows host. - -* You need to create and activate a WinRM listener. More details, see :ref:`winrm_listener`. - -.. Note:: Some Ansible modules have additional requirements, such as a newer OS or PowerShell version. Consult the module documentation page to determine whether a host meets those requirements. - -Upgrading PowerShell and .NET Framework ---------------------------------------- -Ansible requires PowerShell version 5.1 and .NET Framework 4.6 or newer to function. The base image for older unsupported OS' does not meet these -requirements. You can use the `Upgrade-PowerShell.ps1 `_ script to update these. - -This is an example of how to run this script from PowerShell: - -.. code-block:: powershell - - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/scripts/Upgrade-PowerShell.ps1" - $file = "$env:temp\Upgrade-PowerShell.ps1" - $username = "Administrator" - $password = "Password" - - (New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file) - Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force - - &$file -Version 5.1 -Username $username -Password $password -Verbose - -In the script, the ``file`` value can be the PowerShell version 3.0, 4.0, or 5.1. - -Once completed, you need to run the following PowerShell commands: - -1. As an optional but good security practice, you can set the execution policy back to the default. - -.. code-block:: powershell - - Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force - -Use the ``RemoteSigned`` value for Windows servers, or ``Restricted`` for Windows clients. - -2. Remove the auto logon. - -.. code-block:: powershell - - $reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" - Set-ItemProperty -Path $reg_winlogon_path -Name AutoAdminLogon -Value 0 - Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultUserName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultPassword -ErrorAction SilentlyContinue - -The script determines what programs you need to install (such as .NET Framework 4.5.2) and what PowerShell version needs to be present. If a reboot is needed and the ``username`` and ``password`` parameters are set, the script will automatically reboot the machine and then logon. If the ``username`` and ``password`` parameters are not set, the script will prompt the user to manually reboot and logon when required. When the user is next logged in, the script will continue where it left off and the process continues until no more -actions are required. - -.. Note:: If you run the script on Server 2008, then you need to install SP2. For Server 2008 R2 or Windows 7, you need SP1. - - On Windows Server 2008, you can install only PowerShell 3.0. A newer version will result in the script failure. - - The ``username`` and ``password`` parameters are stored in plain text in the registry. Run the cleanup commands after the script finishes to ensure no credentials are stored on the host. - - -WinRM Memory Hotfix -------------------- -On PowerShell v3.0, there is a bug that limits the amount of memory available to the WinRM service. Use the `Install-WMF3Hotfix.ps1 `_ script to install a hotfix on affected hosts as part of the system bootstrapping or imaging process. Without this hotfix, Ansible fails to execute certain commands on the Windows host. - -To install the hotfix: - -.. code-block:: powershell - - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/scripts/Install-WMF3Hotfix.ps1" - $file = "$env:temp\Install-WMF3Hotfix.ps1" - - (New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file) - powershell.exe -ExecutionPolicy ByPass -File $file -Verbose - -For more details, refer to the `"Out of memory" error on a computer that has a customized MaxMemoryPerShellMB quota set and has WMF 3.0 installed `_ article. - -WinRM Setup -``````````` -You need to configure the WinRM service so that Ansible can connect to it. There are two main components of the WinRM service that govern how Ansible can interface with the Windows host: the ``listener`` and the ``service`` configuration settings. - -.. Note:: - The script for setting up this service is `available to download on GitHub `_. - Reason being that using it can cause several issues for the user. Chances are it will be completely taken down in the future. - - - -.. _winrm_listener: - -WinRM Listener --------------- -The WinRM services listen for requests on one or more ports. Each of these ports must have a listener created and configured. - -To view the current listeners that are running on the WinRM service: - -.. code-block:: powershell - - winrm enumerate winrm/config/Listener - -This will output something like: - -.. code-block:: powershell - - Listener - Address = * - Transport = HTTP - Port = 5985 - Hostname - Enabled = true - URLPrefix = wsman - CertificateThumbprint - ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80:: - ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7 - - Listener - Address = * - Transport = HTTPS - Port = 5986 - Hostname = SERVER2016 - Enabled = true - URLPrefix = wsman - CertificateThumbprint = E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE - ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80:: - ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7 - -In the example above there are two listeners activated. One is listening on port 5985 over HTTP and the other is listening on port 5986 over HTTPS. Some of the key options that are useful to understand are: - -* ``Transport``: Whether the listener is run over HTTP or HTTPS. We recommend you use a listener over HTTPS because the data is encrypted without any further changes required. - -* ``Port``: The port the listener runs on. By default, it is ``5985`` for HTTP and ``5986`` for HTTPS. This port can be changed to whatever is required and corresponds to the host var ``ansible_port``. - -* ``URLPrefix``: The URL prefix to listen on. By default, it is ``wsman``. If you change this option, you need to set the host var ``ansible_winrm_path`` to the same value. - -* ``CertificateThumbprint``: If you use an HTTPS listener, this is the thumbprint of the certificate in the Windows Certificate Store that is used in the connection. To get the details of the certificate itself, run this command with the relevant certificate thumbprint in PowerShell: - -.. code-block:: powershell - - $thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" - Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object { $_.Thumbprint -eq $thumbprint } | Select-Object * - -Setup WinRM Listener -++++++++++++++++++++ -There are three ways to set up a WinRM listener: - -* Using ``winrm quickconfig`` for HTTP or ``winrm quickconfig -transport:https`` for HTTPS. This is the easiest option to use when running outside of a domain environment and a simple listener is required. Unlike the other options, this process also has the added benefit of opening up the firewall for the ports required and starting the WinRM service. - -* Using Group Policy Objects (GPO). This is the best way to create a listener when the host is a member of a domain because the configuration is done automatically without any user input. For more information on group policy objects, see the `Group Policy Objects documentation `_. - -* Using PowerShell to create a listener with a specific configuration. This can be done by running the following PowerShell commands: - - .. code-block:: powershell - - $selector_set = @{ - Address = "*" - Transport = "HTTPS" - } - $value_set = @{ - CertificateThumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" - } - - New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selector_set -ValueSet $value_set - - To see the other options with this PowerShell command, refer to the - `New-WSManInstance `_ documentation. - -.. Note:: When creating an HTTPS listener, you must create and store a certificate in the ``LocalMachine\My`` certificate store. - -Delete WinRM Listener -+++++++++++++++++++++ -* To remove all WinRM listeners: - -.. code-block:: powershell - - Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force - -* To remove only those listeners that run over HTTPS: - -.. code-block:: powershell - - Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -contains "Transport=HTTPS" } | Remove-Item -Recurse -Force - -.. Note:: The ``Keys`` object is an array of strings, so it can contain different values. By default, it contains a key for ``Transport=`` and ``Address=`` which correspond to the values from the ``winrm enumerate winrm/config/Listeners`` command. - -WinRM Service Options ---------------------- -You can control the behavior of the WinRM service component, including authentication options and memory settings. - -To get an output of the current service configuration options, run the following command: - -.. code-block:: powershell - - winrm get winrm/config/Service - winrm get winrm/config/Winrs - -This will output something like: - -.. code-block:: powershell - - Service - RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD) - MaxConcurrentOperations = 4294967295 - MaxConcurrentOperationsPerUser = 1500 - EnumerationTimeoutms = 240000 - MaxConnections = 300 - MaxPacketRetrievalTimeSeconds = 120 - AllowUnencrypted = false - Auth - Basic = true - Kerberos = true - Negotiate = true - Certificate = true - CredSSP = true - CbtHardeningLevel = Relaxed - DefaultPorts - HTTP = 5985 - HTTPS = 5986 - IPv4Filter = * - IPv6Filter = * - EnableCompatibilityHttpListener = false - EnableCompatibilityHttpsListener = false - CertificateThumbprint - AllowRemoteAccess = true - - Winrs - AllowRemoteShellAccess = true - IdleTimeout = 7200000 - MaxConcurrentUsers = 2147483647 - MaxShellRunTime = 2147483647 - MaxProcessesPerShell = 2147483647 - MaxMemoryPerShellMB = 2147483647 - MaxShellsPerUser = 2147483647 - -You do not need to change the majority of these options. However, some of the important ones to know about are: - -* ``Service\AllowUnencrypted`` - specifies whether WinRM will allow HTTP traffic without message encryption. Message level encryption is only possible when the ``ansible_winrm_transport`` variable is ``ntlm``, ``kerberos`` or ``credssp``. By default, this is ``false`` and you should only set it to ``true`` when debugging WinRM messages. - -* ``Service\Auth\*`` - defines what authentication options you can use with the WinRM service. By default, ``Negotiate (NTLM)`` and ``Kerberos`` are enabled. - -* ``Service\Auth\CbtHardeningLevel`` - specifies whether channel binding tokens are not verified (None), verified but not required (Relaxed), or verified and required (Strict). CBT is only used when connecting with NT LAN Manager (NTLM) or Kerberos over HTTPS. - -* ``Service\CertificateThumbprint`` - thumbprint of the certificate for encrypting the TLS channel used with CredSSP authentication. By default, this is empty. A self-signed certificate is generated when the WinRM service starts and is used in the TLS process. - -* ``Winrs\MaxShellRunTime`` - maximum time, in milliseconds, that a remote command is allowed to execute. - -* ``Winrs\MaxMemoryPerShellMB`` - maximum amount of memory allocated per shell, including its child processes. - -To modify a setting under the ``Service`` key in PowerShell, you need to provide a path to the option after ``winrm/config/Service``: - -.. code-block:: powershell - - Set-Item -Path WSMan:\localhost\Service\{path} -Value {some_value} - -For example, to change ``Service\Auth\CbtHardeningLevel``: - -.. code-block:: powershell - - Set-Item -Path WSMan:\localhost\Service\Auth\CbtHardeningLevel -Value Strict - -To modify a setting under the ``Winrs`` key in PowerShell, you need to provide a path to the option after ``winrm/config/Winrs``: - -.. code-block:: powershell - - Set-Item -Path WSMan:\localhost\Shell\{path} -Value {some_value} - -For example, to change ``Winrs\MaxShellRunTime``: - -.. code-block:: powershell - - Set-Item -Path WSMan:\localhost\Shell\MaxShellRunTime -Value 2147483647 - -.. Note:: If you run the command in a domain environment, some of these options are set by - GPO and cannot be changed on the host itself. When you configure a key with GPO, it contains the text ``[Source="GPO"]`` next to the value. - -Common WinRM Issues -------------------- -WinRM has a wide range of configuration options, which makes its configuration complex. As a result, errors that Ansible displays could in fact be problems with the host setup instead. - -To identify a host issue, run the following command from another Windows host to connect to the target Windows host. - -* To test HTTP: - -.. code-block:: powershell - - winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig - -* To test HTTPS: - -.. code-block:: powershell - - winrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfig - -The command will fail if the certificate is not verifiable. - -* To test HTTPS ignoring certificate verification: - -.. code-block:: powershell - - $username = "Username" - $password = ConvertTo-SecureString -String "Password" -AsPlainText -Force - $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password - - $session_option = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck - Invoke-Command -ComputerName server -UseSSL -ScriptBlock { ipconfig } -Credential $cred -SessionOption $session_option - -If any of the above commands fail, the issue is probably related to the WinRM setup. - -HTTP 401/Credentials Rejected -+++++++++++++++++++++++++++++ -An HTTP 401 error indicates the authentication process failed during the initial -connection. You can check the following to troubleshoot: - -* The credentials are correct and set properly in your inventory with the ``ansible_user`` and ``ansible_password`` variables. - -* The user is a member of the local Administrators group or has been explicitly granted access. You can perform a connection test with the ``winrs`` command to rule this out. - -* The authentication option set by the ``ansible_winrm_transport`` variable is enabled under ``Service\Auth\*``. - -* If running over HTTP and not HTTPS, use ``ntlm``, ``kerberos`` or ``credssp`` with the ``ansible_winrm_message_encryption: auto`` custom inventory variable to enable message encryption. If you use another authentication option, or if it is not possible to upgrade the installed ``pywinrm`` package, you can set ``Service\AllowUnencrypted`` to ``true``. This is recommended only for troubleshooting. - -* The downstream packages ``pywinrm``, ``requests-ntlm``, ``requests-kerberos``, and/or ``requests-credssp`` are up to date using ``pip``. - -* For Kerberos authentication, ensure that ``Service\Auth\CbtHardeningLevel`` is not set to ``Strict``. - -* For Basic or Certificate authentication, make sure that the user is a local account. Domain accounts do not work with Basic and Certificate authentication. - -HTTP 500 Error -++++++++++++++ -An HTTP 500 error indicates a problem with the WinRM service. You can check the following to troubleshoot: - -* The number of your currently open shells has not exceeded either ``WinRsMaxShellsPerUser``. Alternatively, you did not exceed any of the other Winrs quotas. - -Timeout Errors -+++++++++++++++ -Sometimes Ansible is unable to reach the host. These instances usually indicate a problem with the network connection. You can check the following to troubleshoot: - -* The firewall is not set to block the configured WinRM listener ports. -* A WinRM listener is enabled on the port and path set by the host vars. -* The ``winrm`` service is running on the Windows host and is configured for the automatic start. - -Connection Refused Errors -+++++++++++++++++++++++++ -When you communicate with the WinRM service on the host you may encounter some problems. Check the following to help with the troubleshooting: - -* The WinRM service is up and running on the host. Use the ``(Get-Service -Name winrm).Status`` command to get the status of the service. -* The host firewall is allowing traffic over the WinRM port. By default, this is ``5985`` for HTTP and ``5986`` for HTTPS. - -Sometimes an installer may restart the WinRM or HTTP service and cause this error. The best way to deal with this is to use the ``win_psexec`` module from another Windows host. - -Failure to Load Builtin Modules -+++++++++++++++++++++++++++++++ -Sometimes PowerShell fails with an error message similar to: - -.. code-block:: powershell - - The 'Out-String' command was found in the module 'Microsoft.PowerShell.Utility', but the module could not be loaded. - -In that case, there could be a problem when trying to access all the paths specified by the ``PSModulePath`` environment variable. - -A common cause of this issue is that ``PSModulePath`` contains a Universal Naming Convention (UNC) path to a file share. Additionally, the double hop/credential delegation issue causes that the Ansible process cannot access these folders. To work around this problem is to either: - -* Remove the UNC path from ``PSModulePath``. - -or - -* Use an authentication option that supports credential delegation like ``credssp`` or ``kerberos``. You need to have the credential delegation enabled. - -See `KB4076842 `_ for more information on this problem. - -Windows SSH Setup -````````````````` -Ansible 2.8 has added an experimental SSH connection for Windows-managed nodes. - -.. warning:: - Use this feature at your own risk! Using SSH with Windows is experimental. This implementation may make - backwards incompatible changes in future releases. The server-side components can be unreliable depending on your installed version. - -Installing OpenSSH using Windows Settings ------------------------------------------ -You can use OpenSSH to connect Windows 10 clients to Windows Server 2019. OpenSSH Client is available to install on Windows 10 build 1809 and later. OpenSSH Server is available to install on Windows Server 2019 and later. - -For more information, refer to `Get started with OpenSSH for Windows `_. - -Installing Win32-OpenSSH ------------------------- -To install the `Win32-OpenSSH `_ service for use with -Ansible, select one of these installation options: - -* Manually install ``Win32-OpenSSH``, following the `install instructions `_ from Microsoft. - -* Use Chocolatey: - -.. code-block:: powershell - - choco install --package-parameters=/SSHServerFeature openssh - -* Use the ``win_chocolatey`` Ansible module: - -.. code-block:: yaml - - - name: install the Win32-OpenSSH service - win_chocolatey: - name: openssh - package_params: /SSHServerFeature - state: present - -* Install an Ansible Galaxy role for example `jborean93.win_openssh `_: - -.. code-block:: powershell - - ansible-galaxy install jborean93.win_openssh - -* Use the role in your playbook: - -.. code-block:: yaml - - - name: install Win32-OpenSSH service - hosts: windows - gather_facts: false - roles: - - role: jborean93.win_openssh - opt_openssh_setup_service: True - -.. note:: ``Win32-OpenSSH`` is still a beta product and is constantly being updated to include new features and bug fixes. If you use SSH as a connection option for Windows, we highly recommend you install the latest version. - -Configuring the Win32-OpenSSH shell ------------------------------------ - -By default, ``Win32-OpenSSH`` uses ``cmd.exe`` as a shell. - -* To configure a different shell, use an Ansible playbook with a task to define the registry setting: - -.. code-block:: yaml - - - name: set the default shell to PowerShell - win_regedit: - path: HKLM:\SOFTWARE\OpenSSH - name: DefaultShell - data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - type: string - state: present - -* To revert the settings to the default shell: - -.. code-block:: yaml - - - name: set the default shell to cmd - win_regedit: - path: HKLM:\SOFTWARE\OpenSSH - name: DefaultShell - state: absent - -Win32-OpenSSH Authentication ----------------------------- -Win32-OpenSSH authentication with Windows is similar to SSH authentication on Unix/Linux hosts. You can use a plaintext password or SSH public key authentication. - -For the key-based authentication: - -* Add your public keys to an ``authorized_key`` file in the ``.ssh`` folder of the user's profile directory. - -* Configure the SSH service using the ``sshd_config`` file. - -When using SSH key authentication with Ansible, the remote session will not have access to user credentials and will fail when attempting to access a network resource. This is also known as the double-hop or credential delegation issue. To work around this problem: - -* Use plaintext password authentication by setting the ``ansible_password`` variable. -* Use the ``become`` directive on the task with the credentials of the user that needs access to the remote resource. - -Configuring Ansible for SSH on Windows --------------------------------------- -To configure Ansible to use SSH for Windows hosts, you must set two connection variables: - -* set ``ansible_connection`` to ``ssh`` -* set ``ansible_shell_type`` to ``cmd`` or ``powershell`` - -The ``ansible_shell_type`` variable should reflect the ``DefaultShell`` configured on the Windows host. Set ``ansible_shell_type`` to ``cmd`` for the default shell. Alternatively, set ``ansible_shell_type`` to ``powershell`` if you changed ``DefaultShell`` to PowerShell. - -Known issues with SSH on Windows --------------------------------- -Using SSH with Windows is experimental. Currently, existing issues are: - -* Win32-OpenSSH versions older than ``v7.9.0.0p1-Beta`` do not work when ``powershell`` is the shell type. -* While Secure Copy Protocol (SCP) should work, SSH File Transfer Protocol (SFTP) is the recommended mechanism to use when copying or fetching a file. - -.. seealso:: - - :ref:`about_playbooks` - An introduction to playbooks - :ref:`playbooks_best_practices` - Tips and tricks for playbooks - :ref:`List of Windows Modules ` - Windows-specific module list, all implemented in PowerShell - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels +This page has moved to :ref:`windows_winrm`. \ No newline at end of file diff --git a/docs/docsite/rst/os_guide/windows_ssh.rst b/docs/docsite/rst/os_guide/windows_ssh.rst new file mode 100644 index 00000000000..e55b9049b00 --- /dev/null +++ b/docs/docsite/rst/os_guide/windows_ssh.rst @@ -0,0 +1,198 @@ +.. _windows_ssh: + +Windows SSH +=========== + +On newer Windows versions, you can use SSH to connect to a Windows host. This is an alternative connection option to :ref:`WinRM `. + +.. note:: + While Ansible could use the SSH connection plugin with Windows nodes since Ansible 2.8, official support was only added in version 2.18. + +.. contents:: + :local: + + +SSH Setup +--------- + +Microsoft provides an OpenSSH implementation with Windows since Windows Server 2019 as a Windows capability. It can also be installed through an upstream package under `Win32-OpenSSH `_. Ansible officially only supports the OpenSSH implementation shipped with Windows, not the upstream package. The OpenSSH version must be version ``7.9.0.0`` at a minimum. This effectively means official support starts with Windows Server 2022 because Server 2019 ships with version ``7.7.2.1``. Using older Windows versions or the upstream package might work but is not supported. + +To install the OpenSSH feature on Windows Server 2022 and later, use the following PowerShell command: + +.. code-block:: powershell + + Get-WindowsCapability -Name OpenSSH.Server* -Online | + Add-WindowsCapability -Online + Set-Service -Name sshd -StartupType Automatic -Status Running + + $firewallParams = @{ + Name = 'sshd-Server-In-TCP' + DisplayName = 'Inbound rule for OpenSSH Server (sshd) on TCP port 22' + Action = 'Allow' + Direction = 'Inbound' + Enabled = 'True' # This is not a boolean but an enum + Profile = 'Any' + Protocol = 'TCP' + LocalPort = 22 + } + New-NetFirewallRule @firewallParams + + $shellParams = @{ + Path = 'HKLM:\SOFTWARE\OpenSSH' + Name = 'DefaultShell' + Value = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' + PropertyType = 'String' + Force = $true + } + New-ItemProperty @shellParams + + +Default Shell Configuration +""""""""""""""""""""""""""" + +By default, OpenSSH on Windows uses ``cmd.exe`` as the default shell. While Ansible can work with this default shell it is recommended to change this to ``powershell.exe`` as it is better tested and should be faster than having ``cmd.exe`` as the default. To change the default shell you can use the following PowerShell script: + +.. code-block:: powershell + + # Set default to powershell.exe + $shellParams = @{ + Path = 'HKLM:\SOFTWARE\OpenSSH' + Name = 'DefaultShell' + Value = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' + PropertyType = 'String' + Force = $true + } + New-ItemProperty @shellParams + + # Set default back to cmd.exe + Remove-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell + +The new default shell setting will apply to the next SSH connection, there is no need to restart the ``sshd`` service. You can also use Ansible to configure the default shell: + +.. code-block:: yaml + + - name: set the default shell to PowerShell + ansible.windows.win_regedit: + path: HKLM:\SOFTWARE\OpenSSH + name: DefaultShell + data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe + type: string + state: present + + - name: reset SSH connection after shell change + ansible.builtin.meta: reset_connection + + - name: set the default shell to cmd + ansible.windows.win_regedit: + path: HKLM:\SOFTWARE\OpenSSH + name: DefaultShell + state: absent + + - name: reset SSH connection after shell change + ansible.builtin.meta: reset_connection + +The ``meta: reset_connection`` is important to ensure the subsequent tasks will use the new default shell. + + +Ansible Configuration +--------------------- + +To configure Ansible to use SSH for Windows hosts, you must set two connection variables: + +* set ``ansible_connection`` to ``ssh`` +* set ``ansible_shell_type`` to ``powershell`` or ``cmd`` + +The ``ansible_shell_type`` variable should reflect the ``DefaultShell`` configured on the Windows host. Other SSH options as documented under the :ref:`ssh ` can also be set for the Windows host. + + +SSH Authentication +------------------ +Win32-OpenSSH authentication with Windows is similar to SSH authentication on Unix/Linux hosts. While there are many authentication methods that can be used there are typically three used on Windows: + ++----------+----------------+---------------------------+-----------------------+ +| Option | Local Accounts | Active Directory Accounts | Credential Delegation | ++==========+================+===========================+=======================+ +| Key | Yes | Yes | No | ++----------+----------------+---------------------------+-----------------------+ +| GSSAPI | No | Yes | Yes | ++----------+----------------+---------------------------+-----------------------+ +| Password | Yes | Yes | Yes | ++----------+----------------+---------------------------+-----------------------+ + +In most cases it is recommended to use key or GSSAPI authentication over password authentication. + +Key Authentication +"""""""""""""""""" + +SSH key authentication on Windows works in the same way as SSH key authentication for POSIX nodes. You can generate a key pair using the ``ssh-keygen`` command and add the public key to the ``authorized_keys`` file in the user's profile directory. The private key should be kept secure and not shared. + +One difference is that the ``authorized_keys`` file for admin users is not located in the ``.ssh`` folder in the user's profile directory but in ``C:\ProgramData\ssh\administrators_authorized_keys``. It is possible to change the location of the ``authorized_keys`` file for admin users back to the user profile directory by removing, or commenting, the lines in ``C:\ProgramData\ssh\sshd_config`` and restarting the ``sshd`` service. + +.. code-block:: + + Match Group administrators + AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys + +SSH keys work with both local and domain accounts but suffer from the double-hop issue. This means that when using SSH key authentication with Ansible, the remote session will not have access to user credentials and will fail when attempting to access a network resource. To work around this problem, you can use :ref:`become ` on the task with the credentials of the user that needs access to the remote resource. + + +GSSAPI Authentication +""""""""""""""""""""" + +GSSAPI authentication will use Kerberos to authenticate the user with the Windows host. To use GSSAPI authentication with Ansible, the Windows server must be configured to allow GSSAPI authentication by editing the ``C:\ProgramData\ssh\sshd_config`` file. Either add in the following line or edit the existing line: + +.. code-block:: text + + GSSAPIAuthentication yes + +Once edited restart the ``sshd`` service with ``Restart-Service -Name sshd``. + +On the Ansible control node, you need to have Kerberos installed and configured with the domain the Windows host is a member of. How to set this up and configure is outside the scope of this document. Once the Kerberos realm is configured you can use the ``kinit`` command to get a ticket for the user you are connecting with and ``klist`` to verify what tickets are available: + +.. code-block:: bash + + > kinit username@REALM.COM + Password for username@REALM.COM + + > klist + Ticket cache: KCM:1000 + Default principal: username@REALM.COM + + Valid starting Expires Service principal + 29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/REALM.COM@REALM.COM + renew until 05/09/24 13:54:48 + +Once you have a valid ticket you can use the ``ansible_user`` hostvar to specify the UPN username and Ansible will automatically use the Kerberos ticket for that user when using SSH. + +It is also possible to enable unconstrained delegation through GSSAPI authentication to have the Windows node access network resources. For GSSAPI delegation to work the ticket retrieved by ``kinit`` must be forwardable and ``ssh`` must be called with the ``-o GSSAPIDelegateCredentials=yes`` option. To retrieve a forwardable ticket either use the ``-f`` flag with ``kinit`` or add ``forwardable = true`` under ``[libdefaults]`` in the ``/etc/krb5.conf`` file. + +.. code-block:: bash + + > kinit -f username@REALM.COM + Password for username@REALM.COM + + # -f will show the ticket flags, we want to see F + > klist -f + Ticket cache: KCM:1000 + Default principal: username@REALM.COM + + Valid starting Expires Service principal + 29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/REALM.COM@REALM.COM + renew until 05/09/24 13:54:48, Flags: FRIA + +The ``GSSAPIDelegateCredentials=yes`` option can either be set in the ``~/.ssh/config`` file or as a hostvar variable in the inventory: + +.. code-block:: yaml+jinja + + ansible_ssh_common_args: -o GSSAPIDelegateCredentials=yes + +Unlike the ``psrp`` or ``winrm`` connection plugins, the SSH connection plugin cannot get a Kerberos TGT ticket when provided with an explicit username and password. This means that the user must have a valid Kerberos ticket before running the playbook. + +See :ref:`windows_winrm_kerberos` for more information on how to configure, use, and troubleshoot Kerberos authentication. + +Password Authentication +""""""""""""""""""""""" + +Password authentication is the least secure method of authentication and is not recommended. However, it is possible to use password authentication with Windows SSH. To use password authentication with Ansible, set the ``ansible_password`` variable in the inventory file or in the playbook. Using password authentication requires the ``sshpass`` package to be installed on the Ansible control node. + +Password authentication works like WinRM CredSSP authentication where the username and password is given to the Windows host and it will perform unconstrained delegation to access network resources. diff --git a/docs/docsite/rst/os_guide/windows_usage.rst b/docs/docsite/rst/os_guide/windows_usage.rst index c37fcb218d9..10b6db9ca19 100644 --- a/docs/docsite/rst/os_guide/windows_usage.rst +++ b/docs/docsite/rst/os_guide/windows_usage.rst @@ -513,7 +513,5 @@ guides for Windows modules differ substantially from those for standard standard Tips and tricks for playbooks :ref:`List of Windows Modules ` Windows specific module list, all implemented in PowerShell - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/os_guide/windows_winrm.rst b/docs/docsite/rst/os_guide/windows_winrm.rst index 909955679fd..11d20be3f32 100644 --- a/docs/docsite/rst/os_guide/windows_winrm.rst +++ b/docs/docsite/rst/os_guide/windows_winrm.rst @@ -2,12 +2,12 @@ Windows Remote Management ========================= + Unlike Linux/Unix hosts, which use SSH by default, Windows hosts are configured with WinRM. This topic covers how to configure and use WinRM with Ansible. .. contents:: :local: - :depth: 2 What is WinRM? @@ -16,270 +16,300 @@ What is WinRM? WinRM is a management protocol used by Windows to remotely communicate with another server. It is a SOAP-based protocol that communicates over HTTP/HTTPS and is included in all recent Windows operating systems. Since Windows -Server 2012, WinRM has been enabled by default, but in most cases, extra +Server 2012, WinRM has been enabled by default, but in some cases, extra configuration is required to use WinRM with Ansible. -Ansible uses the `pywinrm `_ package to -communicate with Windows servers over WinRM. It is not installed by default -with the Ansible package. +Ansible can use WinRM through the :ref:`psrp ` or :ref:`winrm ` connection plugins. These plugins have their own Python requirements that are not included in the Ansible package and must be installed separately. -If you chose the ``pipx`` install instructions, you can install it by running the -following: +If you chose the ``pipx`` install instructions, you can install those requirements by running the following: .. code-block:: shell - pipx inject ansible pywinrm # if you installed ansible with pipx - pipx inject ansible-core pywinrm # if you installed ansible-core with pipx + pipx inject "pypsrp<=1.0.0" # for psrp + pipx inject "pywinrm>=0.4.0" # for winrm Or, if you chose the ``pip`` install instructions: .. code-block:: shell - pip install "pywinrm>=0.3.0" - -.. Note:: on distributions with multiple Python versions, use pip2 or pip2.x, - where x matches the Python minor version Ansible is running under. + pip3 install "pypsrp<=1.0.0" # for psrp + pip3 install "pywinrm>=0.4.0" # for winrm .. Warning:: - Using the ``winrm`` or ``psrp`` connection plugins in Ansible on MacOS in - the latest releases typically fails. This is a known problem that occurs - deep within the Python stack and cannot be changed by Ansible. The only - workaround today is to set the environment variable ``no_proxy=*`` and - avoid using Kerberos auth. + Using the ``winrm`` or ``psrp`` connection plugins in Ansible on MacOS in the latest releases typically fails. This is a known problem that occurs deep within the Python stack and cannot be changed by Ansible. The only workaround today is to set the environment variable ``OBJC_DISABLE_INITIALIZE_FORK_SAFETY=yes``, ``no_proxy=*`` and avoid using Kerberos auth. -.. _winrm_auth: +WinRM Setup +----------- -WinRM authentication options ------------------------------ +Before Ansible can connect using WinRM, the Windows host must have a WinRM listener configured. This listener will listen on the configured port and accept incoming WinRM requests. -When connecting to a Windows host, several different options can be used -when authenticating with an account. The authentication type may be set on inventory -hosts or groups with the ``ansible_winrm_transport`` variable. +While this guide covers more details on how to enumerate, add, and remove listeners, you can run the following PowerShell snippet to setup the HTTP listener with the defaults: -The following matrix is a high-level overview of the options: +.. code-block:: powershell -+-------------+----------------+---------------------------+-----------------------+-----------------+ -| Option | Local Accounts | Active Directory Accounts | Credential Delegation | HTTP Encryption | -+=============+================+===========================+=======================+=================+ -| Basic | Yes | No | No | No | -+-------------+----------------+---------------------------+-----------------------+-----------------+ -| Certificate | Yes | No | No | No | -+-------------+----------------+---------------------------+-----------------------+-----------------+ -| Kerberos | No | Yes | Yes | Yes | -+-------------+----------------+---------------------------+-----------------------+-----------------+ -| NTLM | Yes | Yes | No | Yes | -+-------------+----------------+---------------------------+-----------------------+-----------------+ -| CredSSP | Yes | Yes | Yes | Yes | -+-------------+----------------+---------------------------+-----------------------+-----------------+ + # Enables the WinRM service and sets up the HTTP listener + Enable-PSRemoting -Force + + # Opens port 5985 for all profiles + $firewallParams = @{ + Action = 'Allow' + Description = 'Inbound rule for Windows Remote Management via WS-Management. [TCP 5985]' + Direction = 'Inbound' + DisplayName = 'Windows Remote Management (HTTP-In)' + LocalPort = 5985 + Profile = 'Any' + Protocol = 'TCP' + } + New-NetFirewallRule @firewallParams + + # Allows local user accounts to be used with WinRM + # This can be ignored if using domain accounts + $tokenFilterParams = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' + Name = 'LocalAccountTokenFilterPolicy' + Value = 1 + PropertyType = 'DWORD' + Force = $true + } + New-ItemProperty @tokenFilterParams -.. _winrm_basic: +To also add a HTTPS listener with a self signed certificate we can run the following: -Basic -^^^^^^ +.. code-block:: powershell -Basic authentication is one of the simplest authentication options to use but is -also the most insecure. This is because the username and password are simply -base64 encoded, and if a secure channel is not in use (eg, HTTPS) then it can be -decoded by anyone. Basic authentication can only be used for local accounts (not domain accounts). + # Create self signed certificate + $certParams = @{ + CertStoreLocation = 'Cert:\LocalMachine\My' + DnsName = $env:COMPUTERNAME + NotAfter = (Get-Date).AddYears(1) + Provider = 'Microsoft Software Key Storage Provider' + Subject = "CN=$env:COMPUTERNAME" + } + $cert = New-SelfSignedCertificate @certParams + + # Create HTTPS listener + $httpsParams = @{ + ResourceURI = 'winrm/config/listener' + SelectorSet = @{ + Transport = "HTTPS" + Address = "*" + } + ValueSet = @{ + CertificateThumbprint = $cert.Thumbprint + Enabled = $true + } + } + New-WSManInstance @httpsParams + + # Opens port 5986 for all profiles + $firewallParams = @{ + Action = 'Allow' + Description = 'Inbound rule for Windows Remote Management via WS-Management. [TCP 5986]' + Direction = 'Inbound' + DisplayName = 'Windows Remote Management (HTTPS-In)' + LocalPort = 5986 + Profile = 'Any' + Protocol = 'TCP' + } + New-NetFirewallRule @firewallParams -The following example shows host vars configured for basic authentication: +.. warning:: + The above scripts are for demonstration purposes only and should be reviewed before running in a production environment. Some changes, like opening the firewall port for all incoming connections, allowing local accounts to be used with WinRM, self signed certificates, may not be suitable for all environments. -.. code-block:: yaml+jinja - ansible_user: LocalUsername - ansible_password: Password - ansible_connection: winrm - ansible_winrm_transport: basic +Enumerate Listeners +""""""""""""""""""" -Basic authentication is not enabled by default on a Windows host but can be -enabled by running the following in PowerShell: +To view the current listeners that are running on the WinRM service: .. code-block:: powershell - Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true - - -.. _winrm_certificate: - -Certificate -^^^^^^^^^^^^ - -Certificate authentication uses certificates as keys similar to SSH key -pairs, but the file format and key generation process is different. - -The following example shows host vars configured for certificate authentication: + winrm enumerate winrm/config/Listener -.. code-block:: yaml+jinja +This will output something like: - ansible_connection: winrm - ansible_winrm_cert_pem: /path/to/certificate/public/key.pem - ansible_winrm_cert_key_pem: /path/to/certificate/private/key.pem - ansible_winrm_transport: certificate +.. code-block:: powershell -Certificate authentication is not enabled by default on a Windows host but can -be enabled by running the following in PowerShell: + Listener + Address = * + Transport = HTTP + Port = 5985 + Hostname + Enabled = true + URLPrefix = wsman + CertificateThumbprint + ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80:: + ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7 + + Listener + Address = * + Transport = HTTPS + Port = 5986 + Hostname = SERVER2016 + Enabled = true + URLPrefix = wsman + CertificateThumbprint = E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE + ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80:: + ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7 + +In the example above there are two WinRM listeners configured. One is listening on port 5985 over HTTP and the other is listening on port 5986 over HTTPS. Some of the key options that are useful to understand are: + +* ``Transport``: Whether the listener is run over HTTP or HTTPS +* ``Port``: The port the to listen on, default for HTTP is ``5985`` and HTTPS is ``5986`` +* ``CertificateThumbprint``: For HTTPS, this is the thumbprint of the certificate used for the TLS connection + +To view the certificate details that is specified by the ``CertificateThumbprint`` you can run the following PowerShell command: .. code-block:: powershell - Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true - -.. Note:: Encrypted private keys cannot be used as the urllib3 library that - is used by Ansible for WinRM does not support this functionality. + $thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" + Get-Item -Path "Cert:\LocalMachine\My\$thumbprint" | Select-Object * -.. Note:: For enabling certificate authentication with a TLS 1.3 connection, Python 3.8+, 3.7.1, or 3.6.7 and Python packages urllib3==2.0.7 or newer are required. -.._winrm_certificate_generate: +Create Listener +""""""""""""""" -Generate a Certificate -++++++++++++++++++++++ +Creating a HTTP listener can be done through the ``Enable-PSRemoting`` cmdlet but you can also use the following PowerShell code to manually create the HTTP listener. -A certificate must be generated before it can be mapped to a local user. -This can be done using one of the following methods: +.. code-block:: powershell -* OpenSSL -* PowerShell, using the ``New-SelfSignedCertificate`` cmdlet -* Active Directory Certificate Services + $listenerParams = @{ + ResourceURI = 'winrm/config/listener' + SelectorSet = @{ + Transport = "HTTP" + Address = "*" + } + ValueSet = @{ + Enabled = $true + Port = 5985 + } + } + New-WSManInstance @listenerParams -Active Directory Certificate Services is beyond of scope in this documentation but may be -the best option to use when running in a domain environment. For more information, -see the `Active Directory Certificate Services documentation `_. +Creating a HTTPS listener is similar but the ``Port`` is now ``5985`` and the ``CertificateThumbprint`` value must be set. The certificate can either be a self signed certificate or a certificate from a certificate authority. How to generate a certificate is outside the scope of this section. -.. Note:: Using the PowerShell cmdlet ``New-SelfSignedCertificate`` to generate - a certificate for authentication only works when being generated from a - Windows 10 or Windows Server 2012 R2 host or later. OpenSSL is still required to - extract the private key from the PFX certificate to a PEM file for Ansible - to use. +.. code-block:: powershell -To generate a certificate with ``OpenSSL``: + $listenerParams = @{ + ResourceURI = 'winrm/config/listener' + SelectorSet = @{ + Transport = "HTTP" + Address = "*" + } + ValueSet = @{ + CertificateThumbprint = 'E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE' + Enabled = $true + Port = 5985 + } + } + New-WSManInstance @listenerParams -.. code-block:: shell +The ``CertificateThumbprint`` value must be set to the thumbprint of a certificate that is installed in the ``LocalMachine\My`` certificate store. - # Set the name of the local user that will have the key mapped to - USERNAME="username" +The ``Address`` selector value can be set to one of three values: - cat > openssl.conf << EOL - distinguished_name = req_distinguished_name - [req_distinguished_name] - [v3_req_client] - extendedKeyUsage = clientAuth - subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:$USERNAME@localhost - EOL +* ``*`` - binds to all addresses +* ``IP:...`` - binds to the IPv4 or IPv6 address specified by ``...`` +* ``MAC:32-a3-58-90-be-cc`` - binds to the adapter with the MAC address specified - export OPENSSL_CONF=openssl.conf - openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out cert.pem -outform PEM -keyout cert_key.pem -subj "/CN=$USERNAME" -extensions v3_req_client - rm openssl.conf +Remove Listener +""""""""""""""" -To generate a certificate with ``New-SelfSignedCertificate``: +The following code can remove all listeners or a specific one: .. code-block:: powershell - # Set the name of the local user that will have the key mapped - $username = "username" - $output_path = "C:\temp" + # Removes all listeners + Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force - # Instead of generating a file, the cert will be added to the personal - # LocalComputer folder in the certificate store - $cert = New-SelfSignedCertificate -Type Custom ` - -Subject "CN=$username" ` - -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2","2.5.29.17={text}upn=$username@localhost") ` - -KeyUsage DigitalSignature,KeyEncipherment ` - -KeyAlgorithm RSA ` - -KeyLength 2048 + # Removes only HTTP listeners + Get-ChildItem -Path WSMan:\localhost\Listener | + Where-Object Keys -contains "Transport=HTTP" | + Remove-Item -Recurse -Force - # Export the public key - $pem_output = @() - $pem_output += "-----BEGIN CERTIFICATE-----" - $pem_output += [System.Convert]::ToBase64String($cert.RawData) -replace ".{64}", "$&`n" - $pem_output += "-----END CERTIFICATE-----" - [System.IO.File]::WriteAllLines("$output_path\cert.pem", $pem_output) + # Removes only HTTPS listeners + Get-ChildItem -Path WSMan:\localhost\Listener | + Where-Object Keys -contains "Transport=HTTPS" | + Remove-Item -Recurse -Force - # Export the private key in a PFX file - [System.IO.File]::WriteAllBytes("$output_path\cert.pfx", $cert.Export("Pfx")) +WinRM Authentication +-------------------- -.. Note:: To convert the PFX file to a private key that pywinrm can use, run - the following command with OpenSSL - ``openssl pkcs12 -in cert.pfx -nocerts -nodes -out cert_key.pem -passin pass: -passout pass:`` +WinRM has several different authentication options that can be used to authenticate a user with a Windows host. Each option has their own advantages and disadvantages so it is important to understand when to use each one and when to not. -.. _winrm_certificate_import: +The following matrix is a high-level overview of the options: -Import a Certificate to the Certificate Store -+++++++++++++++++++++++++++++++++++++++++++++ ++-------------+----------------+---------------------------+-----------------------+-----------------+ +| Option | Local Accounts | Active Directory Accounts | Credential Delegation | HTTP Encryption | ++=============+================+===========================+=======================+=================+ +| Basic | Yes | No | No | No | ++-------------+----------------+---------------------------+-----------------------+-----------------+ +| Certificate | Yes | No | No | No | ++-------------+----------------+---------------------------+-----------------------+-----------------+ +| Kerberos | No | Yes | Yes | Yes | ++-------------+----------------+---------------------------+-----------------------+-----------------+ +| NTLM | Yes | Yes | No | Yes | ++-------------+----------------+---------------------------+-----------------------+-----------------+ +| CredSSP | Yes | Yes | Yes | Yes | ++-------------+----------------+---------------------------+-----------------------+-----------------+ -Once a certificate has been generated, the issuing certificate needs to be -imported into the ``Trusted Root Certificate Authorities`` of the -``LocalMachine`` store, and the client certificate public key must be present -in the ``Trusted People`` folder of the ``LocalMachine`` store. For this example, -both the issuing certificate and public key are the same. +The ``Basic`` and ``NTLM`` authentication options should not be used over a HTTP listener as they either offer no encryption or very weak encryption. The ``psrp`` connection plugin also offers the ``Negotiate`` authentication option which will attempt to use ``Kerberos`` before falling back to ``NTLM``. The ``winrm`` connection plugin must either specify ``kerberos`` or ``ntlm``. -Following example shows how to import the issuing certificate: +To specify the authentication protocol you can use the following variables: -.. code-block:: powershell +.. code-block:: yaml+jinja - $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 "cert.pem" + # For psrp + ansible_psrp_auth: basic|certificate|negotiate|kerberos|ntlm|credssp - $store_name = [System.Security.Cryptography.X509Certificates.StoreName]::Root - $store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine - $store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location - $store.Open("MaxAllowed") - $store.Add($cert) - $store.Close() + # For winrm + ansible_winrm_transport: basic|certificate|kerberos|ntlm|credssp +The recommendations for WinRM would be to use Kerberos auth over HTTP if in a domain environment or Basic/NTLM over HTTPS for local accounts. CredSSP should only be used when absolutely necessary as it can be a security risk due to its use of unconstrained delegation. -.. Note:: If using ADCS to generate the certificate, then the issuing - certificate will already be imported and this step can be skipped. -The code to import the client certificate public key is: +Basic +""""" -.. code-block:: powershell +Basic authentication is one of the simplest authentication options to use but is +also the most insecure. This is because the username and password are simply +base64 encoded, and if a secure channel is not in use (eg, HTTPS) then it can be +decoded by anyone. Basic authentication can only be used for local accounts (not domain accounts). - $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 "cert.pem" +The following example shows host vars configured for basic authentication: - $store_name = [System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople - $store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine - $store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location - $store.Open("MaxAllowed") - $store.Add($cert) - $store.Close() +.. code-block:: yaml+jinja + ansible_user: LocalUsername + ansible_password: Password -.. _winrm_certificate_mapping: + # psrp + ansible_connection: psrp + ansible_psrp_auth: basic -Mapping a Certificate to an Account -+++++++++++++++++++++++++++++++++++ + # winrm + ansible_connection: winrm + ansible_winrm_transport: basic -Once the certificate has been imported, map it to the local user account: +Basic authentication is not enabled by default on a Windows host but can be +enabled by running the following in PowerShell: .. code-block:: powershell - $username = "username" - $password = ConvertTo-SecureString -String "password" -AsPlainText -Force - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password - - # This is the issuer thumbprint which in the case of a self generated cert - # is the public key thumbprint, additional logic may be required for other - # scenarios - $thumbprint = (Get-ChildItem -Path cert:\LocalMachine\root | Where-Object { $_.Subject -eq "CN=$username" }).Thumbprint - - New-Item -Path WSMan:\localhost\ClientCertificate ` - -Subject "$username@localhost" ` - -URI * ` - -Issuer $thumbprint ` - -Credential $credential ` - -Force + Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true -Once this is complete, the hostvar ``ansible_winrm_cert_pem`` should be set to -the path of the public key and the ``ansible_winrm_cert_key_pem`` variable should be set to -the path of the private key. +Certificate +""""""""""" +See :ref:`windows_winrm_certificate` for more information on how to configure and use certificate authentication. -.. _winrm_ntlm: NTLM -^^^^^ +"""" NTLM is an older authentication mechanism used by Microsoft that can support both local and domain accounts. NTLM is enabled by default on the WinRM @@ -303,21 +333,25 @@ This example shows host variables configured to use NTLM authentication: ansible_user: LocalUsername ansible_password: Password + + # psrp + ansible_connection: psrp + ansible_psrp_auth: negotiate # or ntlm to only use NTLM + + # winrm ansible_connection: winrm ansible_winrm_transport: ntlm -.. _winrm_kerberos: -Kerberos -^^^^^^^^^ +Kerberos and Negotiate +"""""""""""""""""""""" Kerberos is the recommended authentication option to use when running in a domain environment. Kerberos supports features like credential delegation and message encryption over HTTP and is one of the more secure options that is available through WinRM. -Kerberos requires some additional setup work on the Ansible host before it can be -used properly. +Kerberos does require some additional setup work on the Ansible host before it can be used properly. See :ref:`windows_winrm_kerberos` for more information on how to configure, use, and troubleshoot Kerberos authentication. The following example shows host vars configured for Kerberos authentication: @@ -325,219 +359,18 @@ The following example shows host vars configured for Kerberos authentication: ansible_user: username@MY.DOMAIN.COM ansible_password: Password - ansible_connection: winrm - ansible_port: 5985 - ansible_winrm_transport: kerberos - -As of Ansible version 2.3, the Kerberos ticket will be created based on -``ansible_user`` and ``ansible_password``. If running on an older version of -Ansible or when ``ansible_winrm_kinit_mode`` is ``manual``, a Kerberos -ticket must already be obtained. See below for more details. - -Some extra host variables can be set: - -.. code-block:: yaml - - ansible_winrm_kinit_mode: managed/manual (manual means Ansible will not obtain a ticket) - ansible_winrm_kinit_cmd: the kinit binary to use to obtain a Kerberos ticket (default to kinit) - ansible_winrm_service: overrides the SPN prefix that is used, the default is ``HTTP`` and should rarely ever need changing - ansible_winrm_kerberos_delegation: allows the credentials to traverse multiple hops - ansible_winrm_kerberos_hostname_override: the hostname to be used for the Kerberos exchange - -.. _winrm_kerberos_install: - -Installing the Kerberos Library -+++++++++++++++++++++++++++++++ - -Some system dependencies must be installed before using Kerberos. The script below lists the dependencies based on the distro: - -.. code-block:: shell - - # Through Yum (RHEL/Centos/Fedora for the older version) - yum -y install gcc python-devel krb5-devel krb5-libs krb5-workstation - - # Through DNF (RHEL/Centos/Fedora for the newer version) - dnf -y install gcc python3-devel krb5-devel krb5-libs krb5-workstation - - # Through Apt (Ubuntu older than 20.04 LTS (focal)) - sudo apt-get install python-dev libkrb5-dev krb5-user - - # Through Apt (Ubuntu newer than 20.04 LTS) - sudo apt-get install python3-dev libkrb5-dev krb5-user - - # Through Portage (Gentoo) - emerge -av app-crypt/mit-krb5 - emerge -av dev-python/setuptools - - # Through Pkg (FreeBSD) - sudo pkg install security/krb5 - - # Through OpenCSW (Solaris) - pkgadd -d http://get.opencsw.org/now - /opt/csw/bin/pkgutil -U - /opt/csw/bin/pkgutil -y -i libkrb5_3 - - # Through Pacman (Arch Linux) - pacman -S krb5 - - -Once the dependencies have been installed, the ``python-kerberos`` wrapper can -be installed. - -If you chose the ``pipx`` install instructions, you can install it by running -the following: - -.. code-block:: shell - - pipx inject ansible pywinrm[kerberos] # if you installed ansible with pipx - pipx inject ansible-core pywinrm[kerberos] # if you installed ansible-core with pipx - -Or, if you chose the ``pip`` install instructions: - -.. code-block:: shell - - pip install pywinrm[kerberos] - - -.. note:: - While Ansible has supported Kerberos auth through ``pywinrm`` for some - time, optional features or more secure options may only be available in - newer versions of the ``pywinrm`` and/or ``pykerberos`` libraries. It is - recommended you upgrade each version to the latest available to resolve - any warnings or errors. This can be done through tools like ``pip`` or a - system package manager like ``dnf``, ``yum``, ``apt`` but the package - names and versions available may differ between tools. - - -.. _winrm_kerberos_config: - -Configuring Host Kerberos -+++++++++++++++++++++++++ - -Once the dependencies have been installed, Kerberos needs to be configured so -that it can communicate with a domain. This configuration is done through the -``/etc/krb5.conf`` file, which is installed with the packages in the script above. - -To configure Kerberos, in the section that starts with: - -.. code-block:: ini - - [realms] - -Add the full domain name and the fully qualified domain names of the primary -and secondary Active Directory domain controllers. It should look something -like this: - -.. code-block:: ini - - [realms] - MY.DOMAIN.COM = { - kdc = domain-controller1.my.domain.com - kdc = domain-controller2.my.domain.com - } - -In the section that starts with: - -.. code-block:: ini - - [domain_realm] - -Add a line like the following for each domain that Ansible needs access for: - -.. code-block:: ini - - [domain_realm] - .my.domain.com = MY.DOMAIN.COM -You can configure other settings in this file such as the default domain. See -`krb5.conf `_ -for more details. + # psrp + ansible_connection: psrp + ansible_psrp_auth: negotiate # or kerberos to disable ntlm fallback -.. _winrm_kerberos_ticket_auto: - -Automatic Kerberos Ticket Management -++++++++++++++++++++++++++++++++++++ - -Ansible version 2.3 and later defaults to automatically managing Kerberos tickets -when both ``ansible_user`` and ``ansible_password`` are specified for a host. In -this process, a new ticket is created in a temporary credential cache for each -host. This is done before each task executes to minimize the chance of ticket -expiration. The temporary credential caches are deleted after each task -is completed and will not interfere with the default credential cache. - -To disable automatic ticket management, set ``ansible_winrm_kinit_mode=manual`` -through the inventory. - -Automatic ticket management requires a standard ``kinit`` binary on the control -host system path. To specify a different location or binary name, set the -``ansible_winrm_kinit_cmd`` hostvar to the fully qualified path to a MIT krbv5 -``kinit``-compatible binary. - -.. _winrm_kerberos_ticket_manual: - -Manual Kerberos Ticket Management -+++++++++++++++++++++++++++++++++ - -To manually manage Kerberos tickets, the ``kinit`` binary is used. To -obtain a new ticket the following command is used: - -.. code-block:: shell - - kinit username@MY.DOMAIN.COM - -.. Note:: The domain must match the configured Kerberos realm exactly, and must be in upper case. - -To see what tickets (if any) have been acquired, use the following command: - -.. code-block:: shell - - klist - -To destroy all the tickets that have been acquired, use the following command: - -.. code-block:: shell - - kdestroy - -.. _winrm_kerberos_troubleshoot: - -Troubleshooting Kerberos -++++++++++++++++++++++++ - -Kerberos is reliant on a properly configured environment to -work. To troubleshoot Kerberos issues, ensure that: - -* The hostname set for the Windows host is the FQDN and not an IP address. - * If you connect using an IP address you will get the error message `Server not found in Kerberos database`. - * To determine if you are connecting using an IP address or an FQDN run your playbook (or call the ``win_ping`` module) using the `-vvv` flag. - -* The forward and reverse DNS lookups are working properly in the domain. To - test this, ping the Windows host by name and then use the IP address returned - with ``nslookup``. The same name should be returned when using ``nslookup`` - on the IP address. - -* The Ansible host's clock is synchronized with the AD domain controller. Kerberos - is time-sensitive, and a little clock drift can cause the ticket generation - process to fail. - -* Ensure that the fully qualified domain name for the domain is configured in - the ``krb5.conf`` file. To check this, run: - - .. code-block:: console - - kinit -C username@MY.DOMAIN.COM - klist - - If the domain name returned by ``klist`` is different from the one requested, - an alias is being used. The ``krb5.conf`` file needs to be updated so that - the fully qualified domain name is used and not an alias. - -* If the default Kerberos tooling has been replaced or modified (some IdM solutions may do this), this may cause issues when installing or upgrading the Python Kerberos library. As of the time of this writing, this library is called ``pykerberos`` and is known to work with both MIT and Heimdal Kerberos libraries. To resolve ``pykerberos`` installation issues, ensure the system dependencies for Kerberos have been met (see: `Installing the Kerberos Library`_), remove any custom Kerberos tooling paths from the PATH environment variable, and retry the installation of Python Kerberos library package. + # winrm + ansible_connection: winrm + ansible_winrm_transport: kerberos -.. _winrm_credssp: CredSSP -^^^^^^^ +""""""" CredSSP authentication is a newer authentication protocol that allows credential delegation. This is achieved by encrypting the username and password @@ -557,14 +390,14 @@ To use CredSSP authentication, the host vars are configured like so: ansible_user: Username ansible_password: Password - ansible_connection: winrm - ansible_winrm_transport: credssp - -Some extra host variables that can be set as shown below: -.. code-block:: yaml + # psrp + ansible_connection: psrp + ansible_psrp_auth: credssp - ansible_winrm_credssp_disable_tlsv1_2: when true, will not use TLS 1.2 in the CredSSP auth process + # winrm + ansible_connection: winrm + ansible_winrm_transport: credssp CredSSP authentication is not enabled by default on a Windows host, but can be enabled by running the following in PowerShell: @@ -573,62 +406,31 @@ be enabled by running the following in PowerShell: Enable-WSManCredSSP -Role Server -Force -.. _winrm_credssp_install: +CredSSP requires optional Python libraries to be installed and can be done with pipx: -Installing CredSSP Library -++++++++++++++++++++++++++ - -The ``requests-credssp`` wrapper can be installed using ``pip``: - -.. code-block:: bash - - pip install pywinrm[credssp] - -.. _winrm_credssp_tls: - -CredSSP and TLS 1.2 -+++++++++++++++++++ - -By default, the ``requests-credssp`` library is configured to authenticate over -the TLS 1.2 protocol. TLS 1.2 is installed and enabled by default for Windows Server 2012 -and Windows 8 and more recent releases. - -There are two ways that older hosts can be used with CredSSP: - -* Install and enable a hotfix to enable TLS 1.2 support (recommended - for Server 2008 R2 and Windows 7). - -* Set ``ansible_winrm_credssp_disable_tlsv1_2=True`` in the inventory to run - over TLS 1.0. This is the only option when connecting to Windows Server 2008, which - has no way of supporting TLS 1.2 - -See :ref:`winrm_tls12` for more information on how to enable TLS 1.2 on the -Windows host. +.. code-block:: shell -.. _winrm _credssp_cert: + pipx inject "pypsrp[credssp]<=1.0.0" # for psrp + pipx inject "pywinrm[credssp]>=0.4.0" # for winrm -Set CredSSP Certificate -+++++++++++++++++++++++ +Or, if you chose the ``pip`` install instructions: -CredSSP works by encrypting the credentials through the TLS protocol and uses a self-signed certificate by default. The ``CertificateThumbprint`` option under the WinRM service configuration can be used to specify the thumbprint of -another certificate. +.. code-block:: shell -.. Note:: This certificate configuration is independent of the WinRM listener - certificate. With CredSSP, message transport still occurs over the WinRM listener, - but the TLS-encrypted messages inside the channel use the service-level certificate. + pip3 install "pypsrp[credssp]<=1.0.0" # for psrp + pip3 install "pywinrm[credssp]>=0.4.0" # for winrm -To explicitly set the certificate to use for CredSSP: +CredSSP works by using a TLS connection to wrap the authentication tokens and subsequent messages sent over the connection. By default it will use a self-signed certificate automatically generated by Windows. While using CredSSP over a HTTPS connection will still need to validate the HTTPS certificate used by the WinRM listener, there is no validation done on the CredSSP certificate. It is possible to configure CredSSP to use a different certificate by setting the ``CertificateThumbprint`` option under the WinRM service configuration. .. code-block:: powershell - # Note the value $certificate_thumbprint will be different in each - # situation, this needs to be set based on the cert that is used. - $certificate_thumbprint = "7C8DCBD5427AFEE6560F4AF524E325915F51172C" + # Note the value $thumprint will be different in each situation, this needs + # to be set based on the cert that is used. + $thumbprint = "7C8DCBD5427AFEE6560F4AF524E325915F51172C" # Set the thumbprint value - Set-Item -Path WSMan:\localhost\Service\CertificateThumbprint -Value $certificate_thumbprint + Set-Item -Path WSMan:\localhost\Service\CertificateThumbprint -Value $thumbprint -.. _winrm_nonadmin: Non-Administrator Accounts --------------------------- @@ -647,7 +449,6 @@ enabled. While non-administrative accounts can be used with WinRM, most typical server administration tasks require some level of administrative access, so the utility is usually limited. -.. _winrm_encrypt: WinRM Encryption ----------------- @@ -666,8 +467,15 @@ option is ``NTLM``, ``Kerberos`` or ``CredSSP``. These protocols will encrypt the WinRM payload with their own encryption method before sending it to the server. The message-level encryption is not used when running over HTTPS because the encryption uses the more secure TLS protocol instead. If both transport and -message encryption is required, set ``ansible_winrm_message_encryption=always`` -in the host vars. +message encryption is required, the following hostvars can be set: + +.. code-block:: yaml+jinja + + # psrp + ansible_psrp_message_encryption: always + + # winrm + ansible_winrm_message_encryption: always .. Note:: Message encryption over HTTP requires pywinrm>=0.3.0. @@ -685,146 +493,16 @@ requirement: absolutely required. Doing so could allow sensitive information like credentials and files to be intercepted by others on the network. -.. _winrm_inventory: - -Inventory Options ------------------- - -Ansible's Windows support relies on a few standard variables to indicate the -username, password, and connection type of the remote hosts. These variables -are most easily set up in the inventory, but can be set on the ``host_vars``/ -``group_vars`` level. - -When setting up the inventory, the following variables are required: - -.. code-block:: yaml+jinja - - # It is suggested that these be encrypted with ansible-vault: - # ansible-vault edit group_vars/windows.yml - ansible_connection: winrm - - # May also be passed on the command-line through --user - ansible_user: Administrator - - # May also be supplied at runtime with --ask-pass - ansible_password: SecretPasswordGoesHere - - -Using the variables above, Ansible will connect to the Windows host with Basic -authentication through HTTPS. If ``ansible_user`` has a UPN value like -``username@MY.DOMAIN.COM`` then the authentication option will automatically attempt -to use Kerberos unless ``ansible_winrm_transport`` has been set to something other than -``kerberos``. - -The following custom inventory variables are also supported -for additional configuration of WinRM connections: - -* ``ansible_port``: The port WinRM will run over, HTTPS is ``5986`` which is - the default while HTTP is ``5985`` - -* ``ansible_winrm_scheme``: Specify the connection scheme (``http`` or - ``https``) to use for the WinRM connection. Ansible uses ``https`` by default - unless ``ansible_port`` is ``5985`` - -* ``ansible_winrm_path``: Specify an alternate path to the WinRM endpoint, - Ansible uses ``/wsman`` by default - -* ``ansible_winrm_realm``: Specify the realm to use for Kerberos - authentication. If ``ansible_user`` contains ``@``, Ansible will use the part - of the username after ``@`` by default - -* ``ansible_winrm_transport``: Specify one or more authentication transport - options as a comma-separated list. By default, Ansible will use ``kerberos, - basic`` if the ``kerberos`` module is installed and a realm is defined, - otherwise, it will be ``plaintext`` -* ``ansible_winrm_server_cert_validation``: Specify the server certificate - validation mode (``ignore`` or ``validate``). Ansible defaults to - ``validate`` on Python 2.7.9 and higher, which will result in certificate - validation errors against the Windows self-signed certificates. Unless - verifiable certificates have been configured on the WinRM listeners, this - should be set to ``ignore`` - -* ``ansible_winrm_operation_timeout_sec``: Increase the default timeout for - WinRM operations, Ansible uses ``20`` by default - -* ``ansible_winrm_read_timeout_sec``: Increase the WinRM read timeout, Ansible - uses ``30`` by default. Useful if there are intermittent network issues and - read timeout errors keep occurring - -* ``ansible_winrm_message_encryption``: Specify the message encryption - operation (``auto``, ``always``, ``never``) to use, Ansible uses ``auto`` by - default. ``auto`` means message encryption is only used when - ``ansible_winrm_scheme`` is ``http`` and ``ansible_winrm_transport`` supports - message encryption. ``always`` means message encryption will always be used - and ``never`` means message encryption will never be used - -* ``ansible_winrm_ca_trust_path``: Used to specify a different cacert container - than the one used in the ``certifi`` module. See the HTTPS Certificate - Validation section for more details. - -* ``ansible_winrm_send_cbt``: When using ``ntlm`` or ``kerberos`` over HTTPS, - the authentication library will try to send channel binding tokens to - mitigate against man-in-the-middle attacks. This flag controls whether these - bindings will be sent or not (default: ``true``). - -* ``ansible_winrm_*``: Any additional keyword arguments supported by - ``winrm.Protocol`` may be provided in place of ``*`` - -In addition, there are also specific variables that need to be set -for each authentication option. See the section on authentication above for more information. - -.. Note:: Ansible 2.0 has deprecated the "ssh" from ``ansible_ssh_user``, - ``ansible_ssh_pass``, ``ansible_ssh_host``, and ``ansible_ssh_port`` to - become ``ansible_user``, ``ansible_password``, ``ansible_host``, and - ``ansible_port``. If using a version of Ansible prior to 2.0, the older - style (``ansible_ssh_*``) should be used instead. The shorter variables - are ignored, without warning, in older versions of Ansible. - -.. Note:: ``ansible_winrm_message_encryption`` is different from transport - encryption done over TLS. The WinRM payload is still encrypted with TLS - when run over HTTPS, even if ``ansible_winrm_message_encryption=never``. - -.. _winrm_ipv6: - -IPv6 Addresses ---------------- - -IPv6 addresses can be used instead of IPv4 addresses or hostnames. This option -is normally set in an inventory. Ansible will attempt to parse the address -using the `ipaddress `_ -package and pass to ``pywinrm`` correctly. - -When defining a host using an IPv6 address, just add the IPv6 address as you -would an IPv4 address or hostname: - -.. code-block:: ini - - [windows-server] - 2001:db8::1 - - [windows-server:vars] - ansible_user=username - ansible_password=password - ansible_connection=winrm - - -.. Note:: The ipaddress library is only included by default in Python 3.x. To - use IPv6 addresses in Python 2.7, make sure to run ``pip install ipaddress`` which installs - a backported package. - -.. _winrm_https: +.. _windows_winrm_cert_validation: HTTPS Certificate Validation ----------------------------- -As part of the TLS protocol, the certificate is validated to ensure the host -matches the subject and the client trusts the issuer of the server certificate. -When using a self-signed certificate or setting -``ansible_winrm_server_cert_validation: ignore`` these security mechanisms are -bypassed. While self-signed certificates will always need the ``ignore`` flag, -certificates that have been issued from a certificate authority can still be -validated. +As part of the TLS protocol, the certificate is validated to ensure the host matches the subject and the client trusts the issuer of the server certificate. If using a self-signed certificate, the certificate will not be trusted by the client and the connection will fail. To bypass this, set the following hostvars depending on the connection plugin used: + +* ``ansible_psrp_cert_validation: ignore`` +* ``ansible_winrm_server_cert_validation: ignore`` One of the more common ways of setting up an HTTPS listener in a domain environment is to use Active Directory Certificate Service (AD CS). AD CS is @@ -838,152 +516,13 @@ certificate of the CA can be exported as a PEM-encoded certificate. This certificate can then be copied locally to the Ansible control node and used as a source of certificate validation, otherwise known as a CA chain. -The CA chain can contain a single or multiple issuer certificates and each -entry is contained on a new line. To then use the custom CA chain as part of -the validation process, set ``ansible_winrm_ca_trust_path`` to the path of the -file. If this variable is not set, the default CA chain is used instead which -is located in the install path of the Python package -`certifi `_. - -.. Note:: Each HTTP call is done by the Python requests library which does not - use the systems built-in certificate store as a trust authority. - Certificate validation will fail if the server's certificate issuer is - only added to the system's truststore. - -.. _winrm_tls12: - -TLS 1.2 Support ----------------- - -As WinRM runs over the HTTP protocol, using HTTPS means that the TLS protocol -is used to encrypt the WinRM messages. TLS will automatically attempt to -negotiate the best protocol and cipher suite that is available to both the -client and the server. If a match cannot be found then Ansible will error out -with a message similar to: - -.. code-block:: ansible-output - - HTTPSConnectionPool(host='server', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1056)'))) - -Commonly this is when the Windows host has not been configured to support -TLS v1.2 but it could also mean the Ansible control node has an older OpenSSL -version installed. - -Windows 8 and Windows Server 2012 come with TLS v1.2 installed and enabled by -default but older hosts, like Server 2008 R2 and Windows 7, have to be enabled -manually. - -.. Note:: There is a bug with the TLS 1.2 patch for Server 2008 which will stop - Ansible from connecting to the Windows host. This means that Server 2008 - cannot be configured to use TLS 1.2. Server 2008 R2 and Windows 7 are not - affected by this issue and can use TLS 1.2. - -To verify what protocol the Windows host supports, you can run the following -command on the Ansible control node: - -.. code-block:: shell - - openssl s_client -connect :5986 - -The output will contain information about the TLS session and the ``Protocol`` -line will display the version that was negotiated: - -.. code-block:: console - - New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA - Server public key is 2048 bit - Secure Renegotiation IS supported - Compression: NONE - Expansion: NONE - No ALPN negotiated - SSL-Session: - Protocol : TLSv1 - Cipher : ECDHE-RSA-AES256-SHA - Session-ID: 962A00001C95D2A601BE1CCFA7831B85A7EEE897AECDBF3D9ECD4A3BE4F6AC9B - Session-ID-ctx: - Master-Key: .... - Start Time: 1552976474 - Timeout : 7200 (sec) - Verify return code: 21 (unable to verify the first certificate) - --- - - New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 - Server public key is 2048 bit - Secure Renegotiation IS supported - Compression: NONE - Expansion: NONE - No ALPN negotiated - SSL-Session: - Protocol : TLSv1.2 - Cipher : ECDHE-RSA-AES256-GCM-SHA384 - Session-ID: AE16000050DA9FD44D03BB8839B64449805D9E43DBD670346D3D9E05D1AEEA84 - Session-ID-ctx: - Master-Key: .... - Start Time: 1552976538 - Timeout : 7200 (sec) - Verify return code: 21 (unable to verify the first certificate) - -If the host is returning ``TLSv1`` then it should be configured so that -TLS v1.2 is enable. You can do this by running the following PowerShell -script: - -.. code-block:: powershell - - Function Enable-TLS12 { - param( - [ValidateSet("Server", "Client")] - [String]$Component = "Server" - ) - - $protocols_path = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols' - New-Item -Path "$protocols_path\TLS 1.2\$Component" -Force - New-ItemProperty -Path "$protocols_path\TLS 1.2\$Component" -Name Enabled -Value 1 -Type DWORD -Force - New-ItemProperty -Path "$protocols_path\TLS 1.2\$Component" -Name DisabledByDefault -Value 0 -Type DWORD -Force - } +The CA chain can contain a single or multiple issuer certificates and each entry is contained on a new line. To then use the custom CA chain as part of the validation process, set the following hostvar depending on the connection plugin used to the path of the CA PEM formatted file: - Enable-TLS12 -Component Server +* ``ansible_psrp_ca_cert`` +* ``ansible_winrm_ca_trust_path`` - # Not required but highly recommended to enable the Client side TLS 1.2 components - Enable-TLS12 -Component Client +If this variable is not set, the default CA chain is used instead which is located in the install path of the Python package `certifi `_. Some Linux distributions may have configured the underlying Python ``requests`` library that the ``psrp`` and ``winrm`` connection plugins use to use the system's certificate store rather than ``certifi``. If this is the case, the CA chain will be the same as the system's certificate store. - Restart-Computer - -The below Ansible tasks can also be used to enable TLS v1.2: - -.. code-block:: yaml+jinja - - - name: enable TLSv1.2 support - win_regedit: - path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\{{ item.type }} - name: '{{ item.property }}' - data: '{{ item.value }}' - type: dword - state: present - register: enable_tls12 - loop: - - type: Server - property: Enabled - value: 1 - - type: Server - property: DisabledByDefault - value: 0 - - type: Client - property: Enabled - value: 1 - - type: Client - property: DisabledByDefault - value: 0 - - - name: reboot if TLS config was applied - win_reboot: - when: enable_tls12 is changed - -There are other ways to configure the TLS protocols as well as the cipher -suites that are offered by the Windows host. One tool that can give you a GUI -to manage these settings is `IIS Crypto `_ -from Nartac Software. - -.. _winrm_limitations: WinRM limitations ------------------ @@ -1008,9 +547,7 @@ These include: Some of these limitations can be mitigated by doing one of the following: -* Set ``ansible_winrm_transport`` to ``credssp`` or ``kerberos`` (with - ``ansible_winrm_kerberos_delegation=true``) to bypass the double-hop issue - and access network resources +* Set the authentication method to use ``credssp`` or ``kerberos`` with credential delegation enabled * Use ``become`` to bypass all WinRM restrictions and run a command as it would locally. Unlike using an authentication transport like ``credssp``, this will @@ -1022,6 +559,67 @@ Some of these limitations can be mitigated by doing one of the following: restrictions but can only run a command and not modules. +WinRM Troubleshooting +--------------------- +WinRM has a wide range of configuration options, which makes its configuration complex. As a result, errors that Ansible displays could in fact be problems with the host setup instead. + +To identify a host issue, run the following command from another Windows host to test out a connection to the target Windows host. + +* To test HTTP: + +.. code-block:: powershell + + # winrm + winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig + + # psrp + Invoke-Command -ComputerName server { ipconfig } -Credential username + +* To test HTTPS: + +.. code-block:: powershell + + # winrm + winrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfig + + # psrp + Invoke-Command -UseSSL -ComputerName server { ipconfig } -Credential username + + # psrp ignoring certs + $sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck + Invoke-Command -UseSSL -ComputerName server { ipconfig } -Credential username -SessionOption $sessionOption + +To verify that the target hostname is resolvable on the Ansible control node, run one of the following commands: + +.. code-block:: bash + + dig +search server + + # May fail if the Windows firewall is set to block ICMP pings + # but will show the hostname if resolvable. + ping server + +To verify that the WinRM service is listening and a firewall is not blocking the connection you can use ``nc`` to test the connection over the WinRM port: + +.. code-block:: bash + + # HTTP port + > nc -zv server 5985 + Connection to server port 5985 [tcp/wsman] succeeded! + + # HTTPS port + > nc -zv server 5986 + Connection to server port 5986 [tcp/wsmans] succeeded! + +To verify that WinRM has a HTTPS listener and is working you can use ``openssl s_client`` to test the connection and view the certificate details with: + +.. code-block:: bash + + echo '' | openssl s_client -connect server:5986 + +.. note:: + The ``openssl s_client`` command will use the system trust store to validate the certificate which may not align with the trust store used in Ansible. See :ref:`windows_winrm_cert_validation` for more information. + .. seealso:: :ref:`playbooks_intro` @@ -1030,7 +628,5 @@ Some of these limitations can be mitigated by doing one of the following: Tips and tricks for playbooks :ref:`List of Windows Modules ` Windows-specific module list, all implemented in PowerShell - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/os_guide/windows_winrm_certificate.rst b/docs/docsite/rst/os_guide/windows_winrm_certificate.rst new file mode 100644 index 00000000000..080202c1fa8 --- /dev/null +++ b/docs/docsite/rst/os_guide/windows_winrm_certificate.rst @@ -0,0 +1,212 @@ +.. _windows_winrm_certificate: + +WinRM Certificate Authentication +================================ + +WinRM certificate authentication is a method of authenticating to a Windows host using X.509 certificates instead of a username and password. + +.. contents:: + :local: + +Certificate authentication does have some disadvantages compared to SSH key based authentication such as: + +* it can only be mapped to a local Windows user, no domain accounts +* the username and password must be mapped to the certificate, if the password changes, the cert will need to be re-mapped +* an administrator on the Windows host can retrieve the local user password through the certificate mapping +* Ansible cannot use encrypted private keys, they must be stored without encryption +* Ansible cannot use the certs and private keys stored as a var, they must be a file + + +Ansible Configuration +--------------------- + +Certificate authentication uses certificates as keys similar to SSH key pairs. The public and private key is stored on the Ansible control node to use for authentication. The following example shows the hostvars configured for certificate authentication: + +.. code-block:: yaml+jinja + + # psrp + ansible_connection: psrp + ansible_psrp_auth: certificate + ansible_psrp_certificate_pem: /path/to/certificate/public_key.pem + ansible_psrp_certificate_key_pem: /path/to/certificate/private_key.pem + + # winrm + ansible_connection: winrm + ansible_winrm_transport: certificate + ansible_winrm_cert_pem: /path/to/certificate/public_key.pem + ansible_winrm_cert_key_pem: /path/to/certificate/private_key.pem + +Certificate authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell: + +.. code-block:: powershell + + Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true + +The private key cannot be encrypted due to a limitation of the underlying Python library used by Ansible. + +.. note:: + For enabling certificate authentication with a TLS 1.3 connection, Python 3.8+, 3.7.1, or 3.6.7 and Python package urllib3>=2.0.7 or newer are required. + + +Certificate Generation +---------------------- + +The first step of using certificate authentication is to generate a certificate and private key. The certificate must be generated with the following properties: + +* ``Extended Key Usage`` must include ``clientAuth (1.3.6.1.5.5.7.3.2)`` +* ``Subject Alternative Name`` must include ``otherName`` entry for ``userPrincipalName (1.3.6.1.4.1.311.20.2.3)`` + +The ``userPrincipalName`` value can be anything but in this guide we will use the value ``$USERNAME@localhost`` where ``$USERNAME`` is the name of the user that the certificate will be mapped to. + +This can be done through a variety of methods, such as OpenSSL, PowerShell, or Active Directory Certificate Services. The following example shows how to generate a certificate using OpenSSL: + +.. code-block:: bash + + # Set the username to the name of the user the certificate will be mapped to + USERNAME="local-user" + + cat > openssl.conf << EOL + distinguished_name = req_distinguished_name + + [req_distinguished_name] + [v3_req_client] + extendedKeyUsage = clientAuth + subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:${USERNAME}@localhost + EOL + + openssl req \ + -new \ + -sha256 \ + -subj "/CN=${USERNAME}" \ + -newkey rsa:2048 \ + -nodes \ + -keyout cert.key \ + -out cert.csr \ + -config openssl.conf \ + -reqexts v3_req_client + + openssl x509 \ + -req \ + -in cert.csr \ + -sha256 \ + -out cert.pem \ + -days 365 \ + -extfile openssl.conf \ + -extensions v3_req_client \ + -key cert.key + + rm openssl.conf cert.csr + +The following example shows how to generate a certificate using PowerShell: + +.. code-block:: powershell + + # Set the username to the name of the user the certificate will be mapped to + $username = 'local-user' + + $clientParams = @{ + CertStoreLocation = 'Cert:\CurrentUser\My' + NotAfter = (Get-Date).AddYears(1) + Provider = 'Microsoft Software Key Storage Provider' + Subject = "CN=$username" + TextExtension = @("2.5.29.37={text}1.3.6.1.5.5.7.3.2","2.5.29.17={text}upn=$username@localhost") + Type = 'Custom' + } + $cert = New-SelfSignedCertificate @clientParams + $certKeyName = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey( + $cert).Key.UniqueName + + # Exports the public cert.pem and key cert.pfx + Set-Content -Path "cert.pem" -Value @( + "-----BEGIN CERTIFICATE-----" + [Convert]::ToBase64String($cert.RawData) -replace ".{64}", "$&`n" + "-----END CERTIFICATE-----" + ) + $certPfxBytes = $cert.Export('Pfx', '') + [System.IO.File]::WriteAllBytes("$pwd\cert.pfx", $certPfxBytes) + + # Removes the private key and cert from the store after exporting + $keyPath = [System.IO.Path]::Combine($env:AppData, 'Microsoft', 'Crypto', 'Keys', $certKeyName) + Remove-Item -LiteralPath "Cert:\CurrentUser\My\$($cert.Thumbprint)" -Force + Remove-Item -LiteralPath $keyPath -Force + +As PowerShell cannot generate a PKCS8 PEM private key, we need to use OpenSSL to convert the ``cert.pfx`` file to a PEM private key: + +.. code-block:: bash + + openssl pkcs12 \ + -in cert.pfx \ + -nocerts \ + -nodes \ + -passin pass: | + sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' > cert.key + +The ``cert.pem`` is the public key and the ``cert.key`` is the plaintext private key. These files must be accessible by the Ansible control node to use for authentication. The private key does not need to be present on the Windows node. + + +Windows Configuration +--------------------- + +Once the public and private key has been generated we need to import and trust the public key and configure the user mapping on the Windows host. +The Windows host does not need access to the private key, only the public key ``cert.pem`` needs to be accessible to configure the certificate authentication. + + +Import Certificate to the Certificate Store +""""""""""""""""""""""""""""""""""""""""""" + +For Windows to trust the certificate it must be imported into the ``LocalMachine\TrustedPeople`` certificate store. You can do this by running the following: + +.. code-block:: powershell + + $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("cert.pem") + + $store = Get-Item -LiteralPath Cert:\LocalMachine\TrustedPeople + $store.Open('ReadWrite') + $store.Add($cert) + $store.Dispose() + +If the cert is self-signed, or issued by a CA that is not trusted by the host, you will need to import the CA certificate into the trusted root store. As our example uses a self-signed cert, we will import that certificate as a trusted CA but in a production environment you would import the CA that signed the certificate. + +.. code-block:: powershell + + $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("cert.pem") + + $store = Get-Item -LiteralPath Cert:\LocalMachine\Root + $store.Open('ReadWrite') + $store.Add($cert) + $store.Dispose() + + +Mapping Certificate to a Local Account +"""""""""""""""""""""""""""""""""""""" + +Once the certificate has been imported into the ``LocalMachine\TrustedPeople`` store, the WinRM service can create the mapping between the certificate and a local account. This is done by running the following: + +.. code-block:: powershell + + # Will prompt for the password of the user. + $credential = Get-Credential local-user + + $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("cert.pem") + $certChain = [System.Security.Cryptography.X509Certificates.X509Chain]::new() + [void]$certChain.Build($cert) + $caThumbprint = $certChain.ChainElements.Certificate[-1].Thumbprint + + $certMapping = @{ + Path = 'WSMan:\localhost\ClientCertificate' + Subject = $cert.GetNameInfo('UpnName', $false) + Issuer = $caThumbprint + Credential = $credential + Force = $true + } + New-Item @certMapping + +The ``Subject`` is the value of the ``userPrincipalName`` in the certificate SAN entry. The ``Issuer`` is the thumbprint of the CA certificate that issued our certificate. The ``Credential`` is the username and password of the local user we are mapping the certificate to. + +Using Ansible +""""""""""""" + +The following Ansible playbook can be used to create a local user and map the certificate provided to use for certificate authentication. It needs to be called ``username`` and ``cert_pem`` variable set to the name of the user to create and the path to the public key PEM file that was generated. This playbook expects ``cert_pem`` to be a self signed certificate, if using a certificate issued by a CA, you will have to edit it so it copies that across and imports it to the ``LocalMachine\Root`` store instead. + +.. literalinclude:: yaml/winrm_cert_auth_setup.yaml + :language: yaml diff --git a/docs/docsite/rst/os_guide/windows_winrm_kerberos.rst b/docs/docsite/rst/os_guide/windows_winrm_kerberos.rst new file mode 100644 index 00000000000..7b508a7f7fb --- /dev/null +++ b/docs/docsite/rst/os_guide/windows_winrm_kerberos.rst @@ -0,0 +1,298 @@ +.. _windows_winrm_kerberos: + +Kerberos Authentication +======================= + +Kerberos authentication is a modern method used in Windows environments for authentication. It allows both the client and server to verify each others identities and supports modern encryption methods like AES. + +.. contents:: + :local: + + +Installing Kerberos +------------------- + +Kerberos is provided through a GSSAPI library which is part of a system package. Some distributions install the Kerberos packages by default but others may require manual installation. + +To install the Kerberos libraries on a RHEL/Fedora based system: + +.. code-block:: bash + + $ sudo dnf install krb5-devel krb5-libs krb5-workstation python3-devel + +For a Debian/Ubuntu based system: + +.. code-block:: bash + + $ sudo apt-get install krb5-user libkrb5-dev python3-dev + +For an Arch Linux based system: + +.. code-block:: bash + + $ sudo pacman -S krb5 + +For a FreeBSD based system: + +.. code-block:: bash + + $ sudo pkg install heimdal + +.. note:: + The ``python3-devel`` / ``python3-dev`` packages can be ignored if using Kerberos with the ``ssh`` connection plugin. They are only needed if using a WinRM based connection with Kerberos authentication. + +Once installed the ``kinit``, ``klist``, and ``krb5-config`` packages will be available. You can test them out with the following command: + +.. code-block:: bash + + $ krb5-config --version + + Kerberos 5 release 1.21.3 + +The ``psrp`` and ``winrm`` connection plugins require extra Python libraries for Kerberos authentication. The following step can be skipped if using Kerberos with the ``ssh`` connection. + +If you chose the ``pipx`` install instructions for Ansible, you can install those requirements by running the following: + +.. code-block:: shell + + pipx inject "pypsrp[kerberos]<=1.0.0" # for psrp + pipx inject "pywinrm[kerberos]>=0.4.0" # for winrm + +Or, if you chose the ``pip`` install instructions: + +.. code-block:: shell + + pip3 install "pypsrp[kerberos]<=1.0.0" # for psrp + pip3 install "pywinrm[kerberos]>=0.4.0" # for winrm + + +Configuring Host Kerberos +------------------------- + +Once the dependencies have been installed, Kerberos needs to be configured so that it can communicate with a domain. Most Kerberos implementations can either find a domain using DNS or through manual configuration in the ``/etc/krb5.conf`` file. For details on what can be set in the ``/etc/krb5.conf`` file see `krb5.conf `_ for more details. A simple ``krb5.conf`` file that uses DNS to lookup the KDC would be: + +.. code-block:: ini + + [libdefaults] + # Not required but helpful if the realm cannot be determined from + # the hostname + default_realm = MY.DOMAIN.COM + + # Enabled KDC lookups from DNS SRV records + dns_lookup_kdc = true + +With the above configuration when a Kerberos ticket is requested for the server ``server.my.domain.com`` the Kerberos library will do an SRV lookup for ``_kerberos._udp.my.domain.com`` and ``_kerberos._tcp.my.domain.com`` to find the KDC. If you wish to manually set the KDC realms you can use the following configuration: + +.. code-block:: ini + + [libdefaults] + default_realm = MY.DOMAIN.COM + dns_lookup_kdc = false + + [realms] + MY.DOMAIN.COM = { + kdc = domain-controller1.my.domain.com + kdc = domain-controller2.my.domain.com + } + + [domain_realm] + .my.domain.com = MY.DOMAIN.COM + my.domain.com = MY.DOMAIN.COM + +With this configuration any request for a ticket with the DNS suffix ``.my.domain.com`` and ``my.domain.com`` itself will be sent to the KDC ``domain-controller1.my.domain.com`` with a fallback to ``domain-controller2.my.domain.com``. + +More information on how the Kerberos library attempts to find the KDC can be found in the `MIT Kerberos Documentation `_. + +.. note:: + The information in this section assumes you are using the MIT Kerberos implementation which is typically the default on most Linux distributions. Some platforms like FreeBSD or macOS use a different GSSAPI implementation called Heimdal which acts in a similar way to MIT Kerberos but some behaviors may be different. + + +.. _winrm_kerberos_verify_config: + +Verifying Kerberos Configuration +-------------------------------- + +To verify that Kerberos is working correctly, you can use the ``kinit`` command to obtain a ticket for a user in the domain. The following command will request a ticket for the user ``username`` in the domain ``MY.DOMAIN.COM``: + +.. code-block:: bash + + $ kinit username@MY.DOMAIN.COM + Password for username@REALM.COM + +If the password is correct, the command will return without any output. To verify that the ticket has been obtained, you can use the ``klist`` command: + +.. code-block:: bash + + > klist + Ticket cache: KCM:1000 + Default principal: username@MY.DOMAIN.COM + + Valid starting Expires Service principal + 29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/MY.DOMAIN.COM@MY.DOMAIN.COM + renew until 05/09/24 13:54:48 + +If successful, this validates that the Kerberos configuration is correct and that the user can obtain a Ticket Granting Ticket (``TGT``) from the KDC. If ``kinit`` is unable to find the KDC for the requested realm, verify your Kerberos configuration by ensuring DNS can locate the KDC using the SRV records or that the KDC is manually mapped in the ``krb5.conf``. + +On MIT Kerberos based systems, you can use the ``kvno`` command to verify that you are able to retrieve a service ticket for a particular service. For example, if you are using a WinRM based connection to authenticate with ``server.my.domain.com`` you can use the following command to verify that your TGT is able to get a service ticket for the target server: + +.. code-block:: bash + + $ kvno http/server.my.domain.com + http/server2025.domain.test@DOMAIN.TEST: kvno = 2 + +The ``klist`` command can also be used to verify the ticket was stored in the Kerberos cache: + +.. code-block:: bash + + $ klist + Ticket cache: KCM:1000 + Default principal: username@MY.DOMAIN.COM + + Valid starting Expires Service principal + 29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/MY.DOMAIN.COM@MY.DOMAIN.COM + renew until 05/09/24 13:54:48 + 29/08/24 13:55:30 29/08/24 23:55:30 http/server.my.domain.com@MY.DOMAIN.COM + renew until 05/09/24 13:55:30 + +In the above example we have the TGT stored under the ``krbtgt`` service principal and our ``http/server.my.domain.com`` under its own service principal. + +The ``kdestroy`` command can be used to remove the ticket cache. + + +Ticket Management +----------------- + +For Kerberos authentication to work with Ansible, a Kerberos TGT for a user must be present so that Ansible can request a service ticket for the target server. Some connection plugins like ``ssh`` require the TGT to already be present and accessible to the Ansible control process. Other connection plugins, like ``psrp`` and ``winrm``, can automatically obtain a TGT for the user if the user's password is provided in the inventory. + +To retrieve a TGT manually for a user, run the ``kinit`` command with the user's username and domain as shown in :ref:`winrm_kerberos_verify_config`. This TGT will be used automatically when Kerberos authentication is requested by the connection plugin in Ansible. + +If you are using the ``psrp`` or ``winrm`` connection plugin and the user's password is provided in the inventory, the connection plugin will automatically obtain a TGT for the user. This is done by running the ``kinit`` command with the user's username and password. The TGT will be stored in a temporary credential cache and will be used for the task. + + +Delegation +---------- + +Kerberos delegation allows the credentials to traverse multiple hops. This is useful when you need to authenticate to a server and then have that server authenticate to another server on your behalf. To enable delegation, you must: + +* request a forwardable TGT when obtaining a ticket with ``kinit`` +* request the connection plugin to allow delegation to the server +* the AD user is not marked as sensitive and cannot be delegated and is not a member of the ``Protected Users`` group +* depending on the ``krb5.conf`` configuration, the target server may need to allow unconstrained delegation through its AD object delegation settings + +To request a forwardable TGT, either add the ``-f`` flag to the ``kinit`` command or set the ``forwardable = true`` option in the ``[libdefaults]`` section of the ``krb5.conf`` file. If you are using the ``psrp`` or ``winrm`` connection plugin to retrieve the TGT from the user's password in the inventory, it will automatically request a forwardable TGT if the connection plugin is configured to use delegation. + +To have the connection plugin delegate the credentials it will need to set the following hostvar in the inventory: + +.. code-block:: yaml+jinja + + # psrp + ansible_psrp_negotiate_delegate: true + + # winrm + ansible_winrm_kerberos_delegation: true + + # ssh + ansible_ssh_common_args: -o GSSAPIDelegateCredentials=yes + +.. note:: + It is also possible to set ``GSSAPIDelegateCredentials yes`` in the ``~/.ssh/config`` file to allow delegation for all SSH connections. + +To verify if a user is allowed to delegate their credentials, you can run the following PowerShell script on a Windows host in the same domain: + +.. code-block:: powershell + + Function Test-IsDelegatable { + [CmdletBinding()] + param ( + [Parameter(Mandatory)] + [string] + $UserName + ) + + $NOT_DELEGATED = 0x00100000 + + $searcher = [ADSISearcher]"(&(objectClass=user)(objectCategory=person)(sAMAccountName=$UserName))" + $res = $searcher.FindOne() + if (-not $res) { + Write-Error -Message "Failed to find user '$UserName'" + } + else { + $uac = $res.Properties.useraccountcontrol[0] + $memberOf = @($res.Properties.memberof) + + $isSensitive = [bool]($uac -band $NOT_DELEGATED) + $isProtectedUser = [bool]($memberOf -like 'CN=Protected Users,*').Count + + -not ($isSensitive -or $isProtectedUser) + } + } + + Test-IsDelegatable -UserName username + +Newer versions of MIT Kerberos have added a configuration option ``enforce_ok_as_delegate`` in the ``[libdefaults]`` section of the ``krb5.conf`` file. If this option is set to ``true`` delegation will only work if the target server account allows unconstrained delegation. To check or set unconstrained delegation on a Windows computer host, you can use the following PowerShell script: + +.. code-block:: powershell + + # Check if the server allows unconstrained delegation + (Get-ADComputer -Identity WINHOST -Properties TrustedForDelegation).TrustedForDelegation + + # Enable unconstrained delegation + Set-ADComputer -Identity WINHOST -TrustedForDelegation $true + +To verify that delegation is working, you can use the ``klist.exe`` command on the Windows node to verify that the ticket has been forwarded. The output should show the ticket server is for ``krbtgt/MY.DOMAIN.COM @ MY.CDOMAIN.COM`` and the ticket flags contained ``forwarded``. + +.. code-block:: shell + + $ ansible WINHOST -m ansible.windows.win_command -a klist.exe + + WINHOST | CHANGED | rc=0 >> + + Current LogonId is 0:0x82b6977 + + Cached Tickets: (1) + + #0> Client: username @ MY.DOMAIN.COM + Server: krbtgt/MY.DOMAIN.COM @ MY.DOMAIN.COM + KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96 + Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent name_canonicalize + Start Time: 8/30/2024 14:15:18 (local) + End Time: 8/31/2024 0:12:49 (local) + Renew Time: 9/6/2024 14:12:49 (local) + Session Key Type: AES-256-CTS-HMAC-SHA1-96 + Cache Flags: 0x1 -> PRIMARY + Kdc Called: + +If anything goes wrong, the output for ``klist.exe`` will not have the ``forwarded`` flag and the server will be for the target server principal and not ``krbtgt``. + +.. code-block:: shell + + $ ansible WINHOST -m ansible.windows.win_command -a klist.exe + + WINHOST | CHANGED | rc=0 >> + + Current LogonId is 0:0x82c312c + + Cached Tickets: (1) + + #0> Client: username @ MY.DOMAIN.COM + Server: http/winhost.my.domain.com @ MY.DOMAIN.COM + KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96 + Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize + Start Time: 8/30/2024 14:16:24 (local) + End Time: 8/31/2024 0:16:12 (local) + Renew Time: 0 + Session Key Type: AES-256-CTS-HMAC-SHA1-96 + Cache Flags: 0x8 -> ASC + Kdc Called: + + +Troubleshooting Kerberos +------------------------ + +Kerberos is reliant on a properly configured environment to work. Some common issues that can cause Kerberos authentication to fail are: + +* The hostname set for the Windows host is an alias or an IP address +* The time on the Ansible control node is not synchronized with the AD domain controller +* The KDC realm is not set correctly in the ``krb5.conf`` file or cannot be resolved through DNS + +If using the MIT Kerberos implementation, you can set the environment variable ``KRB5_TRACE=/dev/stdout`` to get more detailed information on what the Kerberos library is doing. This can be useful for debugging issues with the Kerberos library such as the KDC lookup behavior, time sync issues, and server name lookup failures. diff --git a/docs/docsite/rst/os_guide/yaml/winrm_cert_auth_setup.yaml b/docs/docsite/rst/os_guide/yaml/winrm_cert_auth_setup.yaml new file mode 100644 index 00000000000..facfbbf5d25 --- /dev/null +++ b/docs/docsite/rst/os_guide/yaml/winrm_cert_auth_setup.yaml @@ -0,0 +1,118 @@ +- name: Setup WinRM Client Cert Authentication + hosts: windows + gather_facts: false + + tasks: + - name: Verify required facts are setup + ansible.builtin.assert: + that: + - cert_pem is defined + - username is defined + + - name: Check that the required files are present + ansible.builtin.stat: + path: '{{ cert_pem }}' + delegate_to: localhost + run_once: true + register: local_cert_stat + + - name: Fail if cert PEM is not present + ansible.builtin.assert: + that: + - local_cert_stat.stat.exists + + - name: Generate local user password + ansible.builtin.set_fact: + user_password: "{{ lookup('ansible.builtin.password', playbook_dir ~ '/user_password', length=15) }}" + + - name: Create local user + ansible.windows.win_user: + name: '{{ username }}' + groups: + - Administrators + - Users + update_password: always + password: '{{ user_password }}' + user_cannot_change_password: true + password_never_expires: true + + - name: Copy across client certificate + ansible.windows.win_copy: + src: '{{ cert_pem }}' + dest: C:\Windows\TEMP\cert.pem + + - name: Import client certificate + ansible.windows.win_certificate_store: + path: C:\Windows\TEMP\cert.pem + state: present + store_location: LocalMachine + store_name: '{{ item }}' + register: client_cert_info + loop: + - Root + - TrustedPeople + + - name: Enable WinRM Certificate auth + ansible.windows.win_powershell: + script: | + $ErrorActionPreference = 'Stop' + $Ansible.Changed = $false + + $authPath = 'WSMan:\localhost\Service\Auth\Certificate' + if ((Get-Item -LiteralPath $authPath).Value -ne 'true') { + Set-Item -LiteralPath $authPath -Value true + $Ansible.Changed = $true + } + + - name: Setup Client Certificate Mapping + ansible.windows.win_powershell: + parameters: + Thumbprint: '{{ client_cert_info.results[0].thumbprints[0] }}' + sensitive_parameters: + - name: Credential + username: '{{ username }}' + password: '{{ user_password }}' + script: | + param( + [Parameter(Mandatory)] + [PSCredential] + $Credential, + + [Parameter(Mandatory)] + [string] + $Thumbprint + ) + + $ErrorActionPreference = 'Stop' + $Ansible.Changed = $false + + $userCert = Get-Item -LiteralPath "Cert:\LocalMachine\TrustedPeople\$Thumbprint" + $subject = $userCert.GetNameInfo('UpnName', $false) # SAN userPrincipalName + + $certChain = New-Object -TypeName Security.Cryptography.X509Certificates.X509Chain + [void]$certChain.Build($userCert) + $caThumbprint = $certChain.ChainElements.Certificate[-1].Thumbprint + + $mappings = Get-ChildItem -LiteralPath WSMan:\localhost\ClientCertificate | + Where-Object { + $mapping = $_ | Get-Item + "Subject=$subject" -in $mapping.Keys + } + + if ($mappings -and "issuer=$($caThumbprint)" -notin $mappings.Keys) { + $null = $mappings | Remove-Item -Force -Recurse + $mappings = $null + $Ansible.Changed = $true + } + + if (-not $mappings) { + $certMapping = @{ + Path = 'WSMan:\localhost\ClientCertificate' + Subject = $subject + Issuer = $caThumbprint + Credential = $Credential + Force = $true + } + $null = New-Item @certMapping + $Ansible.Changed = $true + } diff --git a/docs/docsite/rst/playbook_guide/guide_rolling_upgrade.rst b/docs/docsite/rst/playbook_guide/guide_rolling_upgrade.rst index 9ab80ec679d..805ad81bbf5 100644 --- a/docs/docsite/rst/playbook_guide/guide_rolling_upgrade.rst +++ b/docs/docsite/rst/playbook_guide/guide_rolling_upgrade.rst @@ -23,11 +23,6 @@ playbooks as a template: lamp_haproxy. This example uses a lot of Ansible featur and group variables, and it also comes with an orchestration playbook that can do zero-downtime rolling upgrades of the web application stack. -.. note:: - - `Click here for the latest playbooks for this example - `_. - The playbooks deploy Apache, PHP, MySQL, Nagios, and HAProxy to a CentOS-based set of servers. We're not going to cover how to run these playbooks here. Read the included README in the GitHub project along with the @@ -312,8 +307,6 @@ This should give you a good idea of how to structure a multi-tier application wi .. seealso:: - `lamp_haproxy example `_ - The lamp_haproxy example discussed here. :ref:`working_with_playbooks` An introduction to playbooks :ref:`playbooks_reuse_roles` diff --git a/docs/docsite/rst/playbook_guide/playbook_pathing.rst b/docs/docsite/rst/playbook_guide/playbook_pathing.rst index 9fcd0429059..efc226df507 100644 --- a/docs/docsite/rst/playbook_guide/playbook_pathing.rst +++ b/docs/docsite/rst/playbook_guide/playbook_pathing.rst @@ -26,20 +26,30 @@ Resolving local relative paths When you specify a relative path for a local file, Ansible will try to find that file first in the current task's role, then in other roles that included or depend on the current role, then relative to the file in which the task is defined, and finally relative to the current play. It will take the first matching file that it finds. This way, if multiple files with the same file name exist, Ansible will find the file that is closest to the current task and that is most likely to be file you wanted. -Specifically, Ansible tries to find the file +Specifically, Ansible tries to find the file in the following order: 1. In the current role. - 1. In its appropriate subdirectory—"files", "vars", "templates" or "tasks", depending on the kind of file Ansible is searching for. + 1. In its appropriate subdirectory: "files", "vars", "templates", or "tasks"; depending on the kind of file Ansible is searching for. 2. Directly in its directory. - -2. Like 1, in the parent role that called into this current role with `include_role`, `import_role`, or with a role dependency. If the parent role has its own parent role, Ansible will repeat this step with that role. + +2. Like 1, in the parent role that called into this current role with ``include_role``, ``import_role``, or with a role dependency. If the parent role has its own parent role, Ansible will repeat this step with that role. 3. Like 1, in the current task file's directory. 4. Like 1, in the current play file's directory. -Ansible does not search the current working directory. (The directory you're in when you execute Ansible.) Also, Ansible will only search within a role if you actually included it with an `include_role` or `import_role` task or a dependency. If you instead use `include`, `include_task` or `import_task` to include just the tasks from a specific file but not the full role, Ansible will not search that role in steps 1 and 2. +Ansible does not search for local files in the current working directory; in other words, the directory from which you execute Ansible. + +.. note:: -When you execute Ansible, the variable `ansible_search_path` will contain the paths searched, in the order they were searched in but without listing their subdirectories. If you run Ansible in verbosity level 5 by passing the `-vvvvv` argument, Ansible will report each directory as it searches, except when it searches for a tasks file. + * The current working directory might vary depending on the connection plugin and if the action is local or remote. + For the remote it is normally the directory on which the login shell puts the user. + For local it is either the directory you executed Ansible from or in some cases the playbook directory. + * Search path context is additive, meaning that Ansible uses a "stack" of contexts when resolving file paths. + When resolving local relative paths for files in tasks, the context of the role that includes tasks with an ``include_role`` or ``import_role`` statement gets highest precedence in the stack. + If you import the tasks with ``include_task``, or ``import_task`` statements, Ansible uses the context of the importing file. +Troubleshooting search paths +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. note:: The current working directory might vary depending on the connection plugin and if the action is local or remote. For the remote it is normally the directory on which the login shell puts the user. For local it is either the directory you executed ansible from or in some cases the playbook directory. +When you execute Ansible, the variable ``ansible_search_path`` will contain the paths searched, in the order they were searched in but without listing their subdirectories. +If you run Ansible in verbosity level 5 by passing the ``-vvvvv`` argument, Ansible will report each directory as it searches, except when it searches for a tasks file. diff --git a/docs/docsite/rst/playbook_guide/playbooks.rst b/docs/docsite/rst/playbook_guide/playbooks.rst index 7f6659238dd..6d22d79a464 100644 --- a/docs/docsite/rst/playbook_guide/playbooks.rst +++ b/docs/docsite/rst/playbook_guide/playbooks.rst @@ -14,9 +14,6 @@ At a more advanced level, they can sequence multi-tier rollouts involving rollin Playbooks are designed to be human-readable and are developed in a basic text language. There are multiple ways to organize playbooks and the files they include, and we'll offer up some suggestions on that and making the most out of Ansible. -You should look at `Example Playbooks `_ while reading along with the playbook documentation. -These illustrate best practices as well as how to put many of the various concepts together. - .. toctree:: :maxdepth: 2 diff --git a/docs/docsite/rst/playbook_guide/playbooks_advanced_syntax.rst b/docs/docsite/rst/playbook_guide/playbooks_advanced_syntax.rst index a1327c2e051..e542f1164bc 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_advanced_syntax.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_advanced_syntax.rst @@ -62,10 +62,10 @@ You define an anchor with ``&``, then refer to it using an alias, denoted with ` opts: '-Xms1G -Xmx2G' port: 1000 path: /usr/lib/app1 - app2: - jvm: - <<: *jvm_opts - path: /usr/lib/app2 + app2: + jvm: + <<: *jvm_opts + path: /usr/lib/app2 ... Here, ``app1`` and ``app2`` share the values for ``opts`` and ``port`` using the anchor ``&jvm_opts`` and the alias ``*jvm_opts``. @@ -116,7 +116,5 @@ You've anchored the value of ``version`` with the ``&my_version`` anchor and reu All about variables :ref:`complex_data_manipulation` Doing complex data manipulation in Ansible - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_async.rst b/docs/docsite/rst/playbook_guide/playbooks_async.rst index 7ce38faf979..17349feeb58 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_async.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_async.rst @@ -183,7 +183,5 @@ To run multiple asynchronous tasks while limiting the number of tasks running co Options for controlling playbook execution :ref:`playbooks_intro` An introduction to playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_blocks.rst b/docs/docsite/rst/playbook_guide/playbooks_blocks.rst index e60d50853ee..523928bc5b8 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_blocks.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_blocks.rst @@ -20,6 +20,7 @@ All tasks in a block inherit directives applied at the block level. Most of what tasks: - name: Install, configure, and start Apache + when: ansible_facts['distribution'] == 'CentOS' block: - name: Install httpd and memcached ansible.builtin.yum: @@ -38,7 +39,6 @@ All tasks in a block inherit directives applied at the block level. Most of what name: bar state: started enabled: True - when: ansible_facts['distribution'] == 'CentOS' become: true become_user: root ignore_errors: true @@ -203,7 +203,7 @@ These can be inspected in the ``rescue`` section: ansible.builtin.debug: msg: All is good, ignore error as grep could not find 'me' in hosts - - name: All is good if the first task failed + - name: All is good if the second task failed when: "'/bin/false' in ansible_failed_result.cmd | d([])" ansible.builtin.fail: msg: It is still false!!! @@ -218,7 +218,5 @@ These can be inspected in the ``rescue`` section: An introduction to playbooks :ref:`playbooks_reuse_roles` Playbook organization by roles - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst b/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst index 19a36be16f8..bfd8fd09c4a 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst @@ -600,7 +600,5 @@ Possible values (sample, not complete list): Tips and tricks for playbooks :ref:`playbooks_variables` All about variables - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_debugger.rst b/docs/docsite/rst/playbook_guide/playbooks_debugger.rst index 4f32c04a2d0..1c4fc845d8c 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_debugger.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_debugger.rst @@ -336,7 +336,5 @@ With the default ``linear`` strategy enabled, Ansible halts execution while the Running playbooks while debugging or testing :ref:`playbooks_intro` An introduction to playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_delegation.rst b/docs/docsite/rst/playbook_guide/playbooks_delegation.rst index f4bae2d2e24..3a4e9bb4c40 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_delegation.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_delegation.rst @@ -177,9 +177,5 @@ use the default remote connection type: An introduction to playbooks :ref:`playbooks_strategies` More ways to control how and where Ansible executes - `Ansible Examples on GitHub `_ - Many examples of full-stack deployments - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_environment.rst b/docs/docsite/rst/playbook_guide/playbooks_environment.rst index d4fe6094f51..e948dc941c7 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_environment.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_environment.rst @@ -147,7 +147,5 @@ You can also specify the environment at the task level. :ref:`playbooks_intro` An introduction to playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst b/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst index 1d05f204207..65d92fddc93 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst @@ -116,13 +116,13 @@ You can also combine multiple conditions for failure. This task will fail if bot register: result failed_when: - result.rc == 0 - - '"No such" not in result.stdout' + - '"No such" not in result.stderr' If you want the task to fail when only one condition is satisfied, change the ``failed_when`` definition to .. code-block:: yaml - failed_when: result.rc == 0 or "No such" not in result.stdout + failed_when: result.rc == 0 or "No such" not in result.stderr If you have too many conditions to fit neatly into one line, you can split it into a multi-line YAML value with ``>``. @@ -277,7 +277,5 @@ You can also use blocks to define responses to task errors. This approach is sim Conditional statements in playbooks :ref:`playbooks_variables` All about variables - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_filters.rst b/docs/docsite/rst/playbook_guide/playbooks_filters.rst index 6c25eabc377..bb15adb6f32 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_filters.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_filters.rst @@ -27,7 +27,7 @@ You can provide default values for variables directly in your templates using th {{ some_variable | default(5) }} -In the above example, if the variable 'some_variable' is not defined, Ansible uses the default value 5, rather than raising an "undefined variable" error and failing. If you are working within a role, you can also add a ``defaults/main.yml`` to define the default values for variables in your role. +In the above example, if the variable 'some_variable' is not defined, Ansible uses the default value 5, rather than raising an "undefined variable" error and failing. If you are working within a role, you can also add role defaults to define the default values for variables in your role. To learn more about role defaults see :ref:`Role directory structure `. Beginning in version 2.8, attempting to access an attribute of an Undefined value in Jinja will return another Undefined value, rather than throwing an error immediately. This means that you can now simply use a default with a value in a nested data structure (in other words, :code:`{{ foo.bar.baz | default('DEFAULT') }}`) when you do not know if the intermediate values are defined. @@ -116,6 +116,29 @@ If you are unsure of the underlying Python type of a variable, you can use the : You should note that, while this may seem like a useful filter for checking that you have the right type of data in a variable, you should often prefer :ref:`type tests `, which will allow you to test for specific data types. +Transforming strings into lists +------------------------------- + +Use the :ansplugin:`ansible.builtin.split#filter` filter to transform a character/string delimited string into a list of items suitable for :ref:`looping `. For example, if you want to split a string variable `fruits` by commas, you can use: + +.. code-block:: yaml+jinja + + {{ fruits | split(',') }} + +String data (before applying the :ansplugin:`ansible.builtin.split#filter` filter): + +.. code-block:: yaml + + fruits: apple,banana,orange + +List data (after applying the :ansplugin:`ansible.builtin.split#filter` filter): + +.. code-block:: yaml + + - apple + - banana + - orange + .. _dict_filter: Transforming dictionaries into lists @@ -2216,9 +2239,7 @@ This can then be used to reference hashes in Pod specifications: Playbook organization by roles :ref:`tips_and_tricks` Tips and tricks for playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide `Python 3 Regular expression operations `_ How to use inline regular expression flags diff --git a/docs/docsite/rst/playbook_guide/playbooks_handlers.rst b/docs/docsite/rst/playbook_guide/playbooks_handlers.rst index 1b3c2111859..953c1014711 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_handlers.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_handlers.rst @@ -211,4 +211,5 @@ Since Ansible 2.14 :ansplugin:`meta tasks ` are all Limitations ----------- -A handler cannot run ``import_role`` or ``include_role``. +A handler cannot run ``import_role`` nor ``include_role``. +Handlers :ref:`ignore tags `. diff --git a/docs/docsite/rst/playbook_guide/playbooks_intro.rst b/docs/docsite/rst/playbook_guide/playbooks_intro.rst index 280097a359e..dcf2966bd74 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_intro.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_intro.rst @@ -5,7 +5,7 @@ Ansible playbooks ***************** -Ansible Playbooks offer a repeatable, reusable, simple configuration management and multi-machine deployment system, one that is well suited to deploying complex applications. If you need to execute a task with Ansible more than once, write a playbook and put it under source control. Then you can use the playbook to push out new configuration or confirm the configuration of remote systems. The playbooks in the `ansible-examples repository `_ illustrate many useful techniques. You may want to look at these in another tab as you read the documentation. +Ansible Playbooks offer a repeatable, reusable, simple configuration management and multi-machine deployment system, one that is well suited to deploying complex applications. If you need to execute a task with Ansible more than once, write a playbook and put it under source control. Then you can use the playbook to push out new configuration or confirm the configuration of remote systems. Playbooks can: @@ -136,8 +136,6 @@ Assuming you load balance your checkout location, ``ansible-pull`` scales essent Run ``ansible-pull --help`` for details. -There's also a `clever playbook `_ available to configure ``ansible-pull`` through a crontab from push mode. - Verifying playbooks =================== @@ -173,7 +171,5 @@ The `ansible-lint default rules `_ - Complete end-to-end playbook examples - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_lookups.rst b/docs/docsite/rst/playbook_guide/playbooks_lookups.rst index ee49513ac7f..5ab335ae061 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_lookups.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_lookups.rst @@ -33,7 +33,5 @@ For more details and a list of lookup plugins in ansible-core, see :ref:`plugins All about variables :ref:`playbooks_loops` Looping in playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_loops.rst b/docs/docsite/rst/playbook_guide/playbooks_loops.rst index 93fd27d94eb..ff862a02dea 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_loops.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_loops.rst @@ -167,7 +167,7 @@ You can register the output of a loop as a variable. For example - "two" register: echo -When you use ``register`` with a loop, the data structure placed in the variable will contain a ``results`` attribute that is a list of all responses from the module. This differs from the data structure returned when using ``register`` without a loop. +When you use ``register`` with a loop, the data structure placed in the variable will contain a ``results`` attribute that is a list of all responses from the module. This differs from the data structure returned when using ``register`` without a loop. The ``changed``/``failed``/``skipped`` attribute that's beside the ``results`` will represent the overall state. ``changed``/``failed`` will be `true` if at least one of the iterations triggered a change/failed, while ``skipped`` will be `true` only if all iterations were skipped. .. code-block:: json @@ -254,7 +254,29 @@ To see the results of individual retries, run the play with ``-vv``. When you run a task with ``until`` and register the result as a variable, the registered variable will include a key called "attempts", which records the number of retries for the task. -If ``until`` is not specified, the task will retry until the task succeeds but at most ``retries`` times. +If ``until`` is not specified, the task will retry until the task succeeds but at most ``retries`` times (New in version 2.16). + +You can combine the ``until`` keyword with ``loop`` or ``with_``. The result of the task for each element of the loop is registered in the variable and can be used in the ``until`` condition. Here is an example: + +.. code-block:: yaml + + - name: Retry combined with a loop + uri: + url: "https://{{ item }}.ansible.com" + method: GET + register: uri_output + with_items: + - "galaxy" + - "docs" + - "forum" + - "www" + retries: 2 + delay: 1 + until: "uri_output.status == 200" + +.. note:: + + When you use the ``timeout`` keyword in a loop, it applies to each attempt of the task action. See :ref:`TASK_TIMEOUT ` for more details. .. _loop_over_inventory: @@ -365,6 +387,33 @@ To control the time (in seconds) between the execution of each item in a task lo loop_control: pause: 3 +Breaking out of a loop +---------------------- +.. versionadded:: 2.18 + +Use the ``break_when`` directive with ``loop_control`` to exit a loop after any item, based on Jinja2 expressions. + +.. code-block:: yaml+jinja + + # main.yml + - name: Use set_fact in a loop until a condition is met + vars: + special_characters: "!@#$%^&*(),.?:{}|<>" + character_set: "digits,ascii_letters,{{ special_characters }}" + password_policy: '^(?=.*\d)(?=.*[A-Z])(?=.*[{{ special_characters | regex_escape }}]).{12,}$' + block: + - name: Generate a password until it contains a digit, uppercase letter, and special character (10 attempts) + set_fact: + password: "{{ lookup('password', '/dev/null', chars=character_set, length=12) }}" + loop: "{{ range(0, 10) }}" + loop_control: + break_when: + - password is match(password_policy) + + - fail: + msg: "Maximum attempts to generate a valid password exceeded" + when: password is not match(password_policy) + Tracking progress through a loop with ``index_var`` --------------------------------------------------- .. versionadded:: 2.5 @@ -471,7 +520,7 @@ To avoid this, you can specify the name of the variable for each loop using ``lo .. code-block:: yaml+jinja # main.yml - - include_task: inner.yml + - include_tasks: inner.yml loop: - 1 - 2 @@ -566,7 +615,5 @@ Migrating from with_X to loop Conditional statements in playbooks :ref:`playbooks_variables` All about variables - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_privilege_escalation.rst b/docs/docsite/rst/playbook_guide/playbooks_privilege_escalation.rst index 56169edc36e..1166a174498 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_privilege_escalation.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_privilege_escalation.rst @@ -769,7 +769,5 @@ Limitations of become on Windows .. seealso:: - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_prompts.rst b/docs/docsite/rst/playbook_guide/playbooks_prompts.rst index d962352cb2c..50e90231ab2 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_prompts.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_prompts.rst @@ -118,7 +118,5 @@ Some special characters, such as ``{`` and ``%`` can create templating errors. I Conditional statements in playbooks :ref:`playbooks_variables` All about variables - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_reuse.rst b/docs/docsite/rst/playbook_guide/playbooks_reuse.rst index 4e42fc8d28a..c4c5966d54c 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_reuse.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_reuse.rst @@ -220,7 +220,5 @@ Imports are processed before the play begins, so the name of the import no longe Tips and tricks for playbooks :ref:`ansible_galaxy` How to share roles on galaxy, role management - `GitHub Ansible examples `_ - Complete playbook files from the GitHub project source - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst b/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst index 05b86f213c4..386869059e3 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst @@ -9,6 +9,8 @@ Roles let you automatically load related vars, files, tasks, handlers, and other .. contents:: :local: +.. _role_directory_structure: + Role directory structure ======================== @@ -77,6 +79,20 @@ Or call those tasks directly when loading the role, which bypasses the ``main.ym when: ansible_facts['os_family'] == 'Debian' +Directories ``defaults`` and ``vars`` may also include *nested directories*. If your variables file is a directory, Ansible reads all variables files and directories inside in alphabetical order. If a nested directory contains variables files as well as directories, Ansible reads the directories first. Below is an example of a ``vars/main`` directory: + +.. code-block:: text + + roles/ + common/ # this hierarchy represents a "role" + vars/ + main/ # <-- variables associated with this role + first_nested_directory/ + first_variables_file.yml + second_nested_directory/ + second_variables_file.yml + third_variables_file.yml + .. _role_search_path: Storing and finding roles @@ -125,15 +141,21 @@ The classic (original) way to use roles is with the ``roles`` option for a given - common - webservers -When you use the ``roles`` option at the play level, for each role 'x': +When you use the ``roles`` option at the play level, each role 'x' looks for a ``main.yml`` (also ``main.yaml`` and ``main``) in the following directories: -- If roles/x/tasks/main.yml exists, Ansible adds the tasks in that file to the play. -- If roles/x/handlers/main.yml exists, Ansible adds the handlers in that file to the play. -- If roles/x/vars/main.yml exists, Ansible adds the variables in that file to the play. -- If roles/x/defaults/main.yml exists, Ansible adds the variables in that file to the play. -- If roles/x/meta/main.yml exists, Ansible adds any role dependencies in that file to the list of roles. +- ``roles/x/tasks/`` +- ``roles/x/handlers/`` +- ``roles/x/vars/`` +- ``roles/x/defaults/`` +- ``roles/x/meta/`` - Any copy, script, template or include tasks (in the role) can reference files in roles/x/{files,templates,tasks}/ (dir depends on task) without having to path them relatively or absolutely. +.. note:: + ``vars`` and ``defaults`` can also match to a directory of the same name and Ansible will process all the files contained in that directory. See :ref:`Role directory structure ` for more details. + +.. note:: + If you use ``include_role/import_role``, you can specify a custom file name instead of ``main``. The ``meta`` directory is an exception because it does not allow for customization. + When you use the ``roles`` option at the play level, Ansible treats the roles as static imports and processes them during playbook parsing. Ansible executes each play in this order: - Any ``pre_tasks`` defined in the play. @@ -365,7 +387,7 @@ role ``meta/argument_specs.yml`` file. All fields are lowercase. * If ``required`` is ``false``/missing, ``default`` may be specified (assumed ``null`` if missing). * Ensure that the default value in the docs matches the default value in the code. The actual - default for the role variable will always come from ``defaults/main.yml``. + default for the role variable will always come from the role defaults (as defined in :ref:`Role directory structure `). * The default field must not be listed as part of the description unless it requires additional information or conditions. * If the option is a boolean value, you should use ``true``/``false`` if you want to be compatible with ``ansible-lint``. @@ -714,7 +736,7 @@ Sharing roles: Ansible Galaxy The client ``ansible-galaxy`` is included in Ansible. The Galaxy client allows you to download roles from Ansible Galaxy and provides an excellent default framework for creating your own roles. -Read the `Ansible Galaxy documentation `_ page for more information. A page that refers back to this one frequently is the Galaxy Roles document which explains the required metadata your role needs for use in Galaxy . +Read the `Ansible Galaxy documentation `_ page for more information. .. seealso:: @@ -738,7 +760,5 @@ Read the `Ansible Galaxy documentation `_ page Browse existing collections, modules, and plugins :ref:`developing_modules` Extending Ansible by writing your own modules - `GitHub Ansible examples `_ - Complete playbook files from the GitHub project source - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_strategies.rst b/docs/docsite/rst/playbook_guide/playbooks_strategies.rst index 97b620a4898..83d75751574 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_strategies.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_strategies.rst @@ -248,7 +248,5 @@ As always with :ref:`delegation `, the action will be exec Running tasks on or assigning facts to specific machines :ref:`playbooks_reuse_roles` Playbook organization by roles - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_tags.rst b/docs/docsite/rst/playbook_guide/playbooks_tags.rst index 5069e09fdfb..89124f01057 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_tags.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_tags.rst @@ -9,9 +9,13 @@ If you have a large playbook, it may be useful to run only specific parts of it #. Add tags to your tasks, either individually or with tag inheritance from a block, play, role, or import. #. Select or skip tags when you run your playbook. +.. note:: + The ``tags`` keyword is part of 'pre processing' the playbook and has high precedence when deciding what tasks are available to consider for execution. + .. contents:: :local: + Adding tags with the tags keyword ================================= @@ -81,6 +85,14 @@ You can apply the same tag to more than one individual task. This example tags s If you ran these four tasks in a playbook with ``--tags ntp``, Ansible would run the three tasks tagged ``ntp`` and skip the one task that does not have that tag. +.. _tags_on_handlers: + +Adding tags to handlers +^^^^^^^^^^^^^^^^^^^^^^^ + +Handlers are a special case of tasks that only execute when notified, as such they ignore all tags and cannot be selected for nor against. + + .. _tags_on_blocks: Adding tags to blocks @@ -121,6 +133,23 @@ If you want to apply a tag to many, but not all, of the tasks in your play, use tags: filesharing +Be mindful that ``tag`` selection supersedes most other logic, including ``block`` error handling. Setting a tag on a task in a ``block`` but not in the ``rescue`` or ``always`` section will prevent those from triggering if your tags selection does not cover the tasks in those sections. + +.. code-block:: yaml + + - block: + - debug: msg=run with tag, but always fail + failed_when: true + tags: example + + rescue: + - debug: msg=I always run because the block always fails, except if you select to only run 'example' tag + + always: + - debug: msg=I always run, except if you select to only run 'example' tag + +This example runs all 3 tasks if called without specifying ``--tags`` but only runs the first task if you run with ``--tags example``. + .. _tags_on_plays: Adding tags to plays @@ -156,6 +185,8 @@ If all the tasks in a play should get the same tag, you can add the tag at the l tasks: ... +.. note:: + The tasks tagged will include all implicit tasks (like fact gathering) of the play, including those added via roles. .. _tags_on_roles: @@ -192,6 +223,12 @@ or: # using YAML shorthand, this is equivalent to: # - { role: foo, tags: ["bar", "baz"] } + +.. note:: + When adding a tag at the role level, not only are all tasks tagged, but the role's dependencies also have their tasks tagged. + See the tag inheritance section for details. + + .. _tags_on_includes: Adding tags to includes @@ -479,7 +516,5 @@ If you run or skip certain tags by default, you can use the :ref:`TAGS_RUN` and An introduction to playbooks :ref:`playbooks_reuse_roles` Playbook organization by roles - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_templating.rst b/docs/docsite/rst/playbook_guide/playbooks_templating.rst index 9cc971ea28c..506a17dab3e 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_templating.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_templating.rst @@ -61,7 +61,5 @@ Our test.j2: Tips and tricks for playbooks `Jinja2 Docs `_ Jinja2 documentation, includes the syntax and semantics of the templates - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_tests.rst b/docs/docsite/rst/playbook_guide/playbooks_tests.rst index 4a298ef8099..15905a06218 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_tests.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_tests.rst @@ -536,7 +536,5 @@ When looking to determine types, it may be tempting to use the ``type_debug`` fi Playbook organization by roles :ref:`tips_and_tricks` Tips and tricks for playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_variables.rst b/docs/docsite/rst/playbook_guide/playbooks_variables.rst index 3a4e5fcace5..127fc38ec8c 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_variables.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_variables.rst @@ -6,7 +6,7 @@ Using Variables Ansible uses variables to manage differences between systems. With Ansible, you can execute tasks and playbooks on multiple different systems with a single command. To represent the variations among those different systems, you can create variables with standard YAML syntax, including lists and dictionaries. You can define these variables in your playbooks, in your :ref:`inventory `, in reusable :ref:`files ` or :ref:`roles `, or at the command line. You can also create variables during a playbook run by registering the return value or values of a task as a new variable. -After you create variables, either by defining them in a file, passing them at the command line, or registering the return value or values of a task as a new variable, you can use those variables in module arguments, in :ref:`conditional "when" statements `, in :ref:`templates `, and in :ref:`loops `. The `ansible-examples GitHub repository `_ contains many examples of using variables in Ansible. +After you create variables, either by defining them in a file, passing them at the command line, or registering the return value or values of a task as a new variable, you can use those variables in module arguments, in :ref:`conditional "when" statements `, in :ref:`templates `, and in :ref:`loops `. Once you understand the concepts and examples on this page, read about :ref:`Ansible facts `, which are variables you retrieve from remote systems. @@ -85,7 +85,7 @@ If you use a variable without quotes like this: - hosts: app_servers vars: - app_path: {{ base_path }}/22 + app_path: {{ base_path }}/22 You will see: ``ERROR! Syntax Error while loading YAML.`` If you add quotes, Ansible works correctly: @@ -93,7 +93,7 @@ You will see: ``ERROR! Syntax Error while loading YAML.`` If you add quotes, Ans - hosts: app_servers vars: - app_path: "{{ base_path }}/22" + app_path: "{{ base_path }}/22" .. _boolean_variables: @@ -177,6 +177,70 @@ Both of these examples reference the same value ("one"). Bracket notation always ``add``, ``append``, ``as_integer_ratio``, ``bit_length``, ``capitalize``, ``center``, ``clear``, ``conjugate``, ``copy``, ``count``, ``decode``, ``denominator``, ``difference``, ``difference_update``, ``discard``, ``encode``, ``endswith``, ``expandtabs``, ``extend``, ``find``, ``format``, ``fromhex``, ``fromkeys``, ``get``, ``has_key``, ``hex``, ``imag``, ``index``, ``insert``, ``intersection``, ``intersection_update``, ``isalnum``, ``isalpha``, ``isdecimal``, ``isdigit``, ``isdisjoint``, ``is_integer``, ``islower``, ``isnumeric``, ``isspace``, ``issubset``, ``issuperset``, ``istitle``, ``isupper``, ``items``, ``iteritems``, ``iterkeys``, ``itervalues``, ``join``, ``keys``, ``ljust``, ``lower``, ``lstrip``, ``numerator``, ``partition``, ``pop``, ``popitem``, ``real``, ``remove``, ``replace``, ``reverse``, ``rfind``, ``rindex``, ``rjust``, ``rpartition``, ``rsplit``, ``rstrip``, ``setdefault``, ``sort``, ``split``, ``splitlines``, ``startswith``, ``strip``, ``swapcase``, ``symmetric_difference``, ``symmetric_difference_update``, ``title``, ``translate``, ``union``, ``update``, ``upper``, ``values``, ``viewitems``, ``viewkeys``, ``viewvalues``, ``zfill``. +Combining variables +=================== + +To merge variables that contain lists or dictionaries, you can use the following approaches. + +Combining list variables +------------------------ + +You can use the `set_fact` module to combine lists into a new `merged_list` variable as follows: + +.. code-block:: yaml + + vars: + list1: + - apple + - banana + - fig + + list2: + - peach + - plum + - pear + + tasks: + - name: Combine list1 and list2 into a merged_list var + ansible.builtin.set_fact: + merged_list: "{{ list1 + list2 }}" + +Combining dictionary variables +------------------------------ + +To merge dictionaries use the ``combine`` filter, for example: + +.. code-block:: yaml + + vars: + dict1: + name: Leeroy Jenkins + age: 25 + occupation: Astronaut + + dict2: + location: Galway + country: Ireland + postcode: H71 1234 + + tasks: + - name: Combine dict1 and dict2 into a merged_dict var + ansible.builtin.set_fact: + merged_dict: "{{ dict1 | ansible.builtin.combine(dict2) }}" + +For more details, see :ansplugin:`ansible.builtin.combine#filter` . + +Using the merge_variables lookup +-------------------------------- + +To merge variables that match the given prefixes, suffixes, or regular expressions, you can use the ``community.general.merge_variables`` lookup, for example: + +.. code-block:: yaml + + merged_variable: "{{ lookup('community.general.merge_variables', '__my_pattern', pattern_type='suffix') }}" + +For more details and example usage, refer to the `community.general.merge_variables lookup documentation `_. + .. _registered_variables: Registering variables @@ -360,7 +424,7 @@ Understanding variable precedence Ansible does apply variable precedence, and you might have a use for it. Here is the order of precedence from least to greatest (the last listed variables override all other variables): #. command line values (for example, ``-u my_user``, these are not variables) - #. role defaults (defined in role/defaults/main.yml) [1]_ + #. role defaults (as defined in :ref:`Role directory structure `) [1]_ #. inventory file or script group vars [2]_ #. inventory group_vars/all [3]_ #. playbook group_vars/all [3]_ @@ -373,7 +437,7 @@ Ansible does apply variable precedence, and you might have a use for it. Here is #. play vars #. play vars_prompt #. play vars_files - #. role vars (defined in role/vars/main.yml) + #. role vars (as defined in :ref:`Role directory structure `) #. block vars (only for tasks in block) #. task vars (only for the task) #. include_vars @@ -491,7 +555,7 @@ When you read this playbook it is clear that you have chosen to set a variable o vars: myname: John -Variables set in one role are available to later roles. You can set variables in a ``roles/common_settings/vars/main.yml`` file and use them in other roles and elsewhere in your playbook: +Variables set in one role are available to later roles. You can set variables in the role's ``vars`` directory (as defined in :ref:`Role directory structure `) and use them in other roles and elsewhere in your playbook: .. code-block:: yaml @@ -528,7 +592,5 @@ For information about advanced YAML syntax used to declare variables and have mo Tips and tricks for playbooks :ref:`special_variables` List of special variables - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/playbook_guide/playbooks_vars_facts.rst b/docs/docsite/rst/playbook_guide/playbooks_vars_facts.rst index f27870a715a..7ab357dfb50 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_vars_facts.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_vars_facts.rst @@ -20,7 +20,7 @@ Ansible facts are data related to your remote systems, including operating syste ansible.builtin.debug: var: ansible_facts -To see the 'raw' information as gathered, run this command at the command line: +If you have already created an :ref:`inventory` and configured working SSH credentials, you can see the 'raw' information for any host in your inventory by running this :ref:`ad-hoc ansible command` at the command line: .. code-block:: shell diff --git a/docs/docsite/rst/plugins/action.rst b/docs/docsite/rst/plugins/action.rst index e61ded2dc52..862786cec94 100644 --- a/docs/docsite/rst/plugins/action.rst +++ b/docs/docsite/rst/plugins/action.rst @@ -49,7 +49,5 @@ Use ``ansible-doc `` to see plugin-specific documentation and examples. Th Strategy plugins :ref:`vars_plugins` Vars plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/become.rst b/docs/docsite/rst/plugins/become.rst index 6cd7d402a1f..44ea6b2ca96 100644 --- a/docs/docsite/rst/plugins/become.rst +++ b/docs/docsite/rst/plugins/become.rst @@ -61,7 +61,5 @@ Use ``ansible-doc -t become `` to see plugin-specific documentation Test plugins :ref:`lookup_plugins` Lookup plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/cache.rst b/docs/docsite/rst/plugins/cache.rst index c9ca686ef69..5e877a7670e 100644 --- a/docs/docsite/rst/plugins/cache.rst +++ b/docs/docsite/rst/plugins/cache.rst @@ -38,7 +38,7 @@ If the cache plugin is in a collection use the fully qualified name: [defaults] fact_caching = namespace.collection_name.cache_plugin_name -To enable a custom cache plugin, save it in a ``cache_plugins`` directory adjacent to your play, inside a role, or in one of the directory sources configured in :ref:`ansible.cfg `. +To enable a custom cache plugin, save it in one of the directory sources configured in :ref:`ansible.cfg ` or in a collection and then reference it by FQCN. You also need to configure other settings specific to each plugin. Consult the individual plugin documentation or the Ansible :ref:`configuration ` for more details. @@ -133,7 +133,5 @@ Use ``ansible-doc -t cache `` to see plugin-specific documentation Strategy plugins :ref:`vars_plugins` Vars plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/callback.rst b/docs/docsite/rst/plugins/callback.rst index 76172fc2d3e..41f04ddc873 100644 --- a/docs/docsite/rst/plugins/callback.rst +++ b/docs/docsite/rst/plugins/callback.rst @@ -23,7 +23,7 @@ The :ref:`say ` callback responds with a computer-synthesized spee Enabling callback plugins ------------------------- -You can activate a custom callback by either dropping it into a ``callback_plugins`` directory adjacent to your play, inside a role, or by putting it in one of the callback directory sources configured in :ref:`ansible.cfg `. +You can activate a custom callback, depending on it's ``NEEDS_ENABLED`` property, by either dropping it into one of the callback directory sources configured in :ref:`ansible.cfg ` or in a collection and referencing it in configuration by FQCN. Plugins are loaded in alphanumeric order. For example, a plugin implemented in a file named `1_first.py` would run before a plugin file named `2_second.py`. @@ -110,7 +110,5 @@ Use ``ansible-doc -t callback `` to see plugin-specific documentati Strategy plugins :ref:`vars_plugins` Vars plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/cliconf.rst b/docs/docsite/rst/plugins/cliconf.rst index e175e9a3e99..0d43ff9d4d5 100644 --- a/docs/docsite/rst/plugins/cliconf.rst +++ b/docs/docsite/rst/plugins/cliconf.rst @@ -43,7 +43,5 @@ Use ``ansible-doc -t cliconf `` to see plugin-specific documentatio :ref:`Ansible for Network Automation` An overview of using Ansible to automate networking devices. - `User Mailing List `_ - Have a question? Stop by the Google group! - `irc.libera.chat `_ - #ansible-network IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/connection.rst b/docs/docsite/rst/plugins/connection.rst index dc0c8753102..d7030adbdd6 100644 --- a/docs/docsite/rst/plugins/connection.rst +++ b/docs/docsite/rst/plugins/connection.rst @@ -64,7 +64,5 @@ Use ``ansible-doc -t connection `` to see plugin-specific documenta Lookup plugins :ref:`vars_plugins` Vars plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/docs_fragment.rst b/docs/docsite/rst/plugins/docs_fragment.rst index fc0d923b545..a134780da9b 100644 --- a/docs/docsite/rst/plugins/docs_fragment.rst +++ b/docs/docsite/rst/plugins/docs_fragment.rst @@ -29,7 +29,5 @@ Only collection developers and maintainers use docs fragments. For more informat An introduction to creating Ansible modules :ref:`developing_collections` A guide to creating Ansible collections - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/filter.rst b/docs/docsite/rst/plugins/filter.rst index 2923ce5e6f6..4ec98d33270 100644 --- a/docs/docsite/rst/plugins/filter.rst +++ b/docs/docsite/rst/plugins/filter.rst @@ -57,7 +57,5 @@ You can use ``ansible-doc -t filter -l`` to see the list of available plugins. U Test plugins :ref:`lookup_plugins` Lookup plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/httpapi.rst b/docs/docsite/rst/plugins/httpapi.rst index 09e07677517..4b9657b1bc0 100644 --- a/docs/docsite/rst/plugins/httpapi.rst +++ b/docs/docsite/rst/plugins/httpapi.rst @@ -68,7 +68,5 @@ Use ``ansible-doc -t httpapi `` to see plugin-specific documentatio An overview of using Ansible to automate networking devices. :ref:`Developing network modules` How to develop network modules. - `User Mailing List `_ - Have a question? Stop by the Google group! - `irc.libera.chat `_ - #ansible-network IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/inventory.rst b/docs/docsite/rst/plugins/inventory.rst index 63f46608da0..d01ebc0c279 100644 --- a/docs/docsite/rst/plugins/inventory.rst +++ b/docs/docsite/rst/plugins/inventory.rst @@ -36,8 +36,9 @@ Or, if it is a local plugin, perhaps stored in the path set by :ref:`DEFAULT_INV [inventory] enable_plugins = host_list, script, auto, yaml, ini, toml, my_plugin - + If you use a plugin that supports a YAML configuration source, make sure that the name matches the name provided in the ``plugin`` entry of the inventory source file. +For other plugins you must either save it in one of the directory sources configured in :ref:`ansible.cfg ` and enable it or add to a collection and then reference it by FQCN. .. _using_inventory: @@ -184,7 +185,5 @@ Use ``ansible-doc -t inventory `` to see plugin-specific documentat Lookup plugins :ref:`vars_plugins` Vars plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/lookup.rst b/docs/docsite/rst/plugins/lookup.rst index 4f9cd860953..1bda2954e6b 100644 --- a/docs/docsite/rst/plugins/lookup.rst +++ b/docs/docsite/rst/plugins/lookup.rst @@ -161,7 +161,5 @@ You can use ``ansible-doc -t lookup -l`` to see the list of available plugins. U Jinja2 filter plugins :ref:`test_plugins` Jinja2 test plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/module.rst b/docs/docsite/rst/plugins/module.rst index a2083bc09d1..64f2f60de77 100644 --- a/docs/docsite/rst/plugins/module.rst +++ b/docs/docsite/rst/plugins/module.rst @@ -37,7 +37,5 @@ For information on using modules in ad hoc tasks, see :ref:`intro_adhoc`. For in An introduction to creating Ansible modules :ref:`developing_collections` A guide to creating Ansible collections - `User Mailing List `_ - Have a question? Stop by the Google group! - `irc.libera.chat `_ - #ansible-devel IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/module_util.rst b/docs/docsite/rst/plugins/module_util.rst index c9dc7747e2f..3e5d03cce7c 100644 --- a/docs/docsite/rst/plugins/module_util.rst +++ b/docs/docsite/rst/plugins/module_util.rst @@ -29,7 +29,5 @@ For information on using module utilities, see :ref:`developing_module_utilities An introduction to creating Ansible modules :ref:`developing_collections` A guide to creating Ansible collections - `User Mailing List `_ - Have a question? Stop by the Google group! - `irc.libera.chat `_ - #ansible-devel IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/netconf.rst b/docs/docsite/rst/plugins/netconf.rst index eeba1061faa..7f7581c9591 100644 --- a/docs/docsite/rst/plugins/netconf.rst +++ b/docs/docsite/rst/plugins/netconf.rst @@ -43,7 +43,5 @@ Use ``ansible-doc -t netconf `` to see plugin-specific documentatio :ref:`Ansible for Network Automation` An overview of using Ansible to automate networking devices. - `User Mailing List `_ - Have a question? Stop by the Google group! - `irc.libera.chat `_ - #ansible-network IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/plugins.rst b/docs/docsite/rst/plugins/plugins.rst index 1c1355e081b..317c4aeae01 100644 --- a/docs/docsite/rst/plugins/plugins.rst +++ b/docs/docsite/rst/plugins/plugins.rst @@ -42,7 +42,5 @@ This section covers the various types of plugins that are included with Ansible: Ansible configuration documentation and settings :ref:`command_line_tools` Ansible tools, description and options - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/shell.rst b/docs/docsite/rst/plugins/shell.rst index 96597e76262..97fa6407888 100644 --- a/docs/docsite/rst/plugins/shell.rst +++ b/docs/docsite/rst/plugins/shell.rst @@ -52,7 +52,5 @@ You can use ``ansible-doc -t shell -l`` to see the list of available plugins. Us Test plugins :ref:`lookup_plugins` Lookup plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/strategy.rst b/docs/docsite/rst/plugins/strategy.rst index 3a3ea8a95e6..4c0d6cb9f50 100644 --- a/docs/docsite/rst/plugins/strategy.rst +++ b/docs/docsite/rst/plugins/strategy.rst @@ -80,7 +80,5 @@ Use ``ansible-doc -t strategy `` to see plugin-specific documentati Test plugins :ref:`lookup_plugins` Lookup plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/terminal.rst b/docs/docsite/rst/plugins/terminal.rst index 7bc4c39aa3b..c399c97ca4f 100644 --- a/docs/docsite/rst/plugins/terminal.rst +++ b/docs/docsite/rst/plugins/terminal.rst @@ -36,7 +36,5 @@ Plugins are self-documenting. Each plugin should document its configuration opti An overview of using Ansible to automate networking devices. :ref:`connection_plugins` Connection plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - `irc.libera.chat `_ - #ansible-network IRC chat channel + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/test.rst b/docs/docsite/rst/plugins/test.rst index ee81bdd32ae..49378b3273c 100644 --- a/docs/docsite/rst/plugins/test.rst +++ b/docs/docsite/rst/plugins/test.rst @@ -94,7 +94,5 @@ You can use ``ansible-doc -t test -l`` to see the list of available plugins. Use Using tests :ref:`lookup_plugins` Lookup plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/plugins/vars.rst b/docs/docsite/rst/plugins/vars.rst index e9bd42c3064..1793ba68050 100644 --- a/docs/docsite/rst/plugins/vars.rst +++ b/docs/docsite/rst/plugins/vars.rst @@ -18,7 +18,7 @@ The :ref:`host_group_vars ` plugin shipped with Ansible en Enabling vars plugins --------------------- -You can activate a custom vars plugin by either dropping it into a ``vars_plugins`` directory adjacent to your play, inside a role, or by putting it in one of the directory sources configured in :ref:`ansible.cfg `. +You can activate a custom vars plugin by either dropping it into a ``vars_plugins`` directory adjacent to your play, inside a role, or by putting it in one of the directory sources configured in :ref:`ansible.cfg `. For a vars plugin to run during inventory build you cannot enable it in a play or role as these are not loaded until later. If they are only going to run at task execution, there are no limitations on where they are provided. Most vars plugins are disabled by default. To enable a vars plugin, set ``vars_plugins_enabled`` in the ``defaults`` section of :ref:`ansible.cfg ` or set the ``ANSIBLE_VARS_ENABLED`` environment variable to the list of vars plugins you want to execute. By default, the :ref:`host_group_vars ` plugin shipped with Ansible is enabled. @@ -61,7 +61,5 @@ You can use ``ansible-doc -t vars -l`` to see the list of available vars plugins Cache plugins :ref:`lookup_plugins` Lookup plugins - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/porting_guides/porting_guide_10.rst b/docs/docsite/rst/porting_guides/porting_guide_10.rst index d4cae3313dd..8d7042419e1 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_10.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_10.rst @@ -18,13 +18,40 @@ We suggest you read this page along with the `Ansible 10 Changelog `__ for more details (`https://forum.ansible.com/t/2572 `__). +- The collection ``t_systems_mms.icinga_director`` was renamed to ``telekom_mms.icinga_director``. + For now both collections are included in Ansible. + The content in ``t_systems_mms.icinga_director`` has been replaced by deprecated redirects in Ansible 9.0.0. + The collection will be completely removed from Ansible 11. + Please update your FQCNs from ``t_systems_mms.icinga_director`` to ``telekom_mms.icinga_director``. +- The sensu.sensu_go collection will be removed from Ansible 12 due to violations of the Ansible inclusion requirements. + The collection has \ `unresolved sanity test failures `__. + See `Collections Removal Process for collections not satisfying the collection requirements `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/8380 `__). + +community.general +~~~~~~~~~~~~~~~~~ + +- hipchat - the hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. The module is therefore deprecated and will be removed from community.general 11.0.0 if nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/pull/8919). + +Porting Guide for v10.4.0 +========================= + +Known Issues +------------ + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. +- idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. +- idrac_storage_volume - Issue(290766) - The module will report success instead of showing failure for new virtual creation on the BOSS-N1 controller if a virtual disk is already present on the same controller. +- idrac_support_assist - Issue(308550) - This module fails when the NFS share path contains sub directory. +- ome_diagnostics - Issue(279193) - Export of SupportAssist collection logs to the share location fails on OME version 4.0.0. +- ome_smart_fabric_uplink - Issue(186024) - The module supported by OpenManage Enterprise Modular, however it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, then the existing uplink is modified. + +Breaking Changes +---------------- + +community.mysql +~~~~~~~~~~~~~~~ + +- collection - support of mysqlclient connector is deprecated - use PyMySQL connector instead! We will stop testing against it in collection version 4.0.0 and remove the related code in 5.0.0 (https://github.com/ansible-collections/community.mysql/issues/654). +- mysql_info - The ``users_info`` filter returned variable ``plugin_auth_string`` contains the hashed password and it's misleading, it will be removed from community.mysql 4.0.0. Use the `plugin_hash_string` return value instead (https://github.com/ansible-collections/community.mysql/pull/629). +- mysql_user - the ``user`` alias of the ``name`` argument has been deprecated and will be removed in collection version 5.0.0. Use the ``name`` argument instead. + +Major Changes +------------- + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_secure_boot - This module allows to import the secure boot certificate. +- idrac_support_assist - This module allows to run and export SupportAssist collection logs on iDRAC. + +grafana.grafana +~~~~~~~~~~~~~~~ + +- fix:mimir molecule should use ansible core 2.16 by @GVengelen in https://github.com/grafana/grafana-ansible-collection/pull/254 + +Deprecated Features +------------------- + +amazon.aws +~~~~~~~~~~ + +- iam_role - support for creating and deleting IAM instance profiles using the ``create_instance_profile`` and ``delete_instance_profile`` options has been deprecated and will be removed in a release after 2026-05-01. To manage IAM instance profiles the ``amazon.aws.iam_instance_profile`` module can be used instead (https://github.com/ansible-collections/amazon.aws/pull/2221). + +community.general +~~~~~~~~~~~~~~~~~ + +- MH decorator cause_changes module utils - deprecate parameters ``on_success`` and ``on_failure`` (https://github.com/ansible-collections/community.general/pull/8791). +- pipx - support for versions of the command line tool ``pipx`` older than ``1.7.0`` is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8793). +- pipx_info - support for versions of the command line tool ``pipx`` older than ``1.7.0`` is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8793). + +community.vmware +~~~~~~~~~~~~~~~~ + +- vmware_cluster - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2143). +- vmware_cluster_drs - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2136). +- vmware_cluster_vcls - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2156). + +Porting Guide for v10.3.0 +========================= + +Known Issues +------------ + +community.docker +~~~~~~~~~~~~~~~~ + +- docker_container - when specifying a MAC address for a container's network, and the network is attached after container creation (for example, due to idempotency checks), the MAC address is at least in some cases ignored by the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/933). + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. +- idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. +- idrac_storage_volume - Issue(290766) - The module will report success instead of showing failure for new virtual creation on the BOSS-N1 controller if a virtual disk is already present on the same controller. +- ome_diagnostics - Issue(279193) - Export of SupportAssist collection logs to the share location fails on OME version 4.0.0. +- ome_smart_fabric_uplink - Issue(186024) - The module supported by OpenManage Enterprise Modular, however it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, then the existing uplink is modified. + +Deprecated Features +------------------- + +community.docker +~~~~~~~~~~~~~~~~ + +- The collection deprecates support for all ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.routeros +~~~~~~~~~~~~~~~~~~ + +- The collection deprecates support for all Ansible/ansible-base/ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.sops +~~~~~~~~~~~~~~ + +- The collection deprecates support for all Ansible/ansible-base/ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +Porting Guide for v10.2.0 +========================= Added Collections ----------------- -- community.library_inventory_filtering_v1 (version 1.0.0) +- kubevirt.core (version 1.5.0) +- vmware.vmware (version 1.3.0) Known Issues ------------ @@ -90,6 +263,138 @@ Known Issues dellemc.openmanage ~~~~~~~~~~~~~~~~~~ +- idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. +- idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. +- idrac_storage_volume - Issue(290766) - The module will report success instead of showing failure for new virtual creation on the BOSS-N1 controller if a virtual disk is already present on the same controller. +- ome_diagnostics - Issue(279193) - Export of SupportAssist collection logs to the share location fails on OME version 4.0.0. +- ome_smart_fabric_uplink - Issue(186024) - The module supported by OpenManage Enterprise Modular, however it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, then the existing uplink is modified. + +Major Changes +------------- + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_server_config_profile - This module is enhanced to allow you to export and import custom defaults on iDRAC. +- ome_configuration_compliance_baseline - This module is enhanced to schedule the remediation job and stage the reboot. + +fortinet.fortios +~~~~~~~~~~~~~~~~ + +- Add a sanity_test.yaml file to trigger CI tests in GitHub. +- Support Ansible-core 2.17. +- Support new FOS versions 7.4.4. + +grafana.grafana +~~~~~~~~~~~~~~~ + +- Add a config check before restarting mimir by @panfantastic in https://github.com/grafana/grafana-ansible-collection/pull/198 +- Add support for configuring feature_toggles in grafana role by @LexVar in https://github.com/grafana/grafana-ansible-collection/pull/173 +- Backport post-setup healthcheck from agent to alloy by @v-zhuravlev in https://github.com/grafana/grafana-ansible-collection/pull/213 +- Bump ansible-lint from 24.2.3 to 24.5.0 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/207 +- Bump ansible-lint from 24.5.0 to 24.6.0 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/216 +- Bump braces from 3.0.2 to 3.0.3 in the npm_and_yarn group across 1 directory by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/218 +- Bump pylint from 3.1.0 to 3.1.1 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/200 +- Bump pylint from 3.1.1 to 3.2.2 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/208 +- Bump pylint from 3.2.2 to 3.2.3 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/217 +- Bump pylint from 3.2.3 to 3.2.5 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/234 +- Change from config.river to config.alloy by @cardasac in https://github.com/grafana/grafana-ansible-collection/pull/225 +- Fix Grafana Configuration for Unified and Legacy Alerting Based on Version by @voidquark in https://github.com/grafana/grafana-ansible-collection/pull/215 +- Support adding alloy user to extra groups by @v-zhuravlev in https://github.com/grafana/grafana-ansible-collection/pull/212 +- Updated result.json['message'] to result.json()['message'] by @CPreun in https://github.com/grafana/grafana-ansible-collection/pull/223 + +Deprecated Features +------------------- + +- The ``frr.frr`` collection has been deprecated. + It will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details (`https://forum.ansible.com/t/6243 `__). +- The ``openvswitch.openvswitch`` collection has been deprecated. + It will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details (`https://forum.ansible.com/t/6245 `__). + +Porting Guide for v10.1.0 +========================= + +Added Collections +----------------- + +- ieisystem.inmanage (version 2.0.0) + +Known Issues +------------ + +community.general +~~~~~~~~~~~~~~~~~ + +- homectl - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4691, https://github.com/ansible-collections/community.general/pull/8497). +- udm_user - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4690, https://github.com/ansible-collections/community.general/pull/8497). + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. +- idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. +- idrac_storage_volume - Issue(290766) - The module will report success instead of showing failure for new virtual creation on the BOSS-N1 controller if a virtual disk is already present on the same controller. +- ome_diagnostics - Issue(279193) - Export of SupportAssist collection logs to the share location fails on OME version 4.0.0. +- ome_smart_fabric_uplink - Issue(186024) - The module supported by OpenManage Enterprise Modular, however it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, then the existing uplink is modified. + +Major Changes +------------- + +containers.podman +~~~~~~~~~~~~~~~~~ + +- Add mount and unmount for volumes +- Add multiple subnets for networks +- Add new options for podman_container +- Add new options to pod module +- Add podman search +- Improve idempotency for networking in podman_container +- Redesign idempotency for Podman Pod module + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- Added support to use session ID for authentication of iDRAC, OpenManage Enterprise and OpenManage Enterprise Modular. +- ome_session - This module allows you to create and delete the sessions on OpenManage Enterprise and OpenManage Enterprise Modular. + +Deprecated Features +------------------- + +community.general +~~~~~~~~~~~~~~~~~ + +- CmdRunner module util - setting the value of the ``ignore_none`` parameter within a ``CmdRunner`` context is deprecated and that feature should be removed in community.general 12.0.0 (https://github.com/ansible-collections/community.general/pull/8479). +- git_config - the ``list_all`` option has been deprecated and will be removed in community.general 11.0.0. Use the ``community.general.git_config_info`` module instead (https://github.com/ansible-collections/community.general/pull/8453). +- git_config - using ``state=present`` without providing ``value`` is deprecated and will be disallowed in community.general 11.0.0. Use the ``community.general.git_config_info`` module instead to read a value (https://github.com/ansible-collections/community.general/pull/8453). + +Porting Guide for v10.0.0 +========================= + +Added Collections +----------------- + +- community.library_inventory_filtering_v1 (version 1.0.1) +- kaytus.ksmanage (version 1.2.1) + +Known Issues +------------ + +community.docker +~~~~~~~~~~~~~~~~ + +- Please note that the fix for requests 2.32.0 included in community.docker 3.10.1 only + fixes problems with the *vendored* Docker SDK for Python code. Modules and plugins that + use Docker SDK for Python can still fail due to the SDK currently being incompatible + with requests 2.32.0. + + If you still experience problems with requests 2.32.0, such as error messages like + ``Not supported URL scheme http+docker``, please restrict requests to ``<2.32.0``. + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + - idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. - idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. - idrac_network_attributes - Issue(279049) - If unsupported values are provided for the parameter ``ome_network_attributes``, then this module does not provide a correct error message. @@ -108,17 +413,67 @@ Ansible-core - assert - Nested templating may result in an inability for the conditional to be evaluated. See the porting guide for more information. +amazon.aws +~~~~~~~~~~ + +- amazon.aws collection - Support for ansible-core < 2.15 has been dropped (https://github.com/ansible-collections/amazon.aws/pull/2093). +- iam_role - ``iam_role.assume_role_policy_document`` is no longer converted from CamelCase to snake_case (https://github.com/ansible-collections/amazon.aws/pull/2040). +- iam_role_info - ``iam_role.assume_role_policy_document`` is no longer converted from CamelCase to snake_case (https://github.com/ansible-collections/amazon.aws/pull/2040). +- kms_key - the ``policies`` return value has been renamed to ``key_policies`` the contents has not been changed (https://github.com/ansible-collections/amazon.aws/pull/2040). +- kms_key_info - the ``policies`` return value has been renamed to ``key_policies`` the contents has not been changed (https://github.com/ansible-collections/amazon.aws/pull/2040). +- lambda_event - | ``batch_size`` no longer defaults to 100. According to the boto3 API (https://boto3.amazonaws.com/v1/documentation/api/1.26.78/reference/services/lambda.html#Lambda.Client.create_event_source_mapping), ``batch_size`` defaults to 10 for sqs sources and to 100 for stream sources (https://github.com/ansible-collections/amazon.aws/pull/2025). + cloud.common ~~~~~~~~~~~~ - Bump minimum Python supported version to 3.9. - Remove support for ansible-core < 2.14. +community.aws +~~~~~~~~~~~~~ + +- The community.aws collection has dropped support for ``botocore<1.29.0`` and ``boto3<1.26.0``. Most modules will continue to work with older versions of the AWS SDK, however compatability with older versions of the SDK is not guaranteed and will not be tested. When using older versions of the SDK a warning will be emitted by Ansible (https://github.com/ansible-collections/amazon.aws/pull/1763). +- aws_region_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.aws_region_info``. +- aws_s3_bucket_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.aws_s3_bucket_info``. +- community.aws collection - Support for ansible-core < 2.15 has been dropped (https://github.com/ansible-collections/community.aws/pull/2074). +- community.aws collection - due to the AWS SDKs announcing the end of support for Python less than 3.7 (https://aws.amazon.com/blogs/developer/python-support-policy-updates-for-aws-sdks-and-tools/) support for Python less than 3.7 by this collection wss been deprecated in release 6.0.0 and removed in release 7.0.0. (https://github.com/ansible-collections/amazon.aws/pull/1763). +- iam_access_key - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_access_key``. +- iam_access_key_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_access_key_info``. +- iam_group - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_group`` (https://github.com/ansible-collections/community.aws/pull/1945). +- iam_managed_policy - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_managed_policy`` (https://github.com/ansible-collections/community.aws/pull/1954). +- iam_mfa_device_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_mfa_device_info`` (https://github.com/ansible-collections/community.aws/pull/1953). +- iam_password_policy - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_password_policy``. +- iam_role - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_role`` (https://github.com/ansible-collections/community.aws/pull/1948). +- iam_role_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_role_info`` (https://github.com/ansible-collections/community.aws/pull/1948). +- s3_bucket_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.s3_bucket_info``. +- sts_assume_role - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.sts_assume_role``. + community.ciscosmb ~~~~~~~~~~~~~~~~~~ - in facts of interface 'bandwith' changed to 'bandwidth' +community.dns +~~~~~~~~~~~~~ + +- The default for the ``txt_character_encoding`` options in various modules and plugins changed from ``octal`` to ``decimal`` (https://github.com/ansible-collections/community.dns/pull/196). +- inventory plugins - ``filters`` is now no longer an alias of ``simple_filters``, but a new, different option (https://github.com/ansible-collections/community.dns/pull/196). +- inventory plugins - the ``plugin`` option is now required (https://github.com/ansible-collections/community.dns/pull/196). +- lookup, lookup_as_dict - the default for ``search`` changed from ``false`` (implicit default for community.dns 2.x.y) to ``true`` (https://github.com/ansible-collections/community.dns/issues/200, https://github.com/ansible-collections/community.dns/pull/201). + +community.general +~~~~~~~~~~~~~~~~~ + +- cpanm - the default of the ``mode`` option changed from ``compatibility`` to ``new`` (https://github.com/ansible-collections/community.general/pull/8198). +- django_manage - the module now requires Django >= 4.1 (https://github.com/ansible-collections/community.general/pull/8198). +- django_manage - the module will now fail if ``virtualenv`` is specified but no virtual environment exists at that location (https://github.com/ansible-collections/community.general/pull/8198). +- redfish_command, redfish_config, redfish_info - change the default for ``timeout`` from 10 to 60 (https://github.com/ansible-collections/community.general/pull/8198). + +community.hrobot +~~~~~~~~~~~~~~~~ + +- robot inventory plugin - ``filters`` is now no longer an alias of ``simple_filters``, but a new, different option (https://github.com/ansible-collections/community.hrobot/pull/101). + community.okd ~~~~~~~~~~~~~ @@ -177,6 +532,7 @@ arista.eos - Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now. - This release removes previously deprecated modules and attributes from this collection. Please refer to the **Removed Features** section for details. +- Update the netcommon base version 6.1.0 to support cli_restore plugin. cisco.asa ~~~~~~~~~ @@ -187,6 +543,7 @@ cisco.ios ~~~~~~~~~ - Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now. +- Update the netcommon base version 6.1.0 to support cli_restore plugin. - ios_ntp - Remove deprecated ntp legacy module cisco.iosxr @@ -194,12 +551,19 @@ cisco.iosxr - Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now. - This release removes previously deprecated module and attributes from this collection. Please refer to the **Removed Features** section for details. +- Update the netcommon base version to support cli_restore plugin. cisco.nxos ~~~~~~~~~~ - Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now. - This release removes four previously deprecated modules from this collection. Please refer to the **Removed Features** section for details. +- Updated the minimum required ansible.netcommon version to 6.1.0 to support the cli_restore module. + +community.dns +~~~~~~~~~~~~~ + +- The ``community.dns`` collection now depends on the ``community.library_inventory_filtering_v1`` collection. This utility collection provides host filtering functionality for inventory plugins. If you use the Ansible community package, both collections are included and you do not have to do anything special. If you install the collection with ``ansible-galaxy collection install``, it will be installed automatically. If you install the collection by copying the files of the collection to a place where ansible-core can find it, for example by cloning the git repository, you need to make sure that you also have to install the dependency if you are using the inventory plugins (https://github.com/ansible-collections/community.dns/pull/196). community.docker ~~~~~~~~~~~~~~~~ @@ -211,11 +575,21 @@ community.hashi_vault - requirements - the ``requests`` package which is required by ``hvac`` now has a more restrictive range for this collection in certain use cases due to breaking security changes in ``ansible-core`` that were backported (https://github.com/ansible-collections/community.hashi_vault/pull/416). +community.hrobot +~~~~~~~~~~~~~~~~ + +- The ``community.hrobot`` collection now depends on the ``community.library_inventory_filtering_v1`` collection. This utility collection provides host filtering functionality for inventory plugins. If you use the Ansible community package, both collections are included and you do not have to do anything special. If you install the collection with ``ansible-galaxy collection install``, it will be installed automatically. If you install the collection by copying the files of the collection to a place where ansible-core can find it, for example by cloning the git repository, you need to make sure that you also have to install the dependency if you are using the inventory plugin (https://github.com/ansible-collections/community.hrobot/pull/101). + community.mysql ~~~~~~~~~~~~~~~ - Collection version 2.*.* is EOL, no more bugfixes will be backported. Please consider upgrading to the latest version. +containers.podman +~~~~~~~~~~~~~~~~~ + +- Add quadlet support for Podman modules + dellemc.openmanage ~~~~~~~~~~~~~~~~~~ @@ -225,6 +599,7 @@ dellemc.openmanage - idrac_diagnostics - The module is introduced to run and export diagnostics on iDRAC. - idrac_gather_facts - This role is enhanced to support secure boot. - idrac_license - The module is introduced to configure iDRAC licenses. +- idrac_session - This module allows you to create and delete the sessions on iDRAC. - idrac_user - This role is introduced to manage local users of iDRAC. dellemc.unity @@ -248,7 +623,13 @@ fortinet.fortios grafana.grafana ~~~~~~~~~~~~~~~ +- Add Grafana Loki role by @voidquark in https://github.com/grafana/grafana-ansible-collection/pull/188 +- Add Grafana Mimir role by @GVengelen in https://github.com/grafana/grafana-ansible-collection/pull/183 +- Add a new config part to configure KeyCloak based auth by @he0s in https://github.com/grafana/grafana-ansible-collection/pull/191 +- Add an Ansible role for Grafana Alloy by @ishanjainn in https://github.com/grafana/grafana-ansible-collection/pull/169 - Add an Ansible role for OpenTelemetry Collector by @ishanjainn in https://github.com/grafana/grafana-ansible-collection/pull/138 +- Add promtail role by @voidquark in https://github.com/grafana/grafana-ansible-collection/pull/197 +- Bump ansible-lint from 24.2.2 to 24.2.3 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/195 ibm.qradar ~~~~~~~~~~ @@ -266,6 +647,7 @@ junipernetworks.junos - Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now. - This release removes previously deprecated modules from this collection. Please refer to the **Removed Features** section for details. +- Update the netcommon base version 6.1.0 to support cli_restore plugin. splunk.es ~~~~~~~~~ @@ -288,15 +670,25 @@ Removed Collections Removed Features ---------------- -- The ``gluster.gluster`` collection was considered unmaintained and removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/225). Users can still install this collection with ``ansible-galaxy collection install gluster.gluster``. -- The ``hpe.nimble`` collection was considered unmaintained and removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/254). Users can still install this collection with ``ansible-galaxy collection install hpe.nimble``. -- The ``netapp.aws`` collection was considered unmaintained and removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/223). Users can still install this collection with ``ansible-galaxy collection install netapp.aws``. -- The ``netapp.azure`` collection was considered unmaintained and removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/234). Users can still install this collection with ``ansible-galaxy collection install netapp.azure``. -- The ``netapp.elementsw`` collection was considered unmaintained and removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/235). Users can still install this collection with ``ansible-galaxy collection install netapp.elementsw``. -- The ``netapp.um_info`` collection was considered unmaintained and removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/244). Users can still install this collection with ``ansible-galaxy collection install netapp.um_info``. -- The deprecated ``community.azure`` collection has been removed. There is a successor collection ``azure.azcollection`` in the community package which should cover the same functionality. -- The deprecated ``community.sap`` collection has been removed from Ansible 10 (https://github.com/ansible-community/community-topics/issues/247). There is a successor collection ``community.sap_libs`` in the community package which should cover the same functionality. -- The deprecated ``purestorage.fusion`` collection has been removed (https://forum.ansible.com/t/3712). +- The ``community.azure`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/263 `__). + Users can still install this collection with ``ansible-galaxy collection install community.azure``. +- The ``gluster.gluster`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/225 `__). + Users can still install this collection with ``ansible-galaxy collection install gluster.gluster``. +- The ``hpe.nimble`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/254 `__). + Users can still install this collection with ``ansible-galaxy collection install hpe.nimble``. +- The ``netapp.aws`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/223 `__). + Users can still install this collection with ``ansible-galaxy collection install netapp.aws``. +- The ``netapp.azure`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/234 `__). + Users can still install this collection with ``ansible-galaxy collection install netapp.azure``. +- The ``netapp.elementsw`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/235 `__). + Users can still install this collection with ``ansible-galaxy collection install netapp.elementsw``. +- The ``netapp.um_info`` collection was considered unmaintained and has been removed from Ansible 10 (`https://github.com/ansible-community/community-topics/issues/244 `__). + Users can still install this collection with ``ansible-galaxy collection install netapp.um_info``. +- The collection ``community.sap`` has been completely removed from Ansible. + It has been renamed to ``community.sap_libs``. + The collection will be completely removed from Ansible eventually. + Please update your FQCNs from ``community.sap`` to ``community.sap_libs``. +- The deprecated ``purestorage.fusion`` collection has been removed (`https://forum.ansible.com/t/3712 `__). Ansible-core ~~~~~~~~~~~~ @@ -305,8 +697,16 @@ Ansible-core - Remove deprecated JINJA2_NATIVE_WARNING environment variable (https://github.com/ansible/ansible/issues/81714) - Remove deprecated ``scp_if_ssh`` from ssh connection plugin (https://github.com/ansible/ansible/issues/81715). - Remove deprecated crypt support from ansible.utils.encrypt (https://github.com/ansible/ansible/issues/81717) +- Removed Python 2.7 and Python 3.6 as a supported remote version. Python 3.7+ is now required for target execution. - With the removal of Python 2 support, the yum module and yum action plugin are removed and redirected to ``dnf``. +amazon.aws +~~~~~~~~~~ + +- iam_role - the ``iam_role.assume_role_policy_document_raw`` return value has been deprecated. ``iam_role.assume_role_policy_document`` now returns the same format as ``iam_role.assume_role_policy_document_raw`` (https://github.com/ansible-collections/amazon.aws/pull/2040). +- iam_role_info - the ``iam_role.assume_role_policy_document_raw`` return value has been deprecated. ``iam_role.assume_role_policy_document`` now returns the same format as ``iam_role.assume_role_policy_document_raw`` (https://github.com/ansible-collections/amazon.aws/pull/2040). +- module_utils.policy - the previously deprecated ``sort_json_policy_dict()`` function has been removed, consider using ``compare_policies()`` instead (https://github.com/ansible-collections/amazon.aws/pull/2052). + arista.eos ~~~~~~~~~~ @@ -333,6 +733,39 @@ cisco.nxos - The nxos_ntp_auth module has been removed with this release. - The nxos_ntp_options module has been removed with this release. +community.dns +~~~~~~~~~~~~~ + +- The collection no longer supports Ansible, ansible-base, and ansible-core releases that are currently End of Life at the time of the 3.0.0 release. This means that Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, and ansible-core 2.13 are no longer supported. The collection might still work with these versions, but it can stop working at any moment without advance notice, and this will not be considered a bug (https://github.com/ansible-collections/community.dns/pull/196). +- hetzner_dns_record_set, hetzner_dns_record - the deprecated alias ``name`` of the prefix option was removed (https://github.com/ansible-collections/community.dns/pull/196). +- hosttech_dns_records - the redirect to the ``hosttech_dns_record_sets`` module has been removed (https://github.com/ansible-collections/community.dns/pull/196). + +community.general +~~~~~~~~~~~~~~~~~ + +- The deprecated redirects for internal module names have been removed. These internal redirects were extra-long FQCNs like ``community.general.packaging.os.apt_rpm`` that redirect to the short FQCN ``community.general.apt_rpm``. They were originally needed to implement flatmapping; as various tooling started to recommend users to use the long names flatmapping was removed from the collection and redirects were added for users who already followed these incorrect recommendations (https://github.com/ansible-collections/community.general/pull/7835). +- ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211`` options have been removed. They no longer had any effect (https://github.com/ansible-collections/community.general/pull/8198). +- cloudflare_dns - remove support for SPF records. These are no longer supported by CloudFlare (https://github.com/ansible-collections/community.general/pull/7782). +- django_manage - support for the ``command`` values ``cleanup``, ``syncdb``, and ``validate`` were removed. Use ``clearsessions``, ``migrate``, and ``check`` instead, respectively (https://github.com/ansible-collections/community.general/pull/8198). +- flowdock - this module relied on HTTPS APIs that do not exist anymore and was thus removed (https://github.com/ansible-collections/community.general/pull/8198). +- mh.mixins.deps module utils - the ``DependencyMixin`` has been removed. Use the ``deps`` module utils instead (https://github.com/ansible-collections/community.general/pull/8198). +- proxmox - the ``proxmox_default_behavior`` option has been removed (https://github.com/ansible-collections/community.general/pull/8198). +- rax* modules, rax module utils, rax docs fragment - the Rackspace modules relied on the deprecated package ``pyrax`` and were thus removed (https://github.com/ansible-collections/community.general/pull/8198). +- redhat module utils - the classes ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` have been removed (https://github.com/ansible-collections/community.general/pull/8198). +- redhat_subscription - the alias ``autosubscribe`` of the ``auto_attach`` option was removed (https://github.com/ansible-collections/community.general/pull/8198). +- stackdriver - this module relied on HTTPS APIs that do not exist anymore and was thus removed (https://github.com/ansible-collections/community.general/pull/8198). +- webfaction_* modules - these modules relied on HTTPS APIs that do not exist anymore and were thus removed (https://github.com/ansible-collections/community.general/pull/8198). + +community.grafana +~~~~~~~~~~~~~~~~~ + +- removed deprecated `message` argument in `grafana_dashboard` + +community.hrobot +~~~~~~~~~~~~~~~~ + +- The collection no longer supports Ansible, ansible-base, and ansible-core releases that are currently End of Life at the time of the 2.0.0 release. This means that Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, and ansible-core 2.13 are no longer supported. The collection might still work with these versions, but it can stop working at any moment without advance notice, and this will not be considered a bug (https://github.com/ansible-collections/community.hrobot/pull/101). + junipernetworks.junos ~~~~~~~~~~~~~~~~~~~~~ @@ -341,8 +774,10 @@ junipernetworks.junos Deprecated Features ------------------- -- The ``inspur.sm`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. See `the removal process for details on how this works `__ (https://forum.ansible.com/t/2854). -- The ``netapp.storagegrid`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. See `the removal process for details on how this works `__ (https://forum.ansible.com/t/2811). +- The ``inspur.sm`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/2854 `__). +- The ``netapp.storagegrid`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/2811 `__). Ansible-core ~~~~~~~~~~~~ @@ -356,11 +791,30 @@ Ansible-core amazon.aws ~~~~~~~~~~ +- aws_ec2 inventory plugin - removal of the previously deprecated ``include_extra_api_calls`` option has been assigned to release 9.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2040). +- cloudformation - the ``template`` parameter has been deprecated and will be removed in a release after 2026-05-01. The ``template_body`` parameter can be used in conjungtion with the lookup plugin (https://github.com/ansible-collections/amazon.aws/pull/2048). +- iam_policy - removal of the previously deprecated ``policies`` return key has been assigned to release 9.0.0. Use the ``policy_names`` return key instead (https://github.com/ansible-collections/amazon.aws/pull/2040). - iam_role_info - in a release after 2026-05-01 paths must begin and end with ``/`` (https://github.com/ansible-collections/amazon.aws/pull/1998). +- module_utils.botocore - the ``boto3`` parameter for ``get_aws_connection_info()`` will be removed in a release after 2025-05-01. The ``boto3`` parameter has been ignored since release 4.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2047). +- module_utils.botocore - the ``boto3`` parameter for ``get_aws_region()`` will be removed in a release after 2025-05-01. The ``boto3`` parameter has been ignored since release 4.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2047). +- module_utils.ec2 - the ``boto3`` parameter for ``get_ec2_security_group_ids_from_names()`` will be removed in a release after 2025-05-01. The ``boto3`` parameter has been ignored since release 4.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2047). +- rds_param_group - the ``rds_param_group`` module has been renamed to ``rds_instance_param_group``. The usage of the module has not changed. The rds_param_group alias will be removed in version 10.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2058). + +community.aws +~~~~~~~~~~~~~ + +- aws_glue_connection - updated the deprecation for removal of the ``connection_parameters`` return key from ``after 2024-06-01`` to release version ``9.0.0``, it is being replaced by the ``raw_connection_parameters`` key (https://github.com/ansible-collections/community.aws/pull/518). +- ecs_cluster - updated the deprecation for updated default of ``purge_capacity_providers``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_capacity_providers=False`` (https://github.com/ansible-collections/community.aws/pull/1640). +- ecs_service - updated the deprecation for updated default of ``purge_placement_constraints``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_placement_constraints=False`` (https://github.com/ansible-collections/community.aws/pull/1716). +- ecs_service - updated the deprecation for updated default of ``purge_placement_strategy``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_placement_strategy=False`` (https://github.com/ansible-collections/community.aws/pull/1716). community.crypto ~~~~~~~~~~~~~~~~ +- acme documentation fragment - the default ``community.crypto.acme[.documentation]`` docs fragment is deprecated and will be removed from community.crypto 3.0.0. Replace it with both the new ``community.crypto.acme.basic`` and ``community.crypto.acme.account`` fragments (https://github.com/ansible-collections/community.crypto/pull/735). +- acme.backends module utils - from community.crypto on, all implementations of ``CryptoBackend`` must override ``get_ordered_csr_identifiers()``. The current default implementation, which simply sorts the result of ``get_csr_identifiers()``, will then be removed (https://github.com/ansible-collections/community.crypto/pull/725). +- acme.backends module utils - the ``get_cert_information()`` method for a ACME crypto backend must be implemented from community.crypto 3.0.0 on (https://github.com/ansible-collections/community.crypto/pull/736). +- crypto.module_backends.common module utils - the ``crypto.module_backends.common`` module utils is deprecated and will be removed from community.crypto 3.0.0. Use the improved ``argspec`` module util instead (https://github.com/ansible-collections/community.crypto/pull/749). - openssl_csr_pipe, openssl_privatekey_pipe, x509_certificate_pipe - the current behavior of check mode is deprecated and will change in community.crypto 3.0.0. The current behavior is similar to the modules without ``_pipe``: if the object needs to be (re-)generated, only the ``changed`` status is set, but the object is not updated. From community.crypto 3.0.0 on, the modules will ignore check mode and always act as if check mode is not active. This behavior can already achieved now by adding ``check_mode: false`` to the task. If you think this breaks your use-case of this module, please `create an issue in the community.crypto repository `__ (https://github.com/ansible-collections/community.crypto/issues/712, https://github.com/ansible-collections/community.crypto/pull/714). community.dns @@ -371,12 +825,28 @@ community.dns community.docker ~~~~~~~~~~~~~~~~ +- docker_compose - the Docker Compose v1 module is deprecated and will be removed from community.docker 4.0.0. Please migrate to the ``community.docker.docker_compose_v2`` module, which works with Docker Compose v2 (https://github.com/ansible-collections/community.docker/issues/823, https://github.com/ansible-collections/community.docker/pull/833). - docker_container - the default ``ignore`` for the ``image_name_mismatch`` parameter has been deprecated and will switch to ``recreate`` in community.docker 4.0.0. A deprecation warning will be printed in situations where the default value is used and where a behavior would change once the default changes (https://github.com/ansible-collections/community.docker/pull/703). +- various modules and plugins - the ``ssl_version`` option has been deprecated and will be removed from community.docker 4.0.0. It has already been removed from Docker SDK for Python 7.0.0, and was only necessary in the past to work around SSL/TLS issues (https://github.com/ansible-collections/community.docker/pull/853). community.general ~~~~~~~~~~~~~~~~~ +- MH DependencyCtxMgr module_utils - deprecate ``module_utils.mh.mixin.deps.DependencyCtxMgr`` in favour of ``module_utils.deps`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.AnsibleModule`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.DependencyCtxMgr`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.StateMixin`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarDict,`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarMeta`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarsMixin`` (https://github.com/ansible-collections/community.general/pull/8280). +- ModuleHelper module_utils - deprecate use of ``VarsMixin`` in favor of using the ``VardDict`` module_utils (https://github.com/ansible-collections/community.general/pull/8226). +- ModuleHelper vars module_utils - bump deprecation of ``VarMeta``, ``VarDict`` and ``VarsMixin`` to version 11.0.0 (https://github.com/ansible-collections/community.general/pull/8226). +- apt_rpm - the behavior of ``state=present`` and ``state=installed`` is deprecated and will change in community.general 11.0.0. Right now the module will upgrade a package to the latest version if one of these two states is used. You should explicitly use ``state=latest`` if you want this behavior, and switch to ``state=present_not_latest`` if you do not want to upgrade the package if it is already installed. In community.general 11.0.0 the behavior of ``state=present`` and ``state=installed`` will change to that of ``state=present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8285). - consul_acl - the module has been deprecated and will be removed in community.general 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901). +- django_manage - the ``ack_venv_creation_deprecation`` option has no more effect and will be removed from community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8198). +- gitlab modules - the basic auth method on GitLab API have been deprecated and will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/8383). +- hipchat callback plugin - the hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. The callback plugin is therefore deprecated and will be removed from community.general 10.0.0 if nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/issues/8184, https://github.com/ansible-collections/community.general/pull/8189). +- irc - the defaults ``false`` for ``use_tls`` and ``validate_certs`` have been deprecated and will change to ``true`` in community.general 10.0.0 to improve security. You can already improve security now by explicitly setting them to ``true``. Specifying values now disables the deprecation warning (https://github.com/ansible-collections/community.general/pull/7578). community.hrobot ~~~~~~~~~~~~~~~~ @@ -388,6 +858,11 @@ community.okd - openshift - the ``openshift`` inventory plugin has been deprecated and will be removed in release 4.0.0 (https://github.com/ansible-collections/kubernetes.core/issues/31). +community.vmware +~~~~~~~~~~~~~~~~ + +- vmware_guest_tools_info - `vm_tools_install_status` will be removed from next major version (5.0.0) of the collection since the API call that provides this information has been deprecated by VMware. Use `vm_tools_running_status` / `vm_tools_version_status` instead (https://github.com/ansible-collections/community.vmware/issues/2033). + dellemc.openmanage ~~~~~~~~~~~~~~~~~~ diff --git a/docs/docsite/rst/porting_guides/porting_guide_11.rst b/docs/docsite/rst/porting_guides/porting_guide_11.rst new file mode 100644 index 00000000000..edcfaef0946 --- /dev/null +++ b/docs/docsite/rst/porting_guides/porting_guide_11.rst @@ -0,0 +1,444 @@ +.. + THIS DOCUMENT IS AUTOMATICALLY GENERATED BY ANTSIBULL! PLEASE DO NOT EDIT MANUALLY! (YOU PROBABLY WANT TO EDIT porting_guide_core_2.18.rst) + +.. _porting_11_guide: + +======================== +Ansible 11 Porting Guide +======================== + +.. contents:: + :depth: 2 + + +Ansible 11 is based on Ansible-core 2.18. + +We suggest you read this page along with the `Ansible 11 Changelog `_ to understand what updates you may need to make. + +Porting Guide for v11.0.0a2 +=========================== + +Known Issues +------------ + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. +- idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. +- idrac_storage_volume - Issue(290766) - The module will report success instead of showing failure for new virtual creation on the BOSS-N1 controller if a virtual disk is already present on the same controller. +- idrac_support_assist - Issue(308550) - This module fails when the NFS share path contains sub directory. +- ome_diagnostics - Issue(279193) - Export of SupportAssist collection logs to the share location fails on OME version 4.0.0. +- ome_smart_fabric_uplink - Issue(186024) - The module supported by OpenManage Enterprise Modular, however it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, then the existing uplink is modified. + +Breaking Changes +---------------- + +cloud.common +~~~~~~~~~~~~ + +- cloud.common collection - Support for ansible-core < 2.15 has been dropped (https://github.com/ansible-collections/cloud.common/pull/145/files). + +Major Changes +------------- + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_secure_boot - This module allows to Configure attributes, import, or export secure boot certificate, and reset keys. +- idrac_system_erase - This module allows to Erase system and storage components of the server on iDRAC. + +fortinet.fortios +~~~~~~~~~~~~~~~~ + +- Improve the logic for SET function to send GET request first then PUT or POST +- Mantis +- Support new FOS versions 7.6.0. + +ieisystem.inmanage +~~~~~~~~~~~~~~~~~~ + +- Add new modules system_lock_mode_info, edit_system_lock_mode(https://github.com/ieisystem/ieisystem.inmanage/pull/24). + +kaytus.ksmanage +~~~~~~~~~~~~~~~ + +- Add new modules system_lock_mode_info, edit_system_lock_mode(https://github.com/ieisystem/kaytus.ksmanage/pull/27). + +Removed Collections +------------------- + +- ngine_io.exoscale (previously included version: 1.1.0) + +Removed Features +---------------- + +- The deprecated ``ngine_io.exoscale`` collection has been removed (`https://forum.ansible.com/t/2572 `__). + +Deprecated Features +------------------- + +- The sensu.sensu_go collection will be removed from Ansible 12 due to violations of the Ansible inclusion requirements. + The collection has \ `unresolved sanity test failures `__. + See `Collections Removal Process for collections not satisfying the collection requirements `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/8380 `__). + +community.general +~~~~~~~~~~~~~~~~~ + +- hipchat - the hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. The module is therefore deprecated and will be removed from community.general 11.0.0 if nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/pull/8919). + +community.network +~~~~~~~~~~~~~~~~~ + +- This collection and all content in it is unmaintained and deprecated (https://forum.ansible.com/t/8030). If you are interested in maintaining parts of the collection, please copy them to your own repository, and tell others about in the Forum discussion. See the `collection creator path `__ for details. + +Porting Guide for v11.0.0a1 +=========================== + +Added Collections +----------------- + +- ieisystem.inmanage (version 2.0.0) +- kubevirt.core (version 2.1.0) +- vmware.vmware (version 1.5.0) + +Known Issues +------------ + +Ansible-core +~~~~~~~~~~~~ + +- ansible-test - When using ansible-test containers with Podman on a Ubuntu 24.04 host, ansible-test must be run as a non-root user to avoid permission issues caused by AppArmor. +- ansible-test - When using the Fedora 40 container with Podman on a Ubuntu 24.04 host, the ``unix-chkpwd`` AppArmor profile must be disabled on the host to allow SSH connections to the container. + +ansible.netcommon +~~~~~~~~~~~~~~~~~ + +- libssh - net_put and net_get fail when the destination file intended to be fetched is not present. + +community.docker +~~~~~~~~~~~~~~~~ + +- docker_container - when specifying a MAC address for a container's network, and the network is attached after container creation (for example, due to idempotency checks), the MAC address is at least in some cases ignored by the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/933). + +community.general +~~~~~~~~~~~~~~~~~ + +- homectl - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4691, https://github.com/ansible-collections/community.general/pull/8497). +- udm_user - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4690, https://github.com/ansible-collections/community.general/pull/8497). + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- idrac_diagnostics - Issue(285322) - This module doesn't support export of diagnostics file to HTTP and HTTPS share via SOCKS proxy. +- idrac_firmware - Issue(279282) - This module does not support firmware update using HTTP, HTTPS, and FTP shares with authentication on iDRAC8. +- idrac_storage_volume - Issue(290766) - The module will report success instead of showing failure for new virtual creation on the BOSS-N1 controller if a virtual disk is already present on the same controller. +- idrac_support_assist - Issue(308550) - This module fails when the NFS share path contains sub directory. +- ome_diagnostics - Issue(279193) - Export of SupportAssist collection logs to the share location fails on OME version 4.0.0. +- ome_smart_fabric_uplink - Issue(186024) - The module supported by OpenManage Enterprise Modular, however it does not allow the creation of multiple uplinks of the same name. If an uplink is created using the same name as an existing uplink, then the existing uplink is modified. + +Breaking Changes +---------------- + +Ansible-core +~~~~~~~~~~~~ + +- Stopped wrapping all commands sent over SSH on a Windows target with a ``powershell.exe`` executable. This results in one less process being started on each command for Windows to improve efficiency, simplify the code, and make ``raw`` an actual raw command run with the default shell configured on the Windows sshd settings. This should have no affect on most tasks except for ``raw`` which now is not guaranteed to always be running in a PowerShell shell and from having the console output codepage set to UTF-8. To avoid this issue either swap to using ``ansible.windows.win_command``, ``ansible.windows.win_shell``, ``ansible.windows.win_powershell`` or manually wrap the raw command with the shell commands needed to set the output console encoding. +- assert - Nested templating may result in an inability for the conditional to be evaluated. See the porting guide for more information. +- persistent connection plugins - The ``ANSIBLE_CONNECTION_PATH`` config option no longer has any effect. + +community.mysql +~~~~~~~~~~~~~~~ + +- collection - support of mysqlclient connector is deprecated - use PyMySQL connector instead! We will stop testing against it in collection version 4.0.0 and remove the related code in 5.0.0 (https://github.com/ansible-collections/community.mysql/issues/654). +- mysql_info - The ``users_info`` filter returned variable ``plugin_auth_string`` contains the hashed password and it's misleading, it will be removed from community.mysql 4.0.0. Use the `plugin_hash_string` return value instead (https://github.com/ansible-collections/community.mysql/pull/629). +- mysql_user - the ``user`` alias of the ``name`` argument has been deprecated and will be removed in collection version 5.0.0. Use the ``name`` argument instead. + +community.vmware +~~~~~~~~~~~~~~~~ + +- Adding a dependency on the ``vmware.vmware`` collection (https://github.com/ansible-collections/community.vmware/pull/2159). +- Depending on ``vmware-vcenter`` and ``vmware-vapi-common-client`` instead of ``https://github.com/vmware/vsphere-automation-sdk-python.git`` (https://github.com/ansible-collections/community.vmware/pull/2163). +- Dropping support for pyVmomi < 8.0.3.0.1 (https://github.com/ansible-collections/community.vmware/pull/2163). +- Module utils - Removed ``vmware.run_command_in_guest()`` (https://github.com/ansible-collections/community.vmware/pull/2175). +- Removed support for ansible-core version < 2.17.0. +- vmware_dvs_portgroup - Removed ``security_override`` alias for ``mac_management_override`` and support for ``securityPolicyOverrideAllowed`` which has been deprected in the vSphere API (https://github.com/ansible-collections/community.vmware/issues/1998). +- vmware_dvs_portgroup_info - Removed ``security_override`` because it's deprecated in the vSphere API (https://github.com/ansible-collections/community.vmware/issues/1998). +- vmware_guest_tools_info - Removed deprecated ``vm_tools_install_status`` from the result (https://github.com/ansible-collections/community.vmware/issues/2078). + +community.zabbix +~~~~~~~~~~~~~~~~ + +- All Roles - Remove support for Centos 7 +- All Roles - Remove support for Python2 +- All Roles - Removed support for Debian 10. +- All Roles - Removed support for Ubuntu 18.08 (Bionic) +- Remove support for Ansible < 2.15 and Python < 3.9 +- Remove support for Zabbix 6.2 +- Removed support for Zabbix 6.2 +- zabbix_agent role - Remove support for `zabbix_agent_zabbix_alias`. +- zabbix_agent role - Remove support for `zabbix_get_package` variable. +- zabbix_agent role - Remove support for `zabbix_sender_package` variable. +- zabbix_agent role - Remove support for all `zabbix_agent2_*` variables. + +hetzner.hcloud +~~~~~~~~~~~~~~ + +- Drop support for ansible-core 2.14. + +kubernetes.core +~~~~~~~~~~~~~~~ + +- Remove support for ``ansible-core<2.15`` (https://github.com/ansible-collections/kubernetes.core/pull/737). + +vmware.vmware_rest +~~~~~~~~~~~~~~~~~~ + +- Removing any support for ansible-core <=2.14 + +Major Changes +------------- + +ansible.netcommon +~~~~~~~~~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +ansible.posix +~~~~~~~~~~~~~ + +- Dropping support for Ansible 2.9, ansible-core 2.15 will be minimum required version for this release + +arista.eos +~~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0` due to the end-of-life status of previous `ansible-core` versions. + +check_point.mgmt +~~~~~~~~~~~~~~~~ + +- New R82 Resource Modules +- Support relative positioning for sections + +cisco.asa +~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +cisco.ios +~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +cisco.iosxr +~~~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +cisco.nxos +~~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +community.vmware +~~~~~~~~~~~~~~~~ + +- vmware_guest_tools_upgrade - Subsitute the deprecated ``guest.toolsStatus`` (https://github.com/ansible-collections/community.vmware/pull/2174). +- vmware_vm_shell - Subsitute the deprecated ``guest.toolsStatus`` (https://github.com/ansible-collections/community.vmware/pull/2174). + +community.zabbix +~~~~~~~~~~~~~~~~ + +- All Roles - Add support for openSUSE Leap 15 and SLES 15. +- All Roles - Separate installation of Zabbix repo from all other roles and link them together. + +containers.podman +~~~~~~~~~~~~~~~~~ + +- Add mount and unmount for volumes +- Add multiple subnets for networks +- Add new options for podman_container +- Add new options to pod module +- Add podman search +- Improve idempotency for networking in podman_container +- Redesign idempotency for Podman Pod module + +dellemc.openmanage +~~~~~~~~~~~~~~~~~~ + +- Added support to use session ID for authentication of iDRAC, OpenManage Enterprise and OpenManage Enterprise Modular. +- idrac_secure_boot - This module allows to import the secure boot certificate. +- idrac_server_config_profile - This module is enhanced to allow you to export and import custom defaults on iDRAC. +- idrac_support_assist - This module allows to run and export SupportAssist collection logs on iDRAC. +- ome_configuration_compliance_baseline - This module is enhanced to schedule the remediation job and stage the reboot. +- ome_session - This module allows you to create and delete the sessions on OpenManage Enterprise and OpenManage Enterprise Modular. + +fortinet.fortios +~~~~~~~~~~~~~~~~ + +- Add a sanity_test.yaml file to trigger CI tests in GitHub. +- Support Ansible-core 2.17. +- Support new FOS versions 7.4.4. + +grafana.grafana +~~~~~~~~~~~~~~~ + +- Add a config check before restarting mimir by @panfantastic in https://github.com/grafana/grafana-ansible-collection/pull/198 +- Add support for configuring feature_toggles in grafana role by @LexVar in https://github.com/grafana/grafana-ansible-collection/pull/173 +- Backport post-setup healthcheck from agent to alloy by @v-zhuravlev in https://github.com/grafana/grafana-ansible-collection/pull/213 +- Bump ansible-lint from 24.2.3 to 24.5.0 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/207 +- Bump ansible-lint from 24.5.0 to 24.6.0 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/216 +- Bump braces from 3.0.2 to 3.0.3 in the npm_and_yarn group across 1 directory by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/218 +- Bump pylint from 3.1.0 to 3.1.1 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/200 +- Bump pylint from 3.1.1 to 3.2.2 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/208 +- Bump pylint from 3.2.2 to 3.2.3 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/217 +- Bump pylint from 3.2.3 to 3.2.5 by @dependabot in https://github.com/grafana/grafana-ansible-collection/pull/234 +- Change from config.river to config.alloy by @cardasac in https://github.com/grafana/grafana-ansible-collection/pull/225 +- Fix Grafana Configuration for Unified and Legacy Alerting Based on Version by @voidquark in https://github.com/grafana/grafana-ansible-collection/pull/215 +- Support adding alloy user to extra groups by @v-zhuravlev in https://github.com/grafana/grafana-ansible-collection/pull/212 +- Updated result.json['message'] to result.json()['message'] by @CPreun in https://github.com/grafana/grafana-ansible-collection/pull/223 +- fix:mimir molecule should use ansible core 2.16 by @GVengelen in https://github.com/grafana/grafana-ansible-collection/pull/254 + +ibm.qradar +~~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +junipernetworks.junos +~~~~~~~~~~~~~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +splunk.es +~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +vyos.vyos +~~~~~~~~~ + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +Removed Collections +------------------- + +- frr.frr (previously included version: 2.0.2) +- inspur.sm (previously included version: 2.3.0) +- netapp.storagegrid (previously included version: 21.12.0) +- openvswitch.openvswitch (previously included version: 2.1.1) +- t_systems_mms.icinga_director (previously included version: 2.0.1) + +Removed Features +---------------- + +- The ``inspur.sm`` collection was considered unmaintained and has been removed from Ansible 11 (`https://forum.ansible.com/t/2854 `__). + Users can still install this collection with ``ansible-galaxy collection install inspur.sm``. +- The ``netapp.storagegrid`` collection was considered unmaintained and has been removed from Ansible 11 (`https://forum.ansible.com/t/2811 `__). + Users can still install this collection with ``ansible-galaxy collection install netapp.storagegrid``. +- The collection ``t_systems_mms.icinga_director`` has been completely removed from Ansible. + It has been renamed to ``telekom_mms.icinga_director``. + ``t_systems_mms.icinga_director`` has been replaced by deprecated redirects to ``telekom_mms.icinga_director`` in Ansible 9.0.0. + Please update your FQCNs from ``t_systems_mms.icinga_director`` to ``telekom_mms.icinga_director``. +- The deprecated ``frr.frr`` collection has been removed (`https://forum.ansible.com/t/6243 `__). +- The deprecated ``openvswitch.openvswitch`` collection has been removed (`https://forum.ansible.com/t/6245 `__). + +Ansible-core +~~~~~~~~~~~~ + +- Play - removed deprecated ``ROLE_CACHE`` property in favor of ``role_cache``. +- Remove deprecated `VariableManager._get_delegated_vars` method (https://github.com/ansible/ansible/issues/82950) +- Removed Python 3.10 as a supported version on the controller. Python 3.11 or newer is required. +- Removed support for setting the ``vars`` keyword to lists of dictionaries. It is now required to be a single dictionary. +- loader - remove deprecated non-inclusive words (https://github.com/ansible/ansible/issues/82947). +- paramiko_ssh - removed deprecated ssh_args from the paramiko_ssh connection plugin (https://github.com/ansible/ansible/issues/82939). +- paramiko_ssh - removed deprecated ssh_common_args from the paramiko_ssh connection plugin (https://github.com/ansible/ansible/issues/82940). +- paramiko_ssh - removed deprecated ssh_extra_args from the paramiko_ssh connection plugin (https://github.com/ansible/ansible/issues/82941). +- play_context - remove deprecated PlayContext.verbosity property (https://github.com/ansible/ansible/issues/82945). +- utils/listify - remove deprecated 'loader' argument from listify_lookup_plugin_terms API (https://github.com/ansible/ansible/issues/82949). + +ansible.posix +~~~~~~~~~~~~~ + +- skippy - Remove skippy pluglin as it is no longer supported(https://github.com/ansible-collections/ansible.posix/issues/350). + +community.grafana +~~~~~~~~~~~~~~~~~ + +- removed check and handling of mangled api key in `grafana_dashboard` lookup +- removed deprecated `message` argument in `grafana_dashboard` + +community.okd +~~~~~~~~~~~~~ + +- k8s - Support for ``merge_type=json`` has been removed in version 4.0.0. Please use ``kubernetes.core.k8s_json_patch`` instead (https://github.com/openshift/community.okd/pull/226). + +kubernetes.core +~~~~~~~~~~~~~~~ + +- k8s - Support for ``merge_type=json`` has been removed in version 4.0.0. Please use ``kubernetes.core.k8s_json_patch`` instead (https://github.com/ansible-collections/kubernetes.core/pull/722). +- k8s_exec - the previously deprecated ``result.return_code`` return value has been removed, consider using ``result.rc`` instead (https://github.com/ansible-collections/kubernetes.core/pull/726). +- module_utils/common.py - the previously deprecated ``K8sAnsibleMixin`` class has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726). +- module_utils/common.py - the previously deprecated ``configuration_digest()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726). +- module_utils/common.py - the previously deprecated ``get_api_client()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726). +- module_utils/common.py - the previously deprecated ``unique_string()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726). + +Deprecated Features +------------------- + +Ansible-core +~~~~~~~~~~~~ + +- Deprecate ``ansible.module_utils.basic.AnsibleModule.safe_eval`` and ``ansible.module_utils.common.safe_eval`` as they are no longer used. +- persistent connection plugins - The ``ANSIBLE_CONNECTION_PATH`` config option no longer has any effect, and will be removed in a future release. +- yum_repository - deprecate ``async`` option as it has been removed in RHEL 8 and will be removed in ansible-core 2.22. +- yum_repository - the following options are deprecated: ``deltarpm_metadata_percentage``, ``gpgcakey``, ``http_caching``, ``keepalive``, ``metadata_expire_filter``, ``mirrorlist_expire``, ``protect``, ``ssl_check_cert_permissions``, ``ui_repoid_vars`` as they have no effect for dnf as an underlying package manager. The options will be removed in ansible-core 2.22. + +amazon.aws +~~~~~~~~~~ + +- iam_role - support for creating and deleting IAM instance profiles using the ``create_instance_profile`` and ``delete_instance_profile`` options has been deprecated and will be removed in a release after 2026-05-01. To manage IAM instance profiles the ``amazon.aws.iam_instance_profile`` module can be used instead (https://github.com/ansible-collections/amazon.aws/pull/2221). + +cisco.ios +~~~~~~~~~ + +- ios_bgp_address_family - deprecated attribute password in favour of password_options within neigbhors. +- ios_bgp_global - deprecated attributes aggregate_address, bestpath, inject_map, ipv4_with_subnet, ipv6_with_subnet, nopeerup_delay, distribute_list, address, tag, ipv6_addresses, password, route_map, route_server_context and scope +- ios_linkagg - deprecate legacy module ios_linkagg +- ios_lldp - deprecate legacy module ios_lldp + +community.docker +~~~~~~~~~~~~~~~~ + +- The collection deprecates support for all ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.general +~~~~~~~~~~~~~~~~~ + +- CmdRunner module util - setting the value of the ``ignore_none`` parameter within a ``CmdRunner`` context is deprecated and that feature should be removed in community.general 12.0.0 (https://github.com/ansible-collections/community.general/pull/8479). +- MH decorator cause_changes module utils - deprecate parameters ``on_success`` and ``on_failure`` (https://github.com/ansible-collections/community.general/pull/8791). +- git_config - the ``list_all`` option has been deprecated and will be removed in community.general 11.0.0. Use the ``community.general.git_config_info`` module instead (https://github.com/ansible-collections/community.general/pull/8453). +- git_config - using ``state=present`` without providing ``value`` is deprecated and will be disallowed in community.general 11.0.0. Use the ``community.general.git_config_info`` module instead to read a value (https://github.com/ansible-collections/community.general/pull/8453). +- pipx - support for versions of the command line tool ``pipx`` older than ``1.7.0`` is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8793). +- pipx_info - support for versions of the command line tool ``pipx`` older than ``1.7.0`` is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8793). + +community.grafana +~~~~~~~~~~~~~~~~~ + +- Deprecate `grafana_notification_channel`. It will be removed in version 3.0.0 + +community.routeros +~~~~~~~~~~~~~~~~~~ + +- The collection deprecates support for all Ansible/ansible-base/ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.sops +~~~~~~~~~~~~~~ + +- The collection deprecates support for all Ansible/ansible-base/ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.vmware +~~~~~~~~~~~~~~~~ + +- vmware_cluster - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2143). +- vmware_cluster_drs - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2136). +- vmware_cluster_vcls - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2156). diff --git a/docs/docsite/rst/porting_guides/porting_guide_9.rst b/docs/docsite/rst/porting_guides/porting_guide_9.rst index 5cb14161635..4d9da252673 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_9.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_9.rst @@ -84,6 +84,188 @@ Porting custom scripts Networking ========== +Porting Guide for v9.11.0 +========================= + +Deprecated Features +------------------- + +- The ``ngine_io.exoscale`` collection has been deprecated. + It will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details (`https://forum.ansible.com/t/2572 `__). +- The sensu.sensu_go collection will be removed from Ansible 12 due to violations of the Ansible inclusion requirements. + The collection has \ `unresolved sanity test failures `__. + See `Collections Removal Process for collections not satisfying the collection requirements `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/8380 `__). + +Porting Guide for v9.10.0 +========================= + +Breaking Changes +---------------- + +community.mysql +~~~~~~~~~~~~~~~ + +- collection - support of mysqlclient connector is deprecated - use PyMySQL connector instead! We will stop testing against it in collection version 4.0.0 and remove the related code in 5.0.0 (https://github.com/ansible-collections/community.mysql/issues/654). +- mysql_info - The ``users_info`` filter returned variable ``plugin_auth_string`` contains the hashed password and it's misleading, it will be removed from community.mysql 4.0.0. Use the `plugin_hash_string` return value instead (https://github.com/ansible-collections/community.mysql/pull/629). +- mysql_user - the ``user`` alias of the ``name`` argument has been deprecated and will be removed in collection version 5.0.0. Use the ``name`` argument instead. + +Deprecated Features +------------------- + +community.vmware +~~~~~~~~~~~~~~~~ + +- vmware_cluster - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2143). +- vmware_cluster_drs - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2136). +- vmware_cluster_vcls - the module has been deprecated and will be removed in community.vmware 6.0.0 (https://github.com/ansible-collections/community.vmware/pull/2156). + +Porting Guide for v9.9.0 +======================== + +Known Issues +------------ + +community.docker +~~~~~~~~~~~~~~~~ + +- docker_container - when specifying a MAC address for a container's network, and the network is attached after container creation (for example, due to idempotency checks), the MAC address is at least in some cases ignored by the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/933). + +Deprecated Features +------------------- + +community.docker +~~~~~~~~~~~~~~~~ + +- The collection deprecates support for all ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.routeros +~~~~~~~~~~~~~~~~~~ + +- The collection deprecates support for all Ansible/ansible-base/ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +community.sops +~~~~~~~~~~~~~~ + +- The collection deprecates support for all Ansible/ansible-base/ansible-core versions that are currently End of Life, `according to the ansible-core support matrix `__. This means that the next major release of the collection will no longer support Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14. + +Porting Guide for v9.8.0 +======================== + +Added Collections +----------------- + +- ieisystem.inmanage (version 2.0.0) +- vmware.vmware (version 1.3.0) + +Major Changes +------------- + +fortinet.fortios +~~~~~~~~~~~~~~~~ + +- Add a sanity_test.yaml file to trigger CI tests in GitHub. +- Support Ansible-core 2.17. +- Support new FOS versions 7.4.4. + +Deprecated Features +------------------- + +- The ``frr.frr`` collection has been deprecated. + It will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details (`https://forum.ansible.com/t/6243 `__). +- The ``openvswitch.openvswitch`` collection has been deprecated. + It will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details (`https://forum.ansible.com/t/6245 `__). + +Porting Guide for v9.7.0 +======================== + +Known Issues +------------ + +community.general +~~~~~~~~~~~~~~~~~ + +- homectl - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4691, https://github.com/ansible-collections/community.general/pull/8497). +- udm_user - the module does not work under Python 3.13 or newer, since it relies on the removed ``crypt`` standard library module (https://github.com/ansible-collections/community.general/issues/4690, https://github.com/ansible-collections/community.general/pull/8497). + +Major Changes +------------- + +containers.podman +~~~~~~~~~~~~~~~~~ + +- Add mount and unmount for volumes +- Add multiple subnets for networks +- Add new options for podman_container +- Add new options to pod module +- Add podman search +- Improve idempotency for networking in podman_container +- Redesign idempotency for Podman Pod module + +Removed Features +---------------- + +community.grafana +~~~~~~~~~~~~~~~~~ + +- removed deprecated `message` argument in `grafana_dashboard` + +Porting Guide for v9.6.0 +======================== + +Added Collections +----------------- + +- kaytus.ksmanage (version 1.2.1) + +Known Issues +------------ + +community.docker +~~~~~~~~~~~~~~~~ + +- Please note that the fix for requests 2.32.0 included in community.docker 3.10.1 only + fixes problems with the *vendored* Docker SDK for Python code. Modules and plugins that + use Docker SDK for Python can still fail due to the SDK currently being incompatible + with requests 2.32.0. + + If you still experience problems with requests 2.32.0, such as error messages like + ``Not supported URL scheme http+docker``, please restrict requests to ``<2.32.0``. + +Breaking Changes +---------------- + +community.ciscosmb +~~~~~~~~~~~~~~~~~~ + +- in facts of interface 'bandwith' changed to 'bandwidth' + +Deprecated Features +------------------- + +amazon.aws +~~~~~~~~~~ + +- cloudformation - the ``template`` parameter has been deprecated and will be removed in a release after 2026-05-01. The ``template_body`` parameter can be used in conjungtion with the lookup plugin (https://github.com/ansible-collections/amazon.aws/pull/2048). +- module_utils.botocore - the ``boto3`` parameter for ``get_aws_connection_info()`` will be removed in a release after 2025-05-01. The ``boto3`` parameter has been ignored since release 4.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2047). +- module_utils.botocore - the ``boto3`` parameter for ``get_aws_region()`` will be removed in a release after 2025-05-01. The ``boto3`` parameter has been ignored since release 4.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2047). +- module_utils.ec2 - the ``boto3`` parameter for ``get_ec2_security_group_ids_from_names()`` will be removed in a release after 2025-05-01. The ``boto3`` parameter has been ignored since release 4.0.0 (https://github.com/ansible-collections/amazon.aws/pull/2047). + +community.crypto +~~~~~~~~~~~~~~~~ + +- acme documentation fragment - the default ``community.crypto.acme[.documentation]`` docs fragment is deprecated and will be removed from community.crypto 3.0.0. Replace it with both the new ``community.crypto.acme.basic`` and ``community.crypto.acme.account`` fragments (https://github.com/ansible-collections/community.crypto/pull/735). +- acme.backends module utils - the ``get_cert_information()`` method for a ACME crypto backend must be implemented from community.crypto 3.0.0 on (https://github.com/ansible-collections/community.crypto/pull/736). +- crypto.module_backends.common module utils - the ``crypto.module_backends.common`` module utils is deprecated and will be removed from community.crypto 3.0.0. Use the improved ``argspec`` module util instead (https://github.com/ansible-collections/community.crypto/pull/749). + +community.docker +~~~~~~~~~~~~~~~~ + +- docker_compose - the Docker Compose v1 module is deprecated and will be removed from community.docker 4.0.0. Please migrate to the ``community.docker.docker_compose_v2`` module, which works with Docker Compose v2 (https://github.com/ansible-collections/community.docker/issues/823, https://github.com/ansible-collections/community.docker/pull/833). +- various modules and plugins - the ``ssl_version`` option has been deprecated and will be removed from community.docker 4.0.0. It has already been removed from Docker SDK for Python 7.0.0, and was only necessary in the past to work around SSL/TLS issues (https://github.com/ansible-collections/community.docker/pull/853). + Porting Guide for v9.5.1 ======================== @@ -155,9 +337,13 @@ fortinet.fortios Deprecated Features ------------------- -- The ``inspur.sm`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. See `the removal process for details on how this works `__ (https://forum.ansible.com/t/2854). -- The ``netapp.storagegrid`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. See `the removal process for details on how this works `__ (https://forum.ansible.com/t/2811). -- The ``purestorage.fusion`` collection is officially unmaintained and has been archived. Therefore, it will be removed from Ansible 10 (https://forum.ansible.com/t/3712). +- The ``inspur.sm`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/2854 `__). +- The ``netapp.storagegrid`` collection is considered unmaintained and will be removed from Ansible 11 if no one starts maintaining it again before Ansible 11. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://forum.ansible.com/t/2811 `__). +- The ``purestorage.fusion`` collection has been deprecated. + It will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. + See `Collections Removal Process for unmaintained collections `__ for more details (`https://forum.ansible.com/t/3712 `__). community.crypto ~~~~~~~~~~~~~~~~ @@ -512,12 +698,20 @@ Removed Collections Removed Features ---------------- -- The deprecated servicenow.servicenow collection has been removed from Ansible 7, but accidentally re-added to Ansible 8. It has been removed again from Ansible 9 (https://github.com/ansible-community/community-topics/issues/246). -- The ngine_io.vultr collection has been removed from Ansible 9, because it is officially unmaintained and has been archived. The successor collection ``vultr.cloud`` (using the recent v2 Vultr API) covers the same functionality but might not have compatible syntax (https://github.com/ansible-community/community-topics/issues/257). -- ``cisco.nso`` was considered unmaintained and removed from Ansible 9 as per the `removal from Ansible process `_. Users can still install this collection with ``ansible-galaxy collection install cisco.nso``. -- ``community.fortios`` was considered unmaintained and removed from Ansible 9 as per the `removal from Ansible process `_. Users can still install this collection with ``ansible-galaxy collection install community.fortios``. -- ``community.google`` was considered unmaintained and removed from Ansible 9 as per the `removal from Ansible process `_. Users can still install this collection with ``ansible-galaxy collection install community.google``. -- ``community.skydive`` was considered unmaintained and removed from Ansible 9 as per the `removal from Ansible process `_. Users can still install this collection with ``ansible-galaxy collection install community.skydive``. +- The ``cisco.nso`` collection was considered unmaintained and has been removed from Ansible 9 (`https://github.com/ansible-community/community-topics/issues/155 `__). + Users can still install this collection with ``ansible-galaxy collection install cisco.nso``. +- The ``community.fortios`` collection was considered unmaintained and has been removed from Ansible 9 (`https://github.com/ansible-community/community-topics/issues/162 `__). + Users can still install this collection with ``ansible-galaxy collection install community.fortios``. +- The ``community.google`` collection was considered unmaintained and has been removed from Ansible 9 (`https://github.com/ansible-community/community-topics/issues/160 `__). + Users can still install this collection with ``ansible-galaxy collection install community.google``. +- The ``community.skydive`` collection was considered unmaintained and has been removed from Ansible 9 (`https://github.com/ansible-community/community-topics/issues/171 `__). + Users can still install this collection with ``ansible-galaxy collection install community.skydive``. +- The ``ngine_io.vultr`` collection was considered unmaintained and has been removed from Ansible 9 (`https://github.com/ansible-community/community-topics/issues/257 `__). + Users can still install this collection with ``ansible-galaxy collection install ngine_io.vultr``. +- The servicenow.servicenow collection has been removed from Ansible 9. + The deprecated servicenow.servicenow collection has been removed from Ansible 7, but accidentally re-added to Ansible 8. + See `the removal discussion `__ for details. + Users can still install this collection with ``ansible-galaxy collection install servicenow.servicenow``. Ansible-core ~~~~~~~~~~~~ @@ -632,14 +826,30 @@ hetzner.hcloud Deprecated Features ------------------- -- The ``community.azure`` collection is officially unmaintained and has been archived. Therefore, it will be removed from Ansible 10. There is already a successor collection ``azure.azcollection`` in the community package which should cover the same functionality (https://github.com/ansible-community/community-topics/issues/263). -- The ``hpe.nimble`` collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. See `the removal process for details on how this works `__ (https://github.com/ansible-community/community-topics/issues/254). -- The collection ``community.sap`` has been renamed to ``community.sap_libs``. For now both collections are included in Ansible. The content in ``community.sap`` has deprecated redirects to the new collection in Ansible 9.0.0, and the collection will be removed from Ansible 10 completely. Please update your FQCNs for ``community.sap``. -- The collection ``ibm.spectrum_virtualize`` has been renamed to ``ibm.storage_virtualize``. For now, both collections are included in Ansible. The content in ``ibm.spectrum_virtualize`` will be replaced with deprecated redirects to the new collection in Ansible 10.0.0, and these redirects will eventually be removed from Ansible. Please update your FQCNs for ``ibm.spectrum_virtualize``. -- The collection ``t_systems_mms.icinga_director`` has been renamed to ``telekom_mms.icinga_director``. For now both collections are included in Ansible. The content in ``t_systems_mms.icinga_director`` has been replaced with deprecated redirects to the new collection in Ansible 9.0.0, and these redirects will be removed from Ansible 11. Please update your FQCNs for ``t_systems_mms.icinga_director``. -- The netapp.azure collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. See `the removal process for details on how this works `__ (https://github.com/ansible-community/community-topics/issues/234). -- The netapp.elementsw collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. See `the removal process for details on how this works `__ (https://github.com/ansible-community/community-topics/issues/235). -- The netapp.um_info collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. See `the removal process for details on how this works `__ (https://github.com/ansible-community/community-topics/issues/244). +- The ``community.azure`` collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://github.com/ansible-community/community-topics/issues/263 `__). +- The ``hpe.nimble`` collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://github.com/ansible-community/community-topics/issues/254 `__). +- The ``netapp.azure`` collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://github.com/ansible-community/community-topics/issues/234 `__). +- The ``netapp.elementsw`` collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://github.com/ansible-community/community-topics/issues/235 `__). +- The ``netapp.um_info`` collection is considered unmaintained and will be removed from Ansible 10 if no one starts maintaining it again before Ansible 10. + See `Collections Removal Process for unmaintained collections `__ for more details, including for how this can be cancelled (`https://github.com/ansible-community/community-topics/issues/244 `__). +- The collection ``community.sap`` was renamed to ``community.sap_libs``. + For now both collections are included in Ansible. + The collection will be completely removed from Ansible 10. + Please update your FQCNs from ``community.sap`` to ``community.sap_libs``. +- The collection ``ibm.spectrum_virtualize`` was renamed to ``ibm.storage_virtualize``. + For now both collections are included in Ansible. + The content in ``ibm.spectrum_virtualize`` will be replaced by deprecated redirects in Ansible 10.0.0. + The collection will be completely removed from Ansible eventually. + Please update your FQCNs from ``ibm.spectrum_virtualize`` to ``ibm.storage_virtualize``. +- The collection ``t_systems_mms.icinga_director`` was renamed to ``telekom_mms.icinga_director``. + For now both collections are included in Ansible. + The content in ``t_systems_mms.icinga_director`` has been replaced by deprecated redirects in Ansible 9.0.0. + The collection will be completely removed from Ansible 11. + Please update your FQCNs from ``t_systems_mms.icinga_director`` to ``telekom_mms.icinga_director``. Ansible-core ~~~~~~~~~~~~ diff --git a/docs/docsite/rst/porting_guides/porting_guide_core_2.17.rst b/docs/docsite/rst/porting_guides/porting_guide_core_2.17.rst index 2b4bf724eaf..c7550d0372d 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_core_2.17.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_core_2.17.rst @@ -19,7 +19,34 @@ This document is part of a collection on porting. The complete list of porting g Playbook ======== -No notable changes +* Conditionals - due to mitigation of security issue CVE-2023-5764 in ansible-core 2.16.1, + conditional expressions with embedded template blocks can fail with the message + "``Conditional is marked as unsafe, and cannot be evaluated.``" when an embedded template + consults data from untrusted sources like module results or vars marked ``!unsafe``. + Conditionals with embedded templates can be a source of malicious template injection when + referencing untrusted data, and can nearly always be rewritten without embedded + templates. Playbook task conditional keywords such as ``when`` and ``until`` have long + displayed warnings discouraging use of embedded templates in conditionals; this warning + has been expanded to non-task conditionals as well, such as the ``assert`` action. + + .. code-block:: yaml + + - name: task with a module result (always untrusted by Ansible) + shell: echo "hi mom" + register: untrusted_result + + # don't do it this way... + # - name: insecure conditional with embedded template consulting untrusted data + # assert: + # that: '"hi mom" is in {{ untrusted_result.stdout }}' + + - name: securely access untrusted values directly as Jinja variables instead + assert: + that: '"hi mom" is in untrusted_result.stdout' + +* ``any_errors_fatal`` - when a task in a block with a ``rescue`` section + fails on a host, the ``rescue`` section is executed on all hosts. This + occurs because ``any_errors_fatal`` automatically fails all hosts. Command Line diff --git a/docs/docsite/rst/porting_guides/porting_guides.rst b/docs/docsite/rst/porting_guides/porting_guides.rst index 248636a3cee..b235f9dcef3 100644 --- a/docs/docsite/rst/porting_guides/porting_guides.rst +++ b/docs/docsite/rst/porting_guides/porting_guides.rst @@ -10,6 +10,7 @@ This section lists porting guides that can help you in updating playbooks, plugi :maxdepth: 1 :glob: + porting_guide_11 porting_guide_10 porting_guide_9 porting_guide_8 diff --git a/docs/docsite/rst/reference_appendices/YAMLSyntax.rst b/docs/docsite/rst/reference_appendices/YAMLSyntax.rst index d74f6dc8fdf..b445dfe3da1 100644 --- a/docs/docsite/rst/reference_appendices/YAMLSyntax.rst +++ b/docs/docsite/rst/reference_appendices/YAMLSyntax.rst @@ -270,16 +270,12 @@ value: Learn what playbooks can do and how to write/run them. `YAMLLint `_ YAML Lint (online) helps you debug YAML syntax if you are having problems - `GitHub examples directory `_ - Complete playbook files from the GitHub project source `Wikipedia YAML syntax reference `_ A good guide to YAML syntax - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups - :ref:`communication_irc` - How to join Ansible chat channels (join #yaml for yaml-specific questions) `YAML 1.1 Specification `_ The Specification for YAML 1.1, which PyYAML and libyaml are currently implementing `YAML 1.2 Specification `_ For completeness, YAML 1.2 is the successor of 1.1 + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/reference_appendices/common_return_values.rst b/docs/docsite/rst/reference_appendices/common_return_values.rst index 04f57ac3d6c..561a05ad3b5 100644 --- a/docs/docsite/rst/reference_appendices/common_return_values.rst +++ b/docs/docsite/rst/reference_appendices/common_return_values.rst @@ -18,7 +18,7 @@ Common backup_file ``````````` -For those modules that implement `backup=no|yes` when manipulating files, a path to the backup file created. +For those modules that implement `backup=no|yes` when manipulating files, a path to the backup file created if original file was changed. .. code-block:: console @@ -245,7 +245,5 @@ This key contains a list of dictionaries that will be presented to the user. Key Browse existing collections, modules, and plugins `GitHub modules directory `_ Browse source of core and extras modules - `Mailing List `_ - Development mailing list - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/reference_appendices/faq.rst b/docs/docsite/rst/reference_appendices/faq.rst index 48f65a92c58..2b94a1caf4a 100644 --- a/docs/docsite/rst/reference_appendices/faq.rst +++ b/docs/docsite/rst/reference_appendices/faq.rst @@ -26,7 +26,7 @@ IF you are searching for a specific module, you can check the `runtime.yml `_ for hints on how to improve this. @@ -35,7 +35,7 @@ Ansible may feel sluggish on systems with slow disks, such as Raspberry PI. See .. _set_environment: How can I set the PATH or any other environment variable for a task or entire play? -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Setting environment variables can be done with the `environment` keyword. It can be used at the task or other levels in the play. @@ -154,7 +154,7 @@ Rather connect to a management node inside this cloud provider first and run Ans .. _python_interpreters: How do I handle not having a Python interpreter at /usr/bin/python on a remote machine? -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ While you can write Ansible modules in any language, most Ansible modules are written in Python, including the ones central to letting Ansible work. @@ -182,7 +182,8 @@ Also, this works for ANY interpreter, for example ruby: ``ansible_ruby_interpret so you can use this for custom modules written in any scripting language and control the interpreter location. Keep in mind that if you put ``env`` in your module shebang line (``#!/usr/bin/env ``), -this facility will be ignored so you will be at the mercy of the remote `$PATH`. +this won't work and will be evaluated as one string (including the space between ``env`` and ```` space). +Arguments are neither intended nor supported. .. _installation_faqs: @@ -435,7 +436,7 @@ What is the best way to make content reusable/redistributable? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ If you have not done so already, read all about "Roles" in the playbooks documentation. This helps you make playbook content -self-contained, and works well with things like git submodules for sharing content with others. +self-contained, and works well with things like Git submodules for sharing content with others. If some of these plugin types look strange to you, see the API documentation for more details about ways Ansible can be extended. @@ -860,12 +861,14 @@ In these releases, SCP tries to validate that the path of the file to fetch matc The validation fails if the remote file name requires quotes to escape spaces or non-ascii characters in its path. To avoid this error: -* Use SFTP instead of SCP by setting ``scp_if_ssh`` to ``smart`` (which tries SFTP first) or to ``False``. You can do this in one of four ways: - * Rely on the default setting, which is ``smart`` - this works if ``scp_if_ssh`` is not explicitly set anywhere - * Set a :ref:`host variable ` or :ref:`group variable ` in inventory: ``ansible_scp_if_ssh: False`` - * Set an environment variable on your control node: ``export ANSIBLE_SCP_IF_SSH=False`` - * Pass an environment variable when you run Ansible: ``ANSIBLE_SCP_IF_SSH=smart ansible-playbook`` - * Modify your ``ansible.cfg`` file: add ``scp_if_ssh=False`` to the ``[ssh_connection]`` section +* Ensure you are using SFTP, which is the optimal transfer method for security, speed and reliability. Check that you are doing one of the following: + * Rely on the default setting, which is ``smart`` — this works if ``ssh_transfer_method`` is not explicitly set anywhere + * Set a :ref:`host variable ` or :ref:`group variable ` in inventory: ``ansible_ssh_transfer_method: smart`` + * Set an environment variable on your control node: ``export ANSIBLE_SSH_TRANSFER_METHOD=smart`` + * Pass an environment variable when you run Ansible: ``ANSIBLE_SSH_TRANSFER_METHOD=smart ansible-playbook`` + * Modify your ``ansible.cfg`` file: add ``ssh_transfer_method=smart`` to the ``[ssh_connection]`` section. + The ``smart`` setting attempts to use ``sftp`` for the transfer, then falls back to ``scp`` and then ``dd``. + If you want the transfer to fail if SFTP is not available, add ``ssh_transfer_method=sftp`` to the ``[ssh_connection]`` section. * If you must use SCP, set the ``-T`` arg to tell the SCP client to ignore path validation. You can do this in one of three ways: * Set a :ref:`host variable ` or :ref:`group variable `: ``ansible_scp_extra_args=-T``, * Export or pass an environment variable: ``ANSIBLE_SCP_EXTRA_ARGS=-T`` @@ -876,7 +879,7 @@ fails if the remote file name requires quotes to escape spaces or non-ascii char .. _mfa_support: Does Ansible support multiple factor authentication 2FA/MFA/biometrics/finterprint/usbkey/OTP/... -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ No, Ansible is designed to execute multiple tasks against multiple targets, minimizing user interaction. As with most automation tools, it is not compatible with interactive security systems designed to handle human interaction. @@ -902,11 +905,11 @@ and backups, which most file based modules also support: .. code-block:: yaml - - name: update config and backout if validation fails + - name: maintain config and backout if validation after change fails block: - - name: do the actual update, works with copy, lineinfile and any action that allows for `backup`. - template: src=template.j2 dest=/x/y/z backup=yes moreoptions=stuff - register: updated + - name: do the actual update, works with copy, lineinfile and any action that allows for `backup`. + template: src=template.j2 dest=/x/y/z backup=yes moreoptions=stuff + register: updated - name: run validation, this will change a lot as needed. We assume it returns an error when not passing, use `failed_when` if otherwise. shell: run_validation_commmand @@ -914,17 +917,20 @@ and backups, which most file based modules also support: become_user: requiredbyapp environment: WEIRD_REQUIREMENT: 1 + when: updated is changed rescue: - name: restore backup file to original, in the hope the previous configuration was working. copy: remote_src: true dest: /x/y/z src: "{{ updated['backup_file'] }}" + when: updated is changed always: - name: We choose to always delete backup, but could copy or move, or only delete in rescue. file: path: "{{ updated['backup_file'] }}" state: absent + when: updated is changed .. _jinja2_faqs: @@ -957,14 +963,14 @@ The native jinja2 functionality actually allows us to return full Python objects How do I submit a change to the documentation? ++++++++++++++++++++++++++++++++++++++++++++++ -Documentation for Ansible is kept in the main project git repository, and complete instructions +Documentation for Ansible is kept in the main project Git repository, and complete instructions for contributing can be found in the docs README `viewable on GitHub `_. Thanks! .. _legacy_vs_builtin: What is the difference between ``ansible.legacy`` and ``ansible.builtin`` collections? -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Neither is a real collection. They are virtually constructed by the core engine (synthetic collections). @@ -994,7 +1000,7 @@ Though, if you do not override the ``shell`` module, you can also just write it I don't see my question here ++++++++++++++++++++++++++++ -If you have not found an answer to your questions, you can ask on one of our mailing lists or chat channels. For instructions on subscribing to a list or joining a chat channel, see :ref:`communication`. +If you have not found an answer to your questions, ask the community! Visit the :ref:`Ansible communication guide` for details. .. seealso:: @@ -1002,5 +1008,5 @@ If you have not found an answer to your questions, you can ask on one of our mai An introduction to playbooks :ref:`playbooks_best_practices` Tips and tricks for playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/reference_appendices/general_precedence.rst b/docs/docsite/rst/reference_appendices/general_precedence.rst index a94f4a64f15..7beb76b1c73 100644 --- a/docs/docsite/rst/reference_appendices/general_precedence.rst +++ b/docs/docsite/rst/reference_appendices/general_precedence.rst @@ -21,6 +21,7 @@ Ansible offers four sources for controlling its behavior. In order of precedence * Command-line options * Playbook keywords * Variables + * Direct Assignment Each category overrides any information from all lower-precedence categories. For example, a playbook keyword will override any configuration setting. @@ -97,7 +98,7 @@ Playbooks are the command or 'state description' structure for Ansible, variable Variables ^^^^^^^^^ -Any variable will override any playbook keyword, any command-line option, and any configuration setting. +Ansible variables are very high on the precedence stack. They will override any playbook keyword, any command-line option, environment variable and any configuration file setting. Variables that have equivalent playbook keywords, command-line options, and configuration settings are known as :ref:`connection_variables`. Originally designed for connection parameters, this category has expanded to include other core variables like the temporary directory and the python interpreter. @@ -136,15 +137,44 @@ Variable values set in a playbook exist only within the playbook object that def Variable values associated directly with a host or group, including variables defined in inventory, by vars plugins, or using modules like :ref:`set_fact` and :ref:`include_vars`, are available to all plays. These 'host scope' variables are also available through the ``hostvars[]`` dictionary. +Variables set through ``extra vars`` have a global scope for the current run and will be present both as 'playbook object vars' and 'hostvars'. + .. _general_precedence_extra_vars: Using ``-e`` extra variables at the command line -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""""""""""""""""""" -To override all other settings in all other categories, you can use extra variables: ``--extra-vars`` or ``-e`` at the command line. Values passed with ``-e`` are variables, not command-line options, and they will override configuration settings, command-line options, and playbook keywords as well as variables set elsewhere. For example, this task will connect as ``brian`` not as ``carol``: +To override all other variables, you can use extra variables: ``--extra-vars`` or ``-e`` at the command line. Values passed with ``-e``, while still a command-line option itself, have the highest precedence among variables and will, a bit counter intuitively, be of the higher precedence among most configuration sources, since variables themselves have high precedence. For example, this task will connect as ``brian`` not as ``carol``: .. code:: shell ansible -u carol -e 'ansible_user=brian' -a whoami all You must specify both the variable name and the value with ``--extra-vars``. + + +Direct Assignment +^^^^^^^^^^^^^^^^^ + +This category only applies to things that take direct options, generally modules and some plugin types. Most modules and action plugins do not have any other way to assign settings so precedence rarely comes up in that context, but it still possible for some of them to do so and should be reflected in the documentation. + +.. code:: yaml + + - debug: msg='this is a direct assignment option to an action plugin' + + - ping: + data: also a direct assignment + +Outside of task actions, the most recognizable 'direct assignments' are with lookup, filter and test plugins: + +.. code:: + + lookup('plugin', direct1='value', direct2='value2') + + 'value_directly_assigned'|filter('another directly assigned') + + 'direct value' is testplugin + +Though most of these are not configured in other ways, specially tests, it is possible for plugins and filters to use input from other configuration sources if specified in their documentation. + +Inventory plugins are a bit tricky as they use 'inventory sources' and these sometimes can look like a configuration file and are passed in as a command line option, yet it is still considered 'direct assignment'. It is a bit clearer when using an inline source ``-i host1, host2, host3`` than when using a file source ``-i /path/to/inventory_source``, but they both have the same precedence. diff --git a/docs/docsite/rst/reference_appendices/glossary.rst b/docs/docsite/rst/reference_appendices/glossary.rst index a2cf6bc559c..361a2c87d60 100644 --- a/docs/docsite/rst/reference_appendices/glossary.rst +++ b/docs/docsite/rst/reference_appendices/glossary.rst @@ -5,7 +5,7 @@ The following is a list (and re-explanation) of term definitions used elsewhere Consult the documentation home page for the full documentation and to see the terms in context, but this should be a good resource to check your knowledge of Ansible's components and understand how they fit together. It is something you might wish to read for review or -when a term comes up on the mailing list. +when a term comes up on the :ref:`Ansible Forum`. .. glossary:: @@ -383,7 +383,7 @@ when a term comes up on the mailing list. choices. :command:`ansible-pull` works by checking configuration orders out of - git on a crontab and then managing the machine locally, using the + Git on a crontab and then managing the machine locally, using the :term:`local connection` plugin. Pulp 3 Galaxy @@ -534,7 +534,5 @@ when a term comes up on the mailing list. An introduction to playbooks :ref:`playbooks_best_practices` Tips and tricks for playbooks - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/reference_appendices/interpreter_discovery.rst b/docs/docsite/rst/reference_appendices/interpreter_discovery.rst index 740891ea783..23d1d970929 100644 --- a/docs/docsite/rst/reference_appendices/interpreter_discovery.rst +++ b/docs/docsite/rst/reference_appendices/interpreter_discovery.rst @@ -49,5 +49,3 @@ auto_silent You can still set ``ansible_python_interpreter`` to a specific path at any variable level (for example, in host_vars, in vars files, in playbooks, and so on). Setting a specific path completely disables automatic interpreter discovery; Ansible always uses the path specified. - -.. seealso:: :ref:`python_3_support` for ``ansible_python_interpreter`` usage examples. diff --git a/docs/docsite/rst/reference_appendices/python_3_support.rst b/docs/docsite/rst/reference_appendices/python_3_support.rst index 61239b748c4..5c60a4ea85e 100644 --- a/docs/docsite/rst/reference_appendices/python_3_support.rst +++ b/docs/docsite/rst/reference_appendices/python_3_support.rst @@ -1,5 +1,3 @@ -.. _python_3_support: - ================ Python 3 Support ================ @@ -70,12 +68,6 @@ Using Python 3 on the managed machines with commands and playbooks $ ansible localhost-py3 -m ping $ ansible-playbook sample-playbook.yml -* To use the first Python found on ``PATH`` or if the Python interpreter path is not known in advance, you can use ``/usr/bin/env python`` such as: - -.. code-block:: shell - - ansible_python_interpreter="/usr/bin/env python" - Note that you can also use the `-e` command line option to manually set the python interpreter when you run a command. This can be useful if you want to test whether diff --git a/docs/docsite/rst/reference_appendices/release_and_maintenance.rst b/docs/docsite/rst/reference_appendices/release_and_maintenance.rst index 03f0583c5e1..5dedccf2987 100644 --- a/docs/docsite/rst/reference_appendices/release_and_maintenance.rst +++ b/docs/docsite/rst/reference_appendices/release_and_maintenance.rst @@ -54,9 +54,9 @@ The Ansible community team typically releases two major versions of the communit Starting with version 2.10, the Ansible community team guarantees maintenance for only one major community package release at a time. For example, when Ansible 4.0.0 gets released, the team will stop making new 3.x releases. Community members may maintain older versions if desired. -.. note:: - - Each Ansible EOL version may issue one final maintenance release at or shortly after the first release of the next version. When this happens, the final maintenance release is EOL at the date it releases. +.. note:: + + Each Ansible EOL version may issue one final maintenance release at or shortly after the first release of the next version. When this happens, the final maintenance release is EOL at the date it releases. .. note:: @@ -81,9 +81,10 @@ This table links to the changelogs for each major Ansible release. These changel ================================== ============================================== ========================= Ansible Community Package Release Status Core version dependency ================================== ============================================== ========================= -10.0.0 In development (unreleased) 2.17 -`9.x Changelogs`_ Current 2.16 -`8.x Changelogs`_ Unmaintained (end of life) after Ansible 8.7.0 2.15 +11.0.0 In development (unreleased) 2.18 +`10.x Changelogs`_ Current 2.17 +`9.x Changelogs`_ Minor/patch releases (EOL Nov 2024) 2.16 +`8.x Changelogs`_ Unmaintained (end of life) 2.15 `7.x Changelogs`_ Unmaintained (end of life) 2.14 `6.x Changelogs`_ Unmaintained (end of life) 2.13 `5.x Changelogs`_ Unmaintained (end of life) 2.12 @@ -92,6 +93,7 @@ Ansible Community Package Release Status `2.10 Changelogs`_ Unmaintained (end of life) 2.10 ================================== ============================================== ========================= +.. _10.x Changelogs: https://github.com/ansible-community/ansible-build-data/blob/main/10/CHANGELOG-v10.md .. _9.x Changelogs: https://github.com/ansible-community/ansible-build-data/blob/main/9/CHANGELOG-v9.rst .. _8.x Changelogs: https://github.com/ansible-community/ansible-build-data/blob/main/8/CHANGELOG-v8.rst .. _7.x Changelogs: https://github.com/ansible-community/ansible-build-data/blob/main/7/CHANGELOG-v7.rst @@ -139,6 +141,13 @@ Starting with ``ansible-core`` version 2.16, each release includes target node s Support for Python 2.7 is included in ``ansible-core`` version 2.16 and earlier. +.. _target_node_windows_support: + +``ansible-core`` target node PowerShell and Windows support +----------------------------------------------------------- + +``ansible-core`` on Windows supports the baseline version of PowerShell that each Windows version ships with. For example, Windows Server 2016 shipped with PowerShell 5.1 so Ansible will support PowerShell 5.1 for the life of Windows Server 2016 support. Support for each Windows version is determined by the Windows lifecycle policy and when each version reaches the extended end date. For example Windows Server 2012 and 2012 R2 extended end date was for October 10th 2023 while Windows Server 2016 is January 12th 2027. Windows support does not align with the 3 year Extended Security Updates (``ESU``) support from Microsoft which is a paid support option for products that are past the normal end of support date from Microsoft. + .. _ansible_core_support_matrix: ``ansible-core`` support matrix @@ -149,20 +158,28 @@ Dates listed indicate the start date of the maintenance cycle. .. list-table:: :header-rows: 1 - + * - Version - Support - End Of Life - Control Node Python - Target Python / PowerShell - * - 2.17 + * - `2.18`_ + - | GA: 04 Nov 2024 + | Critical: 19 May 2025 + | Security: 03 Nov 2025 + - May 2026 + - | Python 3.11 - 3.13 + - | Python 3.8 - 3.13 + | PowerShell 5.1 + * - `2.17`_ - | GA: 20 May 2024 | Critical: 04 Nov 2024 | Security: 19 May 2025 - Nov 2025 - | Python 3.10 - 3.12 - | Python 3.7 - 3.12 - | PowerShell TBD + | PowerShell 5.1 * - `2.16`_ - | GA: 06 Nov 2023 | Critical: 20 May 2024 @@ -171,7 +188,7 @@ Dates listed indicate the start date of the maintenance cycle. - | Python 3.10 - 3.12 - | Python 2.7 | Python 3.6 - 3.12 - | Powershell 3 - 5.1 + | Powershell 5.1 * - `2.15`_ - | GA: 22 May 2023 | Critical: 06 Nov 2023 @@ -185,7 +202,8 @@ Dates listed indicate the start date of the maintenance cycle. - | GA: 07 Nov 2022 | Critical: 22 May 2023 | Security: 06 Nov 2023 - - 20 May 2024 + - | **EOL** + | 20 May 2024 - | Python 3.9 - 3.11 - | Python 2.7 | Python 3.5 - 3.11 @@ -243,14 +261,6 @@ Dates listed indicate the start date of the maintenance cycle. - | Python 2.6 - 2.7 | Python 3.5 - 3.8 | PowerShell 3 - 5.1 -.. * - 2.18 -.. - Nov 2024 -.. - May 2025 -.. - Nov 2025 -.. - May 2026 -.. - | Python 3.11 - 3.13 -.. - | Python 3.8 - 3.13 -.. | PowerShell TBD .. * - 2.19 .. - May 2025 .. - Nov 2025 @@ -258,7 +268,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - Nov 2026 .. - | Python 3.11 - 3.13 .. - | Python 3.8 - 3.13 -.. | PowerShell TBD +.. | PowerShell 5.1 .. * - 2.20 .. - Nov 2025 .. - May 2026 @@ -266,7 +276,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - May 2027 .. - | Python 3.12 - 3.14 .. - | Python 3.9 - 3.14 -.. | PowerShell TBD +.. | PowerShell 5.1 .. * - 2.21 .. - May 2026 .. - Nov 2026 @@ -274,7 +284,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - Nov 2027 .. - | Python 3.12 - 3.14 .. - | Python 3.9 - 3.14 -.. | PowerShell TBD +.. | PowerShell 5.1 .. * - 2.22 .. - Nov 2026 .. - May 2027 @@ -282,7 +292,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - May 2028 .. - | Python 3.13 - 3.15 .. - | Python 3.9 - 3.15 -.. | PowerShell TBD +.. | PowerShell 5.1 .. * - 2.23 .. - May 2027 .. - Nov 2027 @@ -290,7 +300,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - Nov 2028 .. - | Python 3.13 - 3.15 .. - | Python 3.10 - 3.15 -.. | PowerShell TBD +.. | PowerShell 5.1 .. * - 2.24 .. - Nov 2027 .. - May 2028 @@ -298,7 +308,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - May 2029 .. - | Python 3.14 - 3.16 .. - | Python 3.11 - 3.16 -.. | PowerShell TBD +.. | PowerShell 5.1 .. * - 2.25 .. - May 2028 .. - Nov 2028 @@ -306,7 +316,7 @@ Dates listed indicate the start date of the maintenance cycle. .. - Nov 2029 .. - | Python 3.14 - 3.16 .. - | Python 3.11 - 3.16 -.. | PowerShell TBD +.. | PowerShell 5.1 .. _2.9: https://github.com/ansible/ansible/blob/stable-2.9/changelogs/CHANGELOG-v2.9.rst @@ -317,6 +327,8 @@ Dates listed indicate the start date of the maintenance cycle. .. _2.14: https://github.com/ansible/ansible/blob/stable-2.14/changelogs/CHANGELOG-v2.14.rst .. _2.15: https://github.com/ansible/ansible/blob/stable-2.15/changelogs/CHANGELOG-v2.15.rst .. _2.16: https://github.com/ansible/ansible/blob/stable-2.16/changelogs/CHANGELOG-v2.16.rst +.. _2.17: https://github.com/ansible/ansible/blob/stable-2.17/changelogs/CHANGELOG-v2.17.rst +.. _2.18: https://github.com/ansible/ansible/blob/stable-2.18/changelogs/CHANGELOG-v2.18.rst @@ -418,7 +430,5 @@ The deprecation cycle in ``ansible-core`` is normally across 4 feature releases Testing strategies :ref:`ansible_community_guide` Community information and contributing - `Development Mailing List `_ - Mailing list for development topics - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/reference_appendices/test_strategies.rst b/docs/docsite/rst/reference_appendices/test_strategies.rst index 2cef3139f34..0d05ffa1ecb 100644 --- a/docs/docsite/rst/reference_appendices/test_strategies.rst +++ b/docs/docsite/rst/reference_appendices/test_strategies.rst @@ -297,7 +297,5 @@ system. An introduction to playbooks :ref:`playbooks_delegation` Delegation, useful for working with load balancers, clouds, and locally executed steps. - `User Mailing List `_ - Have a question? Stop by the Google group! - :ref:`communication_irc` - How to join Ansible chat channels + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/roadmap/COLLECTIONS_11.rst b/docs/docsite/rst/roadmap/COLLECTIONS_11.rst new file mode 100644 index 00000000000..5a9be096182 --- /dev/null +++ b/docs/docsite/rst/roadmap/COLLECTIONS_11.rst @@ -0,0 +1,92 @@ +.. + THIS DOCUMENT IS OWNED BY THE ANSIBLE COMMUNITY STEERING COMMITTEE. ALL CHANGES MUST BE APPROVED BY THE STEERING COMMITTEE! + For small changes (fixing typos, language errors, etc.) create a PR and ping @ansible/steering-committee. + For other changes, create a discussion as described in https://github.com/ansible-community/community-topics/blob/main/community_topics_workflow.md#creating-a-topic + to discuss the changes. + (Creating a draft PR for this file and mentioning it in the community topic is also OK.) + +.. _ansible_11_roadmap: + +==================== +Ansible project 11.0 +==================== + +This release schedule includes dates for the `ansible `_ package, with a few dates for the `ansible-core `_ package as well. All dates are subject to change. See the `ansible-core 2.18 Roadmap `_ for the most recent updates on ``ansible-core``. + +.. contents:: + :local: + + +Release schedule +================= + + +:2024-09-16: ansible-core feature freeze, stable-2.18 branch created. +:2024-09-23: Start of ansible-core 2.18 betas +:2024-09-24: Ansible-11.0.0 alpha1 [1]_ +:2024-10-14: First ansible-core 2.18 release candidate. +:2024-10-15: Ansible-11.0.0 alpha2 [1]_ +:2024-11-04: Ansible-core-2.18.0 released. +:2024-11-04: Last day for collections to make backwards incompatible releases that will be accepted into Ansible-11. This includes adding new collections to Ansible 11.0.0; from now on new collections have to wait for 11.1.0 or later. +:2024-11-05: Ansible-11.0.0 beta1 -- feature freeze [2]_ (weekly beta releases; collection owners and interested users should test for bugs). +:2024-11-12: Ansible-11.0.0 rc1 [3]_ [4]_ (weekly release candidates as needed; test and alert us to any blocker bugs). Blocker bugs will slip release. +:2024-11-15: Last day to trigger an Ansible-11.0.0rc2 release because of major defects in Ansible-11.0.0rc1. +:2024-11-19: Ansible-11.0.0rc2 when necessary, otherwise Ansible-11.0.0 release. +:2024-11-26: Ansible-11.0.0 release when Ansible-11.0.0rc2 was necessary. +:2024-11-19 or 2023-11-26: Create the ansible-build-data directory and files for Ansible-12. +:2024-12-02: Release of ansible-core 2.18.1. +:2024-12-03: Release of Ansible-11.1.0 (bugfix + compatible features: every four weeks.) + +.. [1] In case there are any additional ansible-core beta releases or release candidates, we will try to do another Ansible-11.0.0 alpha release. This might mean that we will release Ansible-11.0.0 alpha2 earlier (and release Ansible-11.0.0 alpha3 or later on 2024-10-15) and / or release one or more additional alpha after 2024-10-15. + +.. [2] No new modules or major features accepted after this date. In practice, this means we will freeze the semver collection versions to compatible release versions. For example, if the version of community.crypto on this date was community.crypto 2.3.0; Ansible-11.0.0 could ship with community.crypto 2.3.1. It would not ship with community.crypto 2.4.0. + +.. [3] After this date only changes blocking a release are accepted. Accepted changes require creating a new release candidate and may slip the final release date. + +.. [4] Collections will be updated to a new version only if a blocker is approved. Collection owners should discuss any blockers at a community meeting (before this freeze) to decide whether to bump the version of the collection for a fix. See the `creating an Ansible Community Topic workflow `_. + +.. note:: + + Breaking changes will be introduced in Ansible 11.0.0. We encourage the use of deprecation periods that give advance notice of breaking changes at least one Ansible release before they are introduced. However, deprecation notices are not guaranteed to take place. + +.. note:: + + In general, it is in the discretion of the release manager to delay a release by 1-2 days for reasons such as personal (schedule) problems, technical problems (CI/infrastructure breakdown), and so on. + However, in case two releases are planned for the same day, a release of the latest stable version takes precedence. This means that if a stable Ansible 11 release collides with a pre-release of Ansible 12, the latter will be delayed. + If a Ansible 11 release collides with a stable Ansible 12 release, including 12.0.0, the Ansible 11 release will be delayed. + + +Planned major changes +===================== + +- The inspur.sm collection will be removed as it is unmaintained (https://github.com/ansible-community/ansible-build-data/issues/424). +- The netapp.storagegrid collection will be removed as it is unmaintained (https://github.com/ansible-community/ansible-build-data/issues/434). +- The frr.frr collection will be removed as it is unmaintained (https://github.com/ansible-community/ansible-build-data/issues/437). +- The openvswitch.openvswitch collection will be removed as it is unmaintained (https://github.com/ansible-community/ansible-build-data/issues/437). + +You can install removed collections manually with ``ansible-galaxy collection install ``. + + +Ansible minor releases +======================= + +Ansible 11.x follows ansible-core-2.18.x releases, so releases will occur approximately every four weeks. If ansible-core delays a release for whatever reason, the next Ansible 11.x minor release will be delayed accordingly. + +Ansible 11.x minor releases may contain new features (including new collections) but not backwards incompatibilities. In practice, this means we will include new collection versions where either the patch or the minor version number has changed but not when the major number has changed. For example, if Ansible-11.0.0 ships with community.crypto 2.3.0, Ansible-11.1.0 could ship with community.crypto 2.4.0 but not community.crypto 3.0.0. + + +.. note:: + + Minor and patch releases will stop when Ansible-12 is released. See the :ref:`Release and Maintenance Page ` for more information. + +.. note:: + + We will not provide bugfixes or security fixes for collections that do not + provide updates for their major release cycle included in Ansible 11. + +Communication +============= + +You can submit feedback on the current roadmap by creating a :ref:`community topic`. + +Visit the :ref:`Ansible communication guide` for details on how to join and use Ansible communication platforms. diff --git a/docs/docsite/rst/roadmap/ROADMAP_2_18.rst b/docs/docsite/rst/roadmap/ROADMAP_2_18.rst new file mode 100644 index 00000000000..93e218bca8a --- /dev/null +++ b/docs/docsite/rst/roadmap/ROADMAP_2_18.rst @@ -0,0 +1,73 @@ +.. _core_roadmap_2.18: + +***************** +Ansible-core 2.18 +***************** + +.. contents:: + :local: + +Release Schedule +================ + +Expected +-------- + +PRs must be raised well in advance of the dates below to have a chance of being included in this ansible-core release. + +.. note:: Dates subject to change. + +Development Phase +^^^^^^^^^^^^^^^^^ + +The ``milestone`` branch will be advanced at the start date of each development phase, and the beta 1 release. + +- 2024-04-29 Development Phase 1 +- 2024-06-24 Development Phase 2 +- 2024-08-05 Development Phase 3 +- 2024-09-23 Beta 1 + +Release Phase +^^^^^^^^^^^^^ + +- 2024-09-16 Feature Freeze (and ``stable-2.18`` branching from ``devel``) + No new functionality (including modules/plugins) to any code + +- 2024-09-23 Beta 1 + +- 2024-10-14 Release Candidate 1 + +- 2024-11-04 Release + +.. note:: The beta and release candidate schedules allow for up to 3 releases on a weekly schedule depending on the necessity of creating a release. + +Release Manager +=============== + + Ansible Core Team + +Planned work +============ + +* Drop Python 3.10, and add Python 3.13 for controller code +* Drop Python 3.7, and add Python 3.13 for target code +* Data Tagging +* Add support to ansible-galaxy for new console.redhat.com service account auth +* Finalize task object connection attribute for connection reporting in callbacks +* Add break functionality for task loops +* Add new non-local mount facts +* Evaluate changes to strategy plugins to use the core strategy result processing for meta task results +* Remove deprecated functionality +* Decrease incidental integration tests +* Add controller type hinting for discrete areas of the code +* Decrease testing sanity ignores +* Update ansible-test container images and VMs +* Update ansible-test dependencies + + +Delayed work +============ + +The following work has been delayed and retargeted for a future release: + +* TBD diff --git a/docs/docsite/rst/roadmap/ansible_core_roadmap_index.rst b/docs/docsite/rst/roadmap/ansible_core_roadmap_index.rst index d5a9af200d9..17b565a77ac 100644 --- a/docs/docsite/rst/roadmap/ansible_core_roadmap_index.rst +++ b/docs/docsite/rst/roadmap/ansible_core_roadmap_index.rst @@ -12,18 +12,14 @@ Each roadmap offers a *best guess*, based on the ``ansible-core`` team's experie Each roadmap is published both as an idea of what is upcoming in ``ansible-core``, and as a medium for seeking further feedback from the community. -You can submit feedback on the current roadmap in multiple ways: - -- Post on the ``#ansible-devel`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) -- Email the ansible-devel list - -See :ref:`Ansible communication channels ` for details on how to join and use the email lists and chat channels. +You can submit feedback on the current roadmap by creating a topic on the :ref:`Ansible Forum` tagged with ``ansible-core``. .. toctree:: :maxdepth: 1 :glob: :caption: ansible-core Roadmaps + ROADMAP_2_18 ROADMAP_2_17 ROADMAP_2_16 ROADMAP_2_15 diff --git a/docs/docsite/rst/roadmap/ansible_roadmap_index.rst b/docs/docsite/rst/roadmap/ansible_roadmap_index.rst index b09d5babd54..410fc3fbc38 100644 --- a/docs/docsite/rst/roadmap/ansible_roadmap_index.rst +++ b/docs/docsite/rst/roadmap/ansible_roadmap_index.rst @@ -12,18 +12,16 @@ Each roadmap offers a *best guess*, based on the Ansible team's experience and o Each roadmap is published both as an idea of what is upcoming in Ansible, and as a medium for seeking further feedback from the community. -You can submit feedback on the current roadmap in multiple ways: +You can submit feedback on the current roadmap by creating a :ref:`community topic`. -- Edit the agenda of an `Ansible Community Meeting `_ (preferred) -- Post on the ``#ansible-community`` chat channel (using Matrix at ansible.im or using IRC at `irc.libera.chat `_) - -See :ref:`Ansible communication channels ` for details on how to join and use our chat channels. +Visit the :ref:`Ansible communication guide` for details on how to join and use Ansible communication platforms. .. toctree:: :maxdepth: 1 :glob: :caption: Ansible Release Roadmaps + COLLECTIONS_11 COLLECTIONS_10 COLLECTIONS_9 COLLECTIONS_8 diff --git a/docs/docsite/rst/shared_snippets/basic_concepts.txt b/docs/docsite/rst/shared_snippets/basic_concepts.txt index a4f7ce06130..2b2c3efeeb6 100644 --- a/docs/docsite/rst/shared_snippets/basic_concepts.txt +++ b/docs/docsite/rst/shared_snippets/basic_concepts.txt @@ -2,7 +2,7 @@ Control node ============ The machine from which you run the Ansible CLI tools (``ansible-playbook`` , ``ansible``, ``ansible-vault`` and others). You can use any computer that meets the software requirements as a control node - laptops, shared desktops, and servers can all run Ansible. -You can also run Ansible in containers known as `Execution Environments `_. +You can also run Ansible in containers known as :ref:`Execution Environments`. Multiple control nodes are possible, but Ansible itself does not coordinate across them, see ``AAP`` for such features. diff --git a/docs/docsite/rst/shared_snippets/installing_collections.txt b/docs/docsite/rst/shared_snippets/installing_collections.txt deleted file mode 100644 index e408ccf113b..00000000000 --- a/docs/docsite/rst/shared_snippets/installing_collections.txt +++ /dev/null @@ -1,72 +0,0 @@ - - -By default, ``ansible-galaxy collection install`` uses https://galaxy.ansible.com as the Galaxy server (as listed in the -:file:`ansible.cfg` file under :ref:`galaxy_server`). You do not need any further configuration. -By default, Ansible installs the collection in ``~/.ansible/collections`` under the ``ansible_collections`` directory. - -See :ref:`Configuring the ansible-galaxy client ` if you are using any other Galaxy server, such as Red Hat Automation Hub. - -To install a collection hosted in Galaxy: - -.. code-block:: bash - - ansible-galaxy collection install my_namespace.my_collection - -To upgrade a collection to the latest available version from the Galaxy server you can use the ``--upgrade`` option: - -.. code-block:: bash - - ansible-galaxy collection install my_namespace.my_collection --upgrade - -You can also directly use the tarball from your build: - -.. code-block:: bash - - ansible-galaxy collection install my_namespace-my_collection-1.0.0.tar.gz -p ./collections - -You can build and install a collection from a local source directory. The ``ansible-galaxy`` utility builds the collection using the ``MANIFEST.json`` or ``galaxy.yml`` -metadata in the directory. - -.. code-block:: bash - - ansible-galaxy collection install /path/to/collection -p ./collections - -You can also install multiple collections in a namespace directory. - -.. code-block:: text - - ns/ - ├── collection1/ - │ ├── MANIFEST.json - │ └── plugins/ - └── collection2/ - ├── galaxy.yml - └── plugins/ - -.. code-block:: bash - - ansible-galaxy collection install /path/to/ns -p ./collections - -.. note:: - The install command automatically appends the path ``ansible_collections`` to the one specified with the ``-p`` option unless the - parent directory is already in a folder called ``ansible_collections``. - - -When using the ``-p`` option to specify the install path, use one of the values configured in :ref:`COLLECTIONS_PATHS`, as this is -where Ansible itself will expect to find collections. If you don't specify a path, ``ansible-galaxy collection install`` installs -the collection to the first path defined in :ref:`COLLECTIONS_PATHS`, which by default is ``~/.ansible/collections`` - -You can also keep a collection adjacent to the current playbook, under a ``collections/ansible_collections/`` directory structure. - -.. code-block:: text - - ./ - ├── play.yml - ├── collections/ - │ └── ansible_collections/ - │ └── my_namespace/ - │ └── my_collection/ - - -See :ref:`collection_structure` for details on the collection directory structure. - diff --git a/docs/docsite/rst/shared_snippets/installing_collections_git_repo.txt b/docs/docsite/rst/shared_snippets/installing_collections_git_repo.txt index 045887389a0..c0f158de519 100644 --- a/docs/docsite/rst/shared_snippets/installing_collections_git_repo.txt +++ b/docs/docsite/rst/shared_snippets/installing_collections_git_repo.txt @@ -1,4 +1,4 @@ -You can install a collection from a git repository instead of from Galaxy or Automation Hub. As a developer, installing from a git repository lets you review your collection before you create the tarball and publish the collection. As a user, installing from a git repository lets you use collections or versions that are not in Galaxy or Automation Hub yet. +You can install a collection from a git repository instead of from Galaxy or Automation Hub. As a developer, installing from a git repository lets you review your collection before you create the tarball and publish the collection. As a user, installing from a git repository lets you use collections or versions that are not in Galaxy or Automation Hub yet. This functionality is meant as a minimal shortcut for developers of content as previously described, and git repositories may not support the full set of features from the ``ansible-galaxy`` CLI. In complex cases, a more flexible option may be to ``git clone`` the repository into the correct file structure of the collection installation directory. The repository must contain a ``galaxy.yml`` or ``MANIFEST.json`` file. This file provides metadata such as the version number and namespace of the collection. diff --git a/docs/docsite/rst/tips_tricks/ansible_tips_tricks.rst b/docs/docsite/rst/tips_tricks/ansible_tips_tricks.rst index 54d2ecbd749..88746d3d8be 100644 --- a/docs/docsite/rst/tips_tricks/ansible_tips_tricks.rst +++ b/docs/docsite/rst/tips_tricks/ansible_tips_tricks.rst @@ -132,7 +132,7 @@ These tips apply to using Ansible, rather than to Ansible artifacts. Use Execution Environments -------------------------- -Reduce complexity with portable container images known as `Execution Environments `_. +Reduce complexity with portable container images known as :ref:`Execution Environments`. Try it in staging first ----------------------- @@ -206,7 +206,5 @@ This pulls in variables from the `group_vars/os_CentOS.yml` file. Learn how to extend Ansible by writing your own modules :ref:`intro_patterns` Learn about how to select hosts - `GitHub examples directory `_ - Complete playbook files from the GitHub project source - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/tips_tricks/sample_setup.rst b/docs/docsite/rst/tips_tricks/sample_setup.rst index 60386cc8807..351095e8fdb 100644 --- a/docs/docsite/rst/tips_tricks/sample_setup.rst +++ b/docs/docsite/rst/tips_tricks/sample_setup.rst @@ -4,7 +4,7 @@ Sample Ansible setup ******************** -You have learned about playbooks, inventory, roles, and variables. This section combines all those elements and outlines a sample setup for automating a web service. You can find more example playbooks that illustrate these patterns in our `ansible-examples repository `_. (NOTE: These examples do not use all of the latest features, but are still an excellent reference.). +You have learned about playbooks, inventory, roles, and variables. This section combines all those elements and outlines a sample setup for automating a web service. The sample setup organizes playbooks, roles, inventory, and files with variables by function. Tags at the play and task level provide greater granularity and control. This is a powerful and flexible approach, but there are other ways to organize Ansible content. Your usage of Ansible should fit your needs, so feel free to modify this approach and organize your content accordingly. @@ -289,7 +289,5 @@ If a playbook has a :file:`./library` directory relative to its YAML file, you c Learn how to extend Ansible by writing your own modules :ref:`intro_patterns` Learn about how to select hosts - `GitHub examples directory `_ - Complete playbook files from the GitHub project source - `Mailing List `_ - Questions? Help? Ideas? Stop by the list on Google Groups + :ref:`Communication` + Got questions? Need help? Want to share your ideas? Visit the Ansible communication guide diff --git a/docs/docsite/rst/user_guide/windows_faq.rst b/docs/docsite/rst/user_guide/windows_faq.rst index 0dc92a9f329..ec937f8d13b 100644 --- a/docs/docsite/rst/user_guide/windows_faq.rst +++ b/docs/docsite/rst/user_guide/windows_faq.rst @@ -3,4 +3,4 @@ Windows Frequently Asked Questions ================================== -This page has moved to :ref:`windows_faq`. \ No newline at end of file +This page has moved to :ref:`working_with_windows`. \ No newline at end of file diff --git a/docs/docsite/rst/user_guide/windows_setup.rst b/docs/docsite/rst/user_guide/windows_setup.rst index 95ac6457436..1614b3fd499 100644 --- a/docs/docsite/rst/user_guide/windows_setup.rst +++ b/docs/docsite/rst/user_guide/windows_setup.rst @@ -3,4 +3,4 @@ Setting up a Windows Host ========================= -This page has moved to :ref:`windows_setup`. \ No newline at end of file +This page has moved to :ref:`working_with_windows`. \ No newline at end of file diff --git a/docs/docsite/rst/vault_guide/vault_managing_passwords.rst b/docs/docsite/rst/vault_guide/vault_managing_passwords.rst index e83eecf1c29..4a685f54639 100644 --- a/docs/docsite/rst/vault_guide/vault_managing_passwords.rst +++ b/docs/docsite/rst/vault_guide/vault_managing_passwords.rst @@ -73,6 +73,12 @@ Storing passwords in files To store a vault password in a file, enter the password as a string on a single line in the file. Make sure the permissions on the file are appropriate. Do not add password files to source control. +When you run a playbook that uses a vault password stored in a file, specify the file within the ``--vault-password-file`` flag. For example: + +.. code-block:: bash + + ansible-playbook --extra-vars @secrets.enc --vault-password-file secrets.pass + .. _vault_password_client_scripts: Storing passwords in third-party tools with vault password client scripts diff --git a/examples/scripts/uptime.py b/examples/scripts/uptime.py deleted file mode 100755 index d77a5fb5660..00000000000 --- a/examples/scripts/uptime.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import json -import shutil - -import ansible.constants as C -from ansible.executor.task_queue_manager import TaskQueueManager -from ansible.module_utils.common.collections import ImmutableDict -from ansible.inventory.manager import InventoryManager -from ansible.parsing.dataloader import DataLoader -from ansible.playbook.play import Play -from ansible.plugins.callback import CallbackBase -from ansible.vars.manager import VariableManager -from ansible import context - - -# Create a callback plugin so we can capture the output -class ResultsCollectorJSONCallback(CallbackBase): - """A sample callback plugin used for performing an action as results come in. - - If you want to collect all results into a single object for processing at - the end of the execution, look into utilizing the ``json`` callback plugin - or writing your own custom callback plugin. - """ - - def __init__(self, *args, **kwargs): - super(ResultsCollectorJSONCallback, self).__init__(*args, **kwargs) - self.host_ok = {} - self.host_unreachable = {} - self.host_failed = {} - - def v2_runner_on_unreachable(self, result): - host = result._host - self.host_unreachable[host.get_name()] = result - - def v2_runner_on_ok(self, result, *args, **kwargs): - """Print a json representation of the result. - - Also, store the result in an instance attribute for retrieval later - """ - host = result._host - self.host_ok[host.get_name()] = result - print(json.dumps({host.name: result._result}, indent=4)) - - def v2_runner_on_failed(self, result, *args, **kwargs): - host = result._host - self.host_failed[host.get_name()] = result - - -def main(): - host_list = ['localhost', 'www.example.com', 'www.google.com'] - # since the API is constructed for CLI it expects certain options to always be set in the context object - context.CLIARGS = ImmutableDict(connection='smart', module_path=['/to/mymodules', '/usr/share/ansible'], forks=10, become=None, - become_method=None, become_user=None, check=False, diff=False, verbosity=0) - # required for - # https://github.com/ansible/ansible/blob/devel/lib/ansible/inventory/manager.py#L204 - sources = ','.join(host_list) - if len(host_list) == 1: - sources += ',' - - # initialize needed objects - loader = DataLoader() # Takes care of finding and reading yaml, json and ini files - passwords = dict(vault_pass='secret') - - # Instantiate our ResultsCollectorJSONCallback for handling results as they come in. Ansible expects this to be one of its main display outlets - results_callback = ResultsCollectorJSONCallback() - - # create inventory, use path to host config file as source or hosts in a comma separated string - inventory = InventoryManager(loader=loader, sources=sources) - - # variable manager takes care of merging all the different sources to give you a unified view of variables available in each context - variable_manager = VariableManager(loader=loader, inventory=inventory) - - # instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks - # IMPORTANT: This also adds library dirs paths to the module loader - # IMPORTANT: and so it must be initialized before calling `Play.load()`. - tqm = TaskQueueManager( - inventory=inventory, - variable_manager=variable_manager, - loader=loader, - passwords=passwords, - stdout_callback=results_callback, # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout - ) - - # create data structure that represents our play, including tasks, this is basically what our YAML loader does internally. - play_source = dict( - name="Ansible Play", - hosts=host_list, - gather_facts='no', - tasks=[ - dict(action=dict(module='shell', args='ls'), register='shell_out'), - dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}'))), - dict(action=dict(module='command', args=dict(cmd='/usr/bin/uptime'))), - ] - ) - - # Create play object, playbook objects use .load instead of init or new methods, - # this will also automatically create the task objects from the info provided in play_source - play = Play().load(play_source, variable_manager=variable_manager, loader=loader) - - # Actually run it - try: - result = tqm.run(play) # most interesting data for a play is actually sent to the callback's methods - finally: - # we always need to cleanup child procs and the structures we use to communicate with them - tqm.cleanup() - if loader: - loader.cleanup_all_tmp_files() - - # Remove ansible tmpdir - shutil.rmtree(C.DEFAULT_LOCAL_TMP, True) - - print("UP ***********") - for host, result in results_callback.host_ok.items(): - print('{0} >>> {1}'.format(host, result._result['stdout'])) - - print("FAILED *******") - for host, result in results_callback.host_failed.items(): - print('{0} >>> {1}'.format(host, result._result['msg'])) - - print("DOWN *********") - for host, result in results_callback.host_unreachable.items(): - print('{0} >>> {1}'.format(host, result._result['msg'])) - - -if __name__ == '__main__': - main() diff --git a/hacking/README.md b/hacking/README.md index 03c0868676a..2da6c9fccbd 100644 --- a/hacking/README.md +++ b/hacking/README.md @@ -5,7 +5,7 @@ env-setup --------- The 'env-setup' script modifies your environment to allow you to run -ansible from a git checkout using python >= 3.8. +ansible from a Git checkout using Python >= 3.8. First, set up your environment to run from the checkout: diff --git a/hacking/build_library/build_ansible/command_plugins/docs_build.py b/hacking/build_library/build_ansible/command_plugins/docs_build.py index e064bfdddad..d0843b91171 100644 --- a/hacking/build_library/build_ansible/command_plugins/docs_build.py +++ b/hacking/build_library/build_ansible/command_plugins/docs_build.py @@ -39,7 +39,7 @@ class NoSuchFile(Exception): # Helpers # -def find_latest_ansible_dir(build_data_working): +def find_latest_ansible_dir(build_data_working) -> tuple[str, "packaging.version.Version"]: """Find the most recent ansible major version.""" # imports here so that they don't cause unnecessary deps for all of the plugins from packaging.version import InvalidVersion, Version @@ -47,7 +47,7 @@ def find_latest_ansible_dir(build_data_working): ansible_directories = glob.glob(os.path.join(build_data_working, '[0-9.]*')) # Find the latest ansible version directory - latest = None + latest_dir = None latest_ver = Version('0') for directory_name in (d for d in ansible_directories if os.path.isdir(d)): try: @@ -61,12 +61,12 @@ def find_latest_ansible_dir(build_data_working): if new_version > latest_ver: latest_ver = new_version - latest = directory_name + latest_dir = directory_name - if latest is None: + if latest_dir is None: raise NoSuchFile('Could not find an ansible data directory in {0}'.format(build_data_working)) - return latest + return latest_dir, latest_ver def parse_deps_file(filename): @@ -84,7 +84,7 @@ def write_deps_file(filename, deps_data): f.write(f'{key}: {value}\n') -def find_latest_deps_file(build_data_working, ansible_version): +def find_latest_deps_file(build_data_working, ansible_version: str) -> tuple[str, "packaging.version.Version"]: """Find the most recent ansible deps file for the given ansible major version.""" # imports here so that they don't cause unnecessary deps for all of the plugins from packaging.version import Version @@ -95,19 +95,19 @@ def find_latest_deps_file(build_data_working, ansible_version): raise Exception('No deps files exist for version {0}'.format(ansible_version)) # Find the latest version of the deps file for this major version - latest = None + latest_deps_file = None latest_ver = Version('0') for filename in deps_files: deps_data = parse_deps_file(filename) new_version = Version(deps_data['_ansible_version']) if new_version > latest_ver: latest_ver = new_version - latest = filename + latest_deps_file = filename - if latest is None: + if latest_deps_file is None: raise NoSuchFile('Could not find an ansible deps file in {0}'.format(data_dir)) - return latest + return latest_deps_file, latest_ver # @@ -133,9 +133,18 @@ def generate_core_docs(args): f.write(yaml.dump(deps_file_contents)) # Generate the plugin rst - return antsibull_docs.run(['antsibull-docs', 'stable', '--deps-file', modified_deps_file, - '--ansible-core-source', str(args.top_dir), - '--dest-dir', args.output_dir]) + full_command = [ + 'antsibull-docs', + 'stable', + '--deps-file', + modified_deps_file, + '--ansible-core-source', + str(args.top_dir), + '--dest-dir', + args.output_dir, + ] + print(f"Running {full_command!r}:") + return antsibull_docs.run(full_command) # If we make this more than just a driver for antsibull: # Run other rst generation @@ -164,16 +173,21 @@ def generate_full_docs(args): if args.ansible_build_data: build_data_working = args.ansible_build_data - ansible_version = args.ansible_version + ansible_version: str = args.ansible_version if ansible_version is None: - ansible_version = find_latest_ansible_dir(build_data_working) - params = ['devel', '--pieces-file', os.path.join(ansible_version, 'ansible.in')] + devel_dir, devel_version = find_latest_ansible_dir(build_data_working) + params = ['devel', '--pieces-file', 'ansible.in', '--major-version', str(devel_version.major)] + cwd = str(devel_dir) else: - latest_filename = find_latest_deps_file(build_data_working, ansible_version) + latest_deps_file, ansible_version_ver = find_latest_deps_file(build_data_working, ansible_version) + deps_dir = os.path.dirname(latest_deps_file) # Make a copy of the deps file so that we can set the ansible-core version we'll use modified_deps_file = os.path.join(tmp_dir, 'ansible.deps') - shutil.copyfile(latest_filename, modified_deps_file) + shutil.copyfile(latest_deps_file, modified_deps_file) + + # Make a copy of collection-meta.yaml + shutil.copyfile(os.path.join(deps_dir, 'collection-meta.yaml'), os.path.join(tmp_dir, 'collection-meta.yaml')) # Put our version of ansible-core into the deps file deps_data = parse_deps_file(modified_deps_file) @@ -182,12 +196,23 @@ def generate_full_docs(args): write_deps_file(modified_deps_file, deps_data) - params = ['stable', '--deps-file', modified_deps_file] + params = ['stable', '--deps-file', 'ansible.deps', '--version', str(ansible_version_ver)] + cwd = str(tmp_dir) - # Generate the plugin rst - return antsibull_docs.run(['antsibull-docs'] + params + - ['--ansible-core-source', str(args.top_dir), - '--dest-dir', args.output_dir]) + old_cwd = os.getcwd() + try: + os.chdir(cwd) + # Generate the plugin rst + full_command = ['antsibull-docs'] + params + [ + '--ansible-core-source', + os.path.join(old_cwd, str(args.top_dir)), + '--dest-dir', + os.path.join(old_cwd, args.output_dir), + ] + print(f"Running {full_command!r} in {cwd!r}:") + return antsibull_docs.run(full_command) + finally: + os.chdir(old_cwd) # If we make this more than just a driver for antsibull: # Run other rst generation @@ -199,7 +224,6 @@ class CollectionPluginDocs(Command): _ACTION_HELP = """Action to perform. full: Regenerate the rst for the full ansible website. core: Regenerate the rst for plugins in ansible-core and then build the website. - named: Regenerate the rst for the named plugins and then build the website. """ @classmethod @@ -212,7 +236,7 @@ def init_parser(cls, add_parser): ' hierarchy.') # I think we should make the actions a subparser but need to look in git history and see if # we tried that and changed it for some reason. - parser.add_argument('action', action='store', choices=('full', 'core', 'named'), + parser.add_argument('action', action='store', choices=('full', 'core'), default='full', help=cls._ACTION_HELP) parser.add_argument("-o", "--output-dir", action="store", dest="output_dir", default=DEFAULT_OUTPUT_DIR, @@ -249,7 +273,7 @@ def main(args): if args.action == 'core': return generate_core_docs(args) - # args.action == 'named' (Invalid actions are caught by argparse) - raise NotImplementedError('Building docs for specific files is not yet implemented') + + raise NotImplementedError('New actions have to be explicitly supported by the code') # return 0 diff --git a/hacking/pr_labeler/.gitignore b/hacking/pr_labeler/.gitignore new file mode 100644 index 00000000000..3feb78adc66 --- /dev/null +++ b/hacking/pr_labeler/.gitignore @@ -0,0 +1 @@ +*.egg-info/ diff --git a/hacking/pr_labeler/data/docs_team_info.md b/hacking/pr_labeler/data/docs_team_info.md deleted file mode 100644 index ceb5c67a51b..00000000000 --- a/hacking/pr_labeler/data/docs_team_info.md +++ /dev/null @@ -1,2 +0,0 @@ -Thanks for your Ansible docs contribution! We talk about Ansible documentation on matrix at [#docs:ansible.im](https://matrix.to/#/#docs:ansible.im) and on libera IRC at #ansible-docs if you ever want to join us and chat about the docs! We meet there on Tuesdays (see [the Ansible calendar](https://github.com/ansible/community/blob/main/meetings/README.md)) and welcome additions to our [weekly agenda items](https://forum.ansible.com/t/documentation-working-group-agenda/153) - scroll down to find the upcoming agenda and add a comment to put something new on that agenda. - diff --git a/hacking/pr_labeler/label.py b/hacking/pr_labeler/label.py deleted file mode 100644 index 160b20fbd62..00000000000 --- a/hacking/pr_labeler/label.py +++ /dev/null @@ -1,405 +0,0 @@ -# Copyright (C) 2023 Maxwell G -# SPDX-License-Identifier: GPL-3.0-or-later - -from __future__ import annotations - -import dataclasses -import json -import os -import re -from collections.abc import Callable, Collection -from contextlib import suppress -from functools import cached_property -from pathlib import Path -from typing import Any, ClassVar, Union - -import github -import github.Auth -import github.Issue -import github.PullRequest -import github.Repository -import typer -from codeowners import CodeOwners, OwnerTuple -from jinja2 import Environment, FileSystemLoader, StrictUndefined, select_autoescape - -OWNER = "ansible" -REPO = "ansible-documentation" -LABELS_BY_CODEOWNER: dict[OwnerTuple, list[str]] = { - ("TEAM", "@ansible/steering-committee"): ["sc_approval"], -} -HERE = Path(__file__).resolve().parent -ROOT = HERE.parent.parent -CODEOWNERS = (ROOT / ".github/CODEOWNERS").read_text("utf-8") -JINJA2_ENV = Environment( - loader=FileSystemLoader(HERE / "data"), - autoescape=select_autoescape(), - trim_blocks=True, - undefined=StrictUndefined, -) -NEW_CONTRIBUTOR_LABEL = "new_contributor" - -IssueOrPrCtx = Union["IssueLabelerCtx", "PRLabelerCtx"] -IssueOrPr = Union["github.Issue.Issue", "github.PullRequest.PullRequest"] - - -# TODO: If we end up needing to log more things with more granularity, -# switch to something like `logging` -def log(ctx: IssueOrPrCtx, *args: object) -> None: - print(f"{ctx.member.number}:", *args) - - -def get_repo( - args: GlobalArgs, authed: bool = True -) -> tuple[github.Github, github.Repository.Repository]: - gclient = github.Github( - auth=github.Auth.Token(os.environ["GITHUB_TOKEN"]) if authed else None, - ) - repo_obj = gclient.get_repo(args.full_repo) - return gclient, repo_obj - - -def get_event_info() -> dict[str, Any]: - event_json = os.environ.get("event_json") - if not event_json: - return {} - with suppress(json.JSONDecodeError): - return json.loads(event_json) - return {} - - -@dataclasses.dataclass() -class GlobalArgs: - owner: str - repo: str - use_author_association: bool - - @property - def full_repo(self) -> str: - return f"{self.owner}/{self.repo}" - - -@dataclasses.dataclass() -class LabelerCtx: - client: github.Github - repo: github.Repository.Repository - dry_run: bool - event_info: dict[str, Any] - issue: github.Issue.Issue - global_args: GlobalArgs - - TYPE: ClassVar[str] - - @property - def member(self) -> IssueOrPr: - raise NotImplementedError - - @property - def event_member(self) -> dict[str, Any]: - raise NotImplementedError - - @cached_property - def previously_labeled(self) -> frozenset[str]: - labels: set[str] = set() - events = ( - self.member.get_events() - if isinstance(self.member, github.Issue.Issue) - else self.member.get_issue_events() - ) - for event in events: - if event.event in ("labeled", "unlabeled"): - assert event.label - labels.add(event.label.name) - return frozenset(labels) - - -@dataclasses.dataclass() -class IssueLabelerCtx(LabelerCtx): - issue: github.Issue.Issue - - TYPE = "issue" - - @property - def member(self) -> IssueOrPr: - return self.issue - - @property - def event_member(self) -> dict[str, Any]: - return self.event_info.get("issue", {}) - - -@dataclasses.dataclass() -class PRLabelerCtx(LabelerCtx): - pr: github.PullRequest.PullRequest - - TYPE = "pull request" - - @property - def member(self) -> IssueOrPr: - return self.pr - - @property - def event_member(self) -> dict[str, Any]: - return self.event_info.get("pull_request", {}) - - -def create_comment(ctx: IssueOrPrCtx, body: str) -> None: - if ctx.dry_run: - return - if isinstance(ctx, IssueLabelerCtx): - ctx.issue.create_comment(body) - else: - ctx.pr.create_issue_comment(body) - - -def get_data_file(name: str, **kwargs: Any) -> str: - """ - Template a data file - """ - return JINJA2_ENV.get_template(name).render(**kwargs).rstrip("\n") - - -def create_boilerplate_comment(ctx: IssueOrPrCtx, name: str, **kwargs) -> None: - """ - Add a boilerplate comment if it hasn't already been added - """ - tmpl = get_data_file(name, ctx=ctx, **kwargs) - tmpl_lines = tmpl.splitlines() - last = tmpl_lines[-1] - if not (last.startswith("")): - raise ValueError( - "Last line must of the template" - " must have an identifying boilerplate comment" - ) - for comment in ctx.issue.get_comments(): - if comment.body.splitlines()[-1] == last: - log(ctx, name, "boilerplate was already commented") - return - msg = f"Templating {name} boilerplate" - if kwargs: - msg += f" with {kwargs}" - log(ctx, msg) - create_comment(ctx, tmpl) - - -def get_team_members(ctx: IssueOrPrCtx, team: str) -> list[str]: - """ - Get the members of a Github team - """ - return [ - user.login - for user in ctx.client.get_organization(ctx.repo.organization.login) - .get_team_by_slug(team) - .get_members() - ] - - -def handle_codeowner_labels(ctx: PRLabelerCtx) -> None: - labels = LABELS_BY_CODEOWNER.copy() - owners = CodeOwners(CODEOWNERS) - files = ctx.pr.get_files() - for file in files: - for owner in owners.of(file.filename): - if labels_to_add := labels.pop(owner, None): - add_label_if_new(ctx, labels_to_add) - if not labels: - return - - -def add_label_if_new(ctx: IssueOrPrCtx, labels: Collection[str] | str) -> None: - """ - Add a label to a PR if it wasn't added in the past - """ - labels = {labels} if isinstance(labels, str) else labels - labels = set(labels) - ctx.previously_labeled - if not labels: - return - log(ctx, "Adding labels", *map(repr, labels)) - if not ctx.dry_run: - ctx.member.add_to_labels(*labels) - - -def is_new_contributor_assoc(ctx: IssueOrPrCtx) -> bool: - """ - Determine whether a user has previously contributed. - Requires authentication as a regular user and does not work with an app - token. - """ - author_association = ctx.event_member.get( - "author_association", ctx.member.raw_data["author_association"] - ) - log(ctx, "author_association is", author_association) - return author_association in {"FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR"} - - -def is_new_contributor_manual(ctx: IssueOrPrCtx) -> bool: - """ - Determine whether a user has previously opened an issue or PR in this repo - without needing special API access. - """ - query_data = { - "repo": "ansible/ansible-documentation", - "author": ctx.issue.user.login, - # Avoid potential race condition where a new contributor opens multiple - # PRs or issues at once. - # Better to welcome twice than not at all. - "is": "closed", - } - issues = ctx.client.search_issues("", **query_data) - for issue in issues: - if issue.number != ctx.issue.number: - return False - return True - - -def new_contributor_welcome(ctx: IssueOrPrCtx) -> None: - """ - Welcome a new contributor to the repo with a message and a label - """ - is_new_contributor: Callable[[IssueOrPrCtx], bool] = ( - is_new_contributor_assoc - if ctx.global_args.use_author_association - else is_new_contributor_manual - ) - if ( - # Contributor has already been welcomed - NEW_CONTRIBUTOR_LABEL in ctx.previously_labeled - # - or not is_new_contributor(ctx) - ): - return - log(ctx, "Welcoming new contributor") - add_label_if_new(ctx, NEW_CONTRIBUTOR_LABEL) - create_comment(ctx, get_data_file("docs_team_info.md")) - - -def no_body_nag(ctx: IssueOrPrCtx) -> None: - """ - Complain if a non-bot user creates a PR or issue without body text - """ - if ctx.member.user.login.endswith("[bot]") or (ctx.member.body or "").strip(): - return - create_boilerplate_comment(ctx, "no_body_nag.md") - - -def warn_porting_guide_change(ctx: PRLabelerCtx) -> None: - """ - Complain if a non-bot user outside of the Release Management WG changes - porting_guide - """ - user = ctx.pr.user.login - if user.endswith("[bot]"): - return - - # If the API token does not have permisisons to view teams in the ansible - # org, fall back to an empty list. - members = [] - try: - members = get_team_members(ctx, "release-management-wg") - except github.UnknownObjectException: - log(ctx, "Failed to get members of @ansible/release-management-wg") - if user in members: - return - - matches: list[str] = [] - for file in ctx.pr.get_files(): - if re.fullmatch( - # Match community porting guides but not core porting guides - r"docs/docsite/rst/porting_guides/porting_guide_\d.*.rst", - file.filename, - ): - matches.append(file.filename) - if not matches: - return - create_boilerplate_comment(ctx, "porting_guide_changes.md", changed_files=matches) - - -APP = typer.Typer() - - -@APP.callback() -def cb( - *, - click_ctx: typer.Context, - owner: str = OWNER, - repo: str = REPO, - use_author_association: bool = False, -): - """ - Basic triager for ansible/ansible-documentation - """ - click_ctx.obj = GlobalArgs(owner, repo, use_author_association) - - -@APP.command(name="pr") -def process_pr( - *, - click_ctx: typer.Context, - pr_number: int, - dry_run: bool = False, - authed_dry_run: bool = False, - force_process_closed: bool = False, -) -> None: - global_args = click_ctx.ensure_object(GlobalArgs) - - authed = not dry_run - if authed_dry_run: - dry_run = True - authed = True - - gclient, repo = get_repo(global_args, authed) - pr = repo.get_pull(pr_number) - ctx = PRLabelerCtx( - client=gclient, - repo=repo, - pr=pr, - dry_run=dry_run, - event_info=get_event_info(), - issue=pr.as_issue(), - global_args=global_args, - ) - if not force_process_closed and pr.state != "open": - log(ctx, "Refusing to process closed ticket") - return - - handle_codeowner_labels(ctx) - new_contributor_welcome(ctx) - no_body_nag(ctx) - warn_porting_guide_change(ctx) - - -@APP.command(name="issue") -def process_issue( - *, - click_ctx: typer.Context, - issue_number: int, - dry_run: bool = False, - authed_dry_run: bool = False, - force_process_closed: bool = False, -) -> None: - global_args = click_ctx.ensure_object(GlobalArgs) - - authed = not dry_run - if authed_dry_run: - dry_run = True - authed = True - gclient, repo = get_repo(global_args, authed) - issue = repo.get_issue(issue_number) - ctx = IssueLabelerCtx( - client=gclient, - repo=repo, - issue=issue, - dry_run=dry_run, - event_info=get_event_info(), - global_args=global_args, - ) - if not force_process_closed and issue.state != "open": - log(ctx, "Refusing to process closed ticket") - return - - add_label_if_new(ctx, "needs_triage") - new_contributor_welcome(ctx) - no_body_nag(ctx) - - -if __name__ == "__main__": - APP() diff --git a/hacking/pr_labeler/pr_labeler/__init__.py b/hacking/pr_labeler/pr_labeler/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hacking/pr_labeler/pr_labeler/__main__.py b/hacking/pr_labeler/pr_labeler/__main__.py new file mode 100644 index 00000000000..a873c924ea0 --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/__main__.py @@ -0,0 +1,13 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Module entrypoint +""" + +from __future__ import annotations + +from .cli import APP + +if __name__ == "__main__": + APP() diff --git a/hacking/pr_labeler/pr_labeler/actions.py b/hacking/pr_labeler/pr_labeler/actions.py new file mode 100644 index 00000000000..018deff1f80 --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/actions.py @@ -0,0 +1,138 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Triager action functions +""" + +from __future__ import annotations + +import re +from collections.abc import Callable, Collection +from typing import TYPE_CHECKING + +import github +from codeowners import CodeOwners + +from .constants import CODEOWNERS, LABELS_BY_CODEOWNER, NEW_CONTRIBUTOR_LABEL +from .github_utils import ( + create_comment, + get_team_members, + is_new_contributor_assoc, + is_new_contributor_manual, +) +from .jinja import get_data_file +from .utils import log + +if TYPE_CHECKING: + from .cli_context import IssueOrPrCtx, PRLabelerCtx + + +def create_boilerplate_comment(ctx: IssueOrPrCtx, name: str, **kwargs) -> None: + """ + Add a boilerplate comment if it hasn't already been added + """ + tmpl = get_data_file(name, ctx=ctx, **kwargs) + tmpl_lines = tmpl.splitlines() + last = tmpl_lines[-1] + if not (last.startswith("")): + raise ValueError( + "Last line must of the template" + " must have an identifying boilerplate comment" + ) + for comment in ctx.issue.get_comments(): + if comment.body.splitlines()[-1] == last: + log(ctx, name, "boilerplate was already commented") + return + msg = f"Templating {name} boilerplate" + if kwargs: + msg += f" with {kwargs}" + log(ctx, msg) + create_comment(ctx, tmpl) + + +def add_label_if_new(ctx: IssueOrPrCtx, labels: Collection[str] | str) -> None: + """ + Add a label to a PR if it wasn't added in the past + """ + labels = {labels} if isinstance(labels, str) else labels + labels = set(labels) - ctx.previously_labeled + if not labels: + return + log(ctx, "Adding labels", *map(repr, labels)) + if not ctx.dry_run: + ctx.member.add_to_labels(*labels) + + +def handle_codeowner_labels(ctx: PRLabelerCtx) -> None: + labels = LABELS_BY_CODEOWNER.copy() + owners = CodeOwners(CODEOWNERS) + files = ctx.pr.get_files() + for file in files: + for owner in owners.of(file.filename): + if labels_to_add := labels.pop(owner, None): + add_label_if_new(ctx, labels_to_add) + if not labels: + return + + +def new_contributor_welcome(ctx: IssueOrPrCtx) -> None: + """ + Welcome a new contributor to the repo with a message and a label + """ + is_new_contributor: Callable[[IssueOrPrCtx], bool] = ( + is_new_contributor_assoc + if ctx.global_args.use_author_association + else is_new_contributor_manual + ) + if ( + # Contributor has already been welcomed + NEW_CONTRIBUTOR_LABEL in ctx.previously_labeled + # + or not is_new_contributor(ctx) + ): + return + log(ctx, "Welcoming new contributor") + add_label_if_new(ctx, NEW_CONTRIBUTOR_LABEL) + create_comment(ctx, get_data_file("docs_team_info.md")) + + +def warn_porting_guide_change(ctx: PRLabelerCtx) -> None: + """ + Complain if a non-bot user outside of the Release Management WG changes + porting_guide + """ + user = ctx.pr.user.login + if user.endswith("[bot]"): + return + + # If the API token does not have permisisons to view teams in the ansible + # org, fall back to an empty list. + members = [] + try: + members = get_team_members(ctx, "release-management-wg") + except github.UnknownObjectException: + log(ctx, "Failed to get members of @ansible/release-management-wg") + if user in members: + return + + matches: list[str] = [] + for file in ctx.pr.get_files(): + if re.fullmatch( + # Match community porting guides but not core porting guides + r"docs/docsite/rst/porting_guides/porting_guide_\d.*.rst", + file.filename, + ): + matches.append(file.filename) + if not matches: + return + create_boilerplate_comment(ctx, "porting_guide_changes.md", changed_files=matches) + + +def no_body_nag(ctx: IssueOrPrCtx) -> None: + """ + Complain if a non-bot user creates a PR or issue without body text + """ + if ctx.member.user.login.endswith("[bot]") or (ctx.member.body or "").strip(): + return + create_boilerplate_comment(ctx, "no_body_nag.md") diff --git a/hacking/pr_labeler/pr_labeler/cli.py b/hacking/pr_labeler/pr_labeler/cli.py new file mode 100644 index 00000000000..8e7b15e9529 --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/cli.py @@ -0,0 +1,113 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +CLI entrypoints +""" + +from __future__ import annotations + +import typer + +from .actions import ( + add_label_if_new, + handle_codeowner_labels, + new_contributor_welcome, + no_body_nag, + warn_porting_guide_change, +) +from .cli_context import GlobalArgs, IssueLabelerCtx, PRLabelerCtx +from .constants import OWNER, REPO +from .github_utils import get_event_info, get_repo +from .utils import log + +APP = typer.Typer() + + +@APP.callback() +def cb( + *, + click_ctx: typer.Context, + owner: str = OWNER, + repo: str = REPO, + use_author_association: bool = False, +): + """ + Basic triager for ansible/ansible-documentation + """ + click_ctx.obj = GlobalArgs(owner, repo, use_author_association) + + +@APP.command(name="pr") +def process_pr( + *, + click_ctx: typer.Context, + pr_number: int, + dry_run: bool = False, + authed_dry_run: bool = False, + force_process_closed: bool = False, +) -> None: + global_args = click_ctx.ensure_object(GlobalArgs) + + authed = not dry_run + if authed_dry_run: + dry_run = True + authed = True + + gclient, repo = get_repo(global_args.full_repo, authed) + pr = repo.get_pull(pr_number) + ctx = PRLabelerCtx( + client=gclient, + repo=repo, + pr=pr, + dry_run=dry_run, + event_info=get_event_info(), + issue=pr.as_issue(), + global_args=global_args, + ) + if not force_process_closed and pr.state != "open": + log(ctx, "Refusing to process closed ticket") + return + + handle_codeowner_labels(ctx) + new_contributor_welcome(ctx) + no_body_nag(ctx) + warn_porting_guide_change(ctx) + + +@APP.command(name="issue") +def process_issue( + *, + click_ctx: typer.Context, + issue_number: int, + dry_run: bool = False, + authed_dry_run: bool = False, + force_process_closed: bool = False, +) -> None: + global_args = click_ctx.ensure_object(GlobalArgs) + + authed = not dry_run + if authed_dry_run: + dry_run = True + authed = True + gclient, repo = get_repo(global_args.full_repo, authed) + issue = repo.get_issue(issue_number) + ctx = IssueLabelerCtx( + client=gclient, + repo=repo, + issue=issue, + dry_run=dry_run, + event_info=get_event_info(), + global_args=global_args, + ) + if not force_process_closed and issue.state != "open": + log(ctx, "Refusing to process closed ticket") + return + + add_label_if_new(ctx, "needs_triage") + new_contributor_welcome(ctx) + no_body_nag(ctx) + + +if __name__ == "__main__": + APP() diff --git a/hacking/pr_labeler/pr_labeler/cli_context.py b/hacking/pr_labeler/pr_labeler/cli_context.py new file mode 100644 index 00000000000..484a2a9f00b --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/cli_context.py @@ -0,0 +1,99 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +CLI context objects +""" + +from __future__ import annotations + +import dataclasses +from functools import cached_property +from typing import TYPE_CHECKING, Any, ClassVar + +import github +import github.Issue +import github.PullRequest +import github.Repository + +if TYPE_CHECKING: + from typing_extensions import TypeAlias + + from .github_utils import IssueOrPr + +IssueOrPrCtx: TypeAlias = "IssueLabelerCtx | PRLabelerCtx" + + +@dataclasses.dataclass() +class GlobalArgs: + owner: str + repo: str + use_author_association: bool + + @property + def full_repo(self) -> str: + return f"{self.owner}/{self.repo}" + + +@dataclasses.dataclass() +class LabelerCtx: + client: github.Github + repo: github.Repository.Repository + dry_run: bool + event_info: dict[str, Any] + issue: github.Issue.Issue + global_args: GlobalArgs + + TYPE: ClassVar[str] + + @property + def member(self) -> IssueOrPr: + raise NotImplementedError + + @property + def event_member(self) -> dict[str, Any]: + raise NotImplementedError + + @cached_property + def previously_labeled(self) -> frozenset[str]: + labels: set[str] = set() + events = ( + self.member.get_events() + if isinstance(self.member, github.Issue.Issue) + else self.member.get_issue_events() + ) + for event in events: + if event.event in ("labeled", "unlabeled"): + assert event.label + labels.add(event.label.name) + return frozenset(labels) + + +@dataclasses.dataclass() +class IssueLabelerCtx(LabelerCtx): + issue: github.Issue.Issue + + TYPE = "issue" + + @property + def member(self) -> IssueOrPr: + return self.issue + + @property + def event_member(self) -> dict[str, Any]: + return self.event_info.get("issue", {}) + + +@dataclasses.dataclass() +class PRLabelerCtx(LabelerCtx): + pr: github.PullRequest.PullRequest + + TYPE = "pull request" + + @property + def member(self) -> IssueOrPr: + return self.pr + + @property + def event_member(self) -> dict[str, Any]: + return self.event_info.get("pull_request", {}) diff --git a/hacking/pr_labeler/pr_labeler/constants.py b/hacking/pr_labeler/pr_labeler/constants.py new file mode 100644 index 00000000000..949de61370f --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/constants.py @@ -0,0 +1,22 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Constants for the tagging script +""" + +from __future__ import annotations + +from pathlib import Path + +from codeowners import OwnerTuple + +OWNER = "ansible" +REPO = "ansible-documentation" +LABELS_BY_CODEOWNER: dict[OwnerTuple, list[str]] = { + ("TEAM", "@ansible/steering-committee"): ["sc_approval"], +} +HERE = Path(__file__).resolve().parent +ROOT = HERE.parent.parent.parent +CODEOWNERS = (ROOT / ".github/CODEOWNERS").read_text("utf-8") +NEW_CONTRIBUTOR_LABEL = "new_contributor" diff --git a/hacking/pr_labeler/pr_labeler/data/docs_team_info.md b/hacking/pr_labeler/pr_labeler/data/docs_team_info.md new file mode 100644 index 00000000000..e850a21c012 --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/data/docs_team_info.md @@ -0,0 +1,2 @@ +Thanks for your Ansible docs contribution! We talk about Ansible documentation on Matrix at [#docs:ansible.im](https://matrix.to/#/#docs:ansible.im) if you ever want to join us and chat about the docs! We meet on Matrix every Tuesday. See [the Ansible calendar](https://forum.ansible.com/upcoming-events) for meeting details. We welcome additions to our [weekly agenda items](https://forum.ansible.com/t/documentation-working-group-agenda/153/7) too. You can add the `dawgs-meeting` tag to a forum topic to bring it up at the next meeting. + diff --git a/hacking/pr_labeler/data/no_body_nag.md b/hacking/pr_labeler/pr_labeler/data/no_body_nag.md similarity index 100% rename from hacking/pr_labeler/data/no_body_nag.md rename to hacking/pr_labeler/pr_labeler/data/no_body_nag.md diff --git a/hacking/pr_labeler/data/porting_guide_changes.md b/hacking/pr_labeler/pr_labeler/data/porting_guide_changes.md similarity index 100% rename from hacking/pr_labeler/data/porting_guide_changes.md rename to hacking/pr_labeler/pr_labeler/data/porting_guide_changes.md diff --git a/hacking/pr_labeler/pr_labeler/github_utils.py b/hacking/pr_labeler/pr_labeler/github_utils.py new file mode 100644 index 00000000000..dd1243da6c2 --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/github_utils.py @@ -0,0 +1,117 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Utilities for working with the Github API +""" + +from __future__ import annotations + +import json +import os +from contextlib import suppress +from typing import TYPE_CHECKING, Any + +import github +import github.Auth +import github.Issue +import github.PullRequest +import github.Repository + +from .cli_context import IssueLabelerCtx, IssueOrPrCtx +from .utils import log + +if TYPE_CHECKING: + from typing_extensions import TypeAlias + + +IssueOrPr: TypeAlias = "github.Issue.Issue | github.PullRequest.PullRequest" + + +def get_repo( + full_repo: str, + authed: bool = True, +) -> tuple[github.Github, github.Repository.Repository]: + """ + Create a Github client and return a `github.Repository.Repository` object + + Args: + full_repo: OWNER/NAME of the repository + authed: + Whether to create an authenticated Github client with the + `$GITHUB_TOKEN` environment variable as the key + """ + gclient = github.Github( + auth=github.Auth.Token(os.environ["GITHUB_TOKEN"]) if authed else None, + ) + repo_obj = gclient.get_repo(full_repo) + return gclient, repo_obj + + +def get_event_info() -> dict[str, Any]: + """ + Load Github event JSON data from `$event_data` + """ + event_json = os.environ.get("event_json") + if not event_json: + return {} + with suppress(json.JSONDecodeError): + return json.loads(event_json) + return {} + + +# Operations + + +def get_team_members(ctx: IssueOrPrCtx, team: str) -> list[str]: + """ + Get the members of a Github team + """ + return [ + user.login + for user in ctx.client.get_organization(ctx.repo.organization.login) + .get_team_by_slug(team) + .get_members() + ] + + +def create_comment(ctx: IssueOrPrCtx, body: str) -> None: + if ctx.dry_run: + return + if isinstance(ctx, IssueLabelerCtx): + ctx.issue.create_comment(body) + else: + ctx.pr.create_issue_comment(body) + + +def is_new_contributor_assoc(ctx: IssueOrPrCtx) -> bool: + """ + Determine whether a user has previously contributed. + Requires authentication as a regular user and does not work with an app + token. + """ + author_association = ctx.event_member.get( + "author_association", ctx.member.raw_data["author_association"] + ) + log(ctx, "author_association is", author_association) + return author_association in {"FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR"} + + +def is_new_contributor_manual(ctx: IssueOrPrCtx) -> bool: + """ + Determine whether a user has previously opened an issue or PR in this repo + without needing special API access. + """ + query_data = { + "repo": "ansible/ansible-documentation", + "author": ctx.issue.user.login, + # Avoid potential race condition where a new contributor opens multiple + # PRs or issues at once. + # Better to welcome twice than not at all. + "is": "closed", + } + issues = ctx.client.search_issues("", **query_data) + for issue in issues: + if issue.number != ctx.issue.number: + return False + return True diff --git a/hacking/pr_labeler/pr_labeler/jinja.py b/hacking/pr_labeler/pr_labeler/jinja.py new file mode 100644 index 00000000000..8d6ce1878e7 --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/jinja.py @@ -0,0 +1,26 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Utilities for Jinja2 templating +""" + +from __future__ import annotations + +from typing import Any, cast + +from jinja2 import Environment, PackageLoader, StrictUndefined, select_autoescape + +JINJA2_ENV = Environment( + loader=PackageLoader(cast(str, __package__), "data"), + autoescape=select_autoescape(), + trim_blocks=True, + undefined=StrictUndefined, +) + + +def get_data_file(name: str, **kwargs: Any) -> str: + """ + Template a data file + """ + return JINJA2_ENV.get_template(name).render(**kwargs).rstrip("\n") diff --git a/hacking/pr_labeler/pr_labeler/py.typed b/hacking/pr_labeler/pr_labeler/py.typed new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hacking/pr_labeler/pr_labeler/utils.py b/hacking/pr_labeler/pr_labeler/utils.py new file mode 100644 index 00000000000..62020e8509e --- /dev/null +++ b/hacking/pr_labeler/pr_labeler/utils.py @@ -0,0 +1,19 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Generic utilities +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .cli_context import IssueOrPrCtx + + +# TODO: If we end up needing to log more things with more granularity, +# switch to something like `logging` +def log(ctx: IssueOrPrCtx, *args: object) -> None: + print(f"{ctx.member.number}:", *args) diff --git a/hacking/pr_labeler/pyproject.toml b/hacking/pr_labeler/pyproject.toml new file mode 100644 index 00000000000..54e960789e2 --- /dev/null +++ b/hacking/pr_labeler/pyproject.toml @@ -0,0 +1,27 @@ +[build-system] +requires = ["setuptools"] +backend = "setuptools.build_meta" + +[project] +name = "ad-internal-pr-labeler" +description = "Internal package to triage ansible-documentation issues and PRs" +classifiers = [ + # Internal package + "Private :: Do Not Upload", +] +version = "0" +requires-python = ">=3.9" +dynamic = ["dependencies"] + +[project.scripts] +ad-triage = "pr_labeler.cli:APP" + +[tool.setuptools.dynamic] +dependencies = {file = "requirements.txt"} + +[tool.setuptools.packages.find] +where = ["."] +include = ["pr_labeler*"] + +[tool.uv] +cache-keys = [{ file = "requirements.txt" }] diff --git a/hacking/pr_labeler/requirements.txt b/hacking/pr_labeler/requirements.txt index b9cdb4ce636..7b037bcf275 100644 --- a/hacking/pr_labeler/requirements.txt +++ b/hacking/pr_labeler/requirements.txt @@ -1,4 +1,4 @@ codeowners jinja2 pygithub -typer +typer-slim diff --git a/hacking/tagger/tag.py b/hacking/tagger/tag.py index d2067583160..a404fc4887f 100755 --- a/hacking/tagger/tag.py +++ b/hacking/tagger/tag.py @@ -42,10 +42,10 @@ DEFAULT_ANSIBLE_CORE_CHECKOUT = ROOT.parent.joinpath("ansible") DEFAULT_REMOTE = "origin" DEFAULT_ACTIVE_BRANCHES: tuple[str, ...] = ( - "stable-2.14", "stable-2.15", "stable-2.16", "stable-2.17", + "stable-2.18", ) diff --git a/hacking/ticket_stubs/README.md b/hacking/ticket_stubs/README.md index 2ab983f76af..0c6e0f036b9 100644 --- a/hacking/ticket_stubs/README.md +++ b/hacking/ticket_stubs/README.md @@ -3,4 +3,4 @@ What's this? This is a directory of common responses to save some typing when responding to GitHub tickets to avoid some carpal tunnel syndrome events as Ansible maintainers deal with the ticket influx. -They are present in the project git repo (on GitHub) so it's easy for people to share and update these snippets of text. +They are present in the project Git repo (on GitHub) so it's easy for people to share and update these snippets of text. diff --git a/noxfile.py b/noxfile.py index fbb0beb757d..d9192fd6fca 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,6 +1,8 @@ from __future__ import annotations import os +import shlex +import shutil from argparse import ArgumentParser, BooleanOptionalAction from glob import iglob from pathlib import Path @@ -9,7 +11,7 @@ import nox LINT_FILES: tuple[str, ...] = ( - "hacking/pr_labeler/label.py", + "hacking/pr_labeler/pr_labeler", "hacking/tagger/tag.py", "noxfile.py", *iglob("docs/bin/*.py"), @@ -18,14 +20,55 @@ nox.options.sessions = ("clone-core", "lint", "checkers", "make") +def _set_env_verbose(session: nox.Session, **env: str) -> dict[str, str]: + """ + Helper function to verbosely set environment variables + """ + final_env: dict[str, str] = {} + for key, value in env.items(): + final_env[key] = value + session.log(f"export {key}={shlex.quote(value)}") + return final_env + + def install(session: nox.Session, *args, req: str, **kwargs): if PINNED: pip_constraint = f"tests/{req}.txt" - kwargs.setdefault("env", {})["PIP_CONSTRAINT"] = pip_constraint - session.log(f"export PIP_CONSTRAINT={pip_constraint!r}") + # Set constraint environment variables for both pip and uv to support + # the nox uv backend + env = _set_env_verbose( + session, + PIP_CONSTRAINT=pip_constraint, + UV_CONSTRAINT=pip_constraint, + UV_BUILD_CONSTRAINT=pip_constraint, + ) + kwargs.setdefault("env", {}).update(env) session.install("-r", f"tests/{req}.in", *args, **kwargs) +CONTAINER_ENGINES = ("podman", "docker") +CHOSEN_CONTAINER_ENGINE = os.environ.get("CONTAINER_ENGINE") +ACTIONLINT_IMAGE = "docker.io/rhysd/actionlint" + + +def _get_container_engine(session: nox.Session) -> str: + path: str | None = None + if CHOSEN_CONTAINER_ENGINE: + path = shutil.which(CHOSEN_CONTAINER_ENGINE) + if not path: + session.error( + f"CONTAINER_ENGINE {CHOSEN_CONTAINER_ENGINE!r} does not exist!" + ) + return path + for engine in CONTAINER_ENGINES: + if path := shutil.which(engine): + return path + session.error( + f"None of the following container engines were found: {CONTAINER_ENGINES}." + f" {session.name} requires a container engine installed." + ) + + @nox.session def static(session: nox.Session): """ @@ -74,12 +117,35 @@ def spelling(session: nox.Session): ) +@nox.session +def actionlint(session: nox.Session) -> None: + """ + Run actionlint to lint Github Actions workflows. + The actionlint tool is run in a Podman/Docker container. + """ + engine = _get_container_engine(session) + session.run_always(engine, "pull", ACTIONLINT_IMAGE, external=True) + session.run( + engine, + "run", + "--rm", + # fmt: off + "--volume", f"{Path.cwd()}:/pwd:z", + "--workdir", "/pwd", + # fmt: on + ACTIONLINT_IMAGE, + *session.posargs, + external=True, + ) + + @nox.session def lint(session: nox.Session): session.notify("typing") session.notify("static") session.notify("formatters") session.notify("spelling") + session.notify("actionlint") requirements_files = list( @@ -88,7 +154,7 @@ def lint(session: nox.Session): ) -@nox.session(name="pip-compile", python=["3.10"]) +@nox.session(name="pip-compile", python=["3.11"]) @nox.parametrize(["req"], requirements_files, requirements_files) def pip_compile(session: nox.Session, req: str): # .pip-tools.toml was introduced in v7 @@ -96,7 +162,14 @@ def pip_compile(session: nox.Session, req: str): # Use --upgrade by default unless a user passes -P. args = list(session.posargs) - if not any( + + # Support a custom --check flag to fail if pip-compile made any changes + # so we can check that that lockfiles are in sync with the input (.in) files. + check_mode = "--check" in args + if check_mode: + # Remove from args, as pip-compile doesn't actually support --check. + args.remove("--check") + elif not any( arg.startswith(("-P", "--upgrade-package", "--no-upgrade")) for arg in args ): args.append("--upgrade") @@ -110,6 +183,9 @@ def pip_compile(session: nox.Session, req: str): ) # fmt: on + if check_mode and session.run("git", "diff", "tests", silent=True, external=True): + session.error("Check mode: files were changed") + @nox.session(name="clone-core") def clone_core(session: nox.Session): @@ -117,7 +193,7 @@ def clone_core(session: nox.Session): Clone relevant portions of ansible-core from ansible/ansible into the current source tree to facilitate building docs. """ - session.run_always("python", "docs/bin/clone-core.py") + session.run_always("python", "docs/bin/clone-core.py", *session.posargs) checker_tests = [ @@ -125,6 +201,13 @@ def clone_core(session: nox.Session): ] +def _clone_core_check(session: nox.Session) -> None: + """ + Helper function to run the clone-core script with "--check" + """ + session.run("python", "docs/bin/clone-core.py", "--check") + + def _relaxed_parser(session: nox.Session) -> ArgumentParser: """ Generate an argument parser with a --relaxed option. @@ -159,6 +242,7 @@ def checkers(session: nox.Session, test: str): args = _relaxed_parser(session).parse_args(session.posargs) install(session, req="requirements-relaxed" if args.relaxed else "requirements") + _clone_core_check(session) session.run("make", "-C", "docs/docsite", "clean", external=True) session.run("python", "tests/checkers.py", test) @@ -175,8 +259,24 @@ def make(session: nox.Session): args = parser.parse_args(session.posargs) install(session, req="requirements-relaxed" if args.relaxed else "requirements") + _clone_core_check(session) make_args: list[str] = [ f"PYTHON={_env_python(session)}", *(args.make_args or ("clean", "coredocs")), ] session.run("make", "-C", "docs/docsite", *make_args, external=True) + + +@nox.session +def tag(session: nox.Session): + """ + Check the core repo for new releases and create tags in ansible-documentation + """ + install(session, req="tag") + args = list(session.posargs) + + # If run without any arguments, default to "tag" + if not any(arg.startswith(("hash", "mantag", "new-tags", "tag")) for arg in args): + args.append("tag") + + session.run("python", "hacking/tagger/tag.py", *args) diff --git a/tests/checkers/docs-build.py b/tests/checkers/docs-build.py index 433d00e6cf1..14e579b3ae2 100644 --- a/tests/checkers/docs-build.py +++ b/tests/checkers/docs-build.py @@ -25,8 +25,6 @@ def main(): 'MANIFEST.in', 'pyproject.toml', 'requirements.txt', - 'setup.cfg', - 'setup.py', ] # The tests write to the source tree, which isn't permitted for sanity tests. diff --git a/tests/constraints.in b/tests/constraints.in index 522d65804a4..30d0fca2285 100644 --- a/tests/constraints.in +++ b/tests/constraints.in @@ -2,4 +2,4 @@ # and antsibull-docs that production builds rely upon. sphinx == 7.2.5 -antsibull-docs == 2.10.0 # currently approved version +antsibull-docs == 2.15.0 # currently approved version diff --git a/tests/formatters.txt b/tests/formatters.txt index 5e1efcba758..25197481cf7 100644 --- a/tests/formatters.txt +++ b/tests/formatters.txt @@ -1,10 +1,10 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --allow-unsafe --output-file=tests/formatters.txt --strip-extras tests/formatters.in # -black==24.4.0 +black==24.8.0 # via -r tests/formatters.in click==8.1.7 # via black @@ -12,13 +12,9 @@ isort==5.13.2 # via -r tests/formatters.in mypy-extensions==1.0.0 # via black -packaging==24.0 +packaging==24.1 # via black pathspec==0.12.1 # via black -platformdirs==4.2.0 - # via black -tomli==2.0.1 - # via black -typing-extensions==4.11.0 +platformdirs==4.3.3 # via black diff --git a/tests/pr_labeler.in b/tests/pr_labeler.in new file mode 120000 index 00000000000..8ccfcc790b9 --- /dev/null +++ b/tests/pr_labeler.in @@ -0,0 +1 @@ +../hacking/pr_labeler/requirements.txt \ No newline at end of file diff --git a/tests/pr_labeler.txt b/tests/pr_labeler.txt new file mode 100644 index 00000000000..c98afc07fde --- /dev/null +++ b/tests/pr_labeler.txt @@ -0,0 +1,51 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --allow-unsafe --output-file=tests/pr_labeler.txt --strip-extras tests/pr_labeler.in +# +certifi==2024.8.30 + # via requests +cffi==1.17.1 + # via + # cryptography + # pynacl +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via typer-slim +codeowners==0.7.0 + # via -r tests/pr_labeler.in +cryptography==43.0.1 + # via pyjwt +deprecated==1.2.14 + # via pygithub +idna==3.8 + # via requests +jinja2==3.1.4 + # via -r tests/pr_labeler.in +markupsafe==2.1.5 + # via jinja2 +pycparser==2.22 + # via cffi +pygithub==2.4.0 + # via -r tests/pr_labeler.in +pyjwt==2.9.0 + # via pygithub +pynacl==1.5.0 + # via pygithub +requests==2.32.3 + # via pygithub +typer-slim==0.12.5 + # via -r tests/pr_labeler.in +typing-extensions==4.12.2 + # via + # codeowners + # pygithub + # typer-slim +urllib3==2.2.3 + # via + # pygithub + # requests +wrapt==1.16.0 + # via deprecated diff --git a/tests/requirements-relaxed.txt b/tests/requirements-relaxed.txt index 96fcc7bf6b9..51e21ed1d9d 100644 --- a/tests/requirements-relaxed.txt +++ b/tests/requirements-relaxed.txt @@ -1,12 +1,16 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --allow-unsafe --output-file=tests/requirements-relaxed.txt --strip-extras tests/requirements-relaxed.in # -aiofiles==23.2.1 - # via antsibull-core -aiohttp==3.9.5 +aiofiles==24.1.0 + # via + # antsibull-core + # antsibull-fileutils +aiohappyeyeballs==2.4.0 + # via aiohttp +aiohttp==3.10.5 # via # antsibull-core # antsibull-docs @@ -14,42 +18,48 @@ aiosignal==1.3.1 # via aiohttp alabaster==0.7.16 # via sphinx -annotated-types==0.6.0 +annotated-types==0.7.0 # via pydantic ansible-pygments==0.1.1 # via # antsibull-docs # sphinx-ansible-theme -antsibull-changelog==0.26.0 +antsibull-changelog==0.30.0 # via antsibull-docs -antsibull-core==3.0.1 +antsibull-core==3.3.0 # via antsibull-docs -antsibull-docs==2.10.0 +antsibull-docs==2.15.0 # via -r tests/requirements-relaxed.in -antsibull-docs-parser==1.0.1 +antsibull-docs-parser==1.1.0 # via antsibull-docs -async-timeout==4.0.3 - # via aiohttp +antsibull-docutils==1.0.0 + # via antsibull-changelog +antsibull-fileutils==1.0.1 + # via + # antsibull-changelog + # antsibull-core + # antsibull-docs asyncio-pool==0.6.0 # via antsibull-docs -attrs==23.2.0 +attrs==24.2.0 # via aiohttp -babel==2.14.0 +babel==2.16.0 # via # sphinx # sphinx-intl -build==1.2.1 +build==1.2.2 # via antsibull-core -certifi==2024.2.2 +certifi==2024.8.30 # via requests charset-normalizer==3.3.2 # via requests click==8.1.7 # via sphinx-intl -docutils==0.18.1 +docutils==0.20.1 # via # antsibull-changelog # antsibull-docs + # antsibull-docutils # rstcheck # sphinx # sphinx-rtd-theme @@ -57,24 +67,24 @@ frozenlist==1.4.1 # via # aiohttp # aiosignal -idna==3.7 +idna==3.9 # via # requests # yarl imagesize==1.4.1 # via sphinx -jinja2==3.1.3 +jinja2==3.1.4 # via # -r tests/requirements-relaxed.in # antsibull-docs # sphinx markupsafe==2.1.5 # via jinja2 -multidict==6.0.5 +multidict==6.1.0 # via # aiohttp # yarl -packaging==24.0 +packaging==24.1 # via # antsibull-changelog # antsibull-core @@ -83,29 +93,28 @@ packaging==24.0 # sphinx perky==0.9.2 # via antsibull-core -pydantic==2.7.0 +pydantic==2.9.1 # via # antsibull-core # antsibull-docs -pydantic-core==2.18.1 +pydantic-core==2.23.3 # via pydantic -pygments==2.17.2 +pygments==2.18.0 # via # ansible-pygments # sphinx -pyproject-hooks==1.0.0 +pyproject-hooks==1.1.0 # via build -pyyaml==6.0.1 +pyyaml==6.0.2 # via # -r tests/requirements-relaxed.in - # antsibull-changelog - # antsibull-core # antsibull-docs -requests==2.31.0 + # antsibull-fileutils +requests==2.32.3 # via sphinx resolvelib==1.0.1 # via -r tests/requirements-relaxed.in -rstcheck==5.0.0 +rstcheck==3.5.0 # via # -c tests/constraints-base.in # -r tests/requirements-relaxed.in @@ -120,7 +129,7 @@ six==1.16.0 # via twiggy snowballstemmer==2.2.0 # via sphinx -sphinx==7.3.7 +sphinx==7.4.7 # via # -r tests/requirements-relaxed.in # antsibull-docs @@ -136,47 +145,39 @@ sphinx-copybutton==0.5.2 # via -r tests/requirements-relaxed.in sphinx-intl==2.2.0 # via -r tests/requirements-relaxed.in -sphinx-notfound-page==1.0.0 +sphinx-notfound-page==1.0.4 # via -r tests/requirements-relaxed.in sphinx-rtd-theme==2.0.0 # via # -c tests/constraints-base.in # sphinx-ansible-theme -sphinxcontrib-applehelp==1.0.8 +sphinxcontrib-applehelp==2.0.0 # via sphinx -sphinxcontrib-devhelp==1.0.6 +sphinxcontrib-devhelp==2.0.0 # via sphinx -sphinxcontrib-htmlhelp==2.0.5 +sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jquery==4.1 # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.7 +sphinxcontrib-qthelp==2.0.0 # via sphinx -sphinxcontrib-serializinghtml==1.1.10 +sphinxcontrib-serializinghtml==2.0.0 # via sphinx -tomli==2.0.1 - # via - # build - # pyproject-hooks - # sphinx twiggy==0.5.1 # via # antsibull-core # antsibull-docs -types-docutils==0.18.3 - # via rstcheck -typing-extensions==4.11.0 +typing-extensions==4.12.2 # via # pydantic # pydantic-core - # rstcheck -urllib3==2.2.1 +urllib3==2.2.3 # via requests -yarl==1.9.4 +yarl==1.11.1 # via aiohttp # The following packages are considered to be unsafe in a requirements file: -setuptools==69.5.1 +setuptools==74.1.2 # via sphinx-intl diff --git a/tests/requirements.txt b/tests/requirements.txt index 6e7daafc6a9..8286a2188e3 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,12 +1,16 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --allow-unsafe --output-file=tests/requirements.txt --strip-extras tests/requirements.in # -aiofiles==23.2.1 - # via antsibull-core -aiohttp==3.9.5 +aiofiles==24.1.0 + # via + # antsibull-core + # antsibull-fileutils +aiohappyeyeballs==2.4.0 + # via aiohttp +aiohttp==3.10.5 # via # antsibull-core # antsibull-docs @@ -14,35 +18,40 @@ aiosignal==1.3.1 # via aiohttp alabaster==0.7.16 # via sphinx -annotated-types==0.6.0 +annotated-types==0.7.0 # via pydantic ansible-pygments==0.1.1 # via # antsibull-docs # sphinx-ansible-theme -antsibull-changelog==0.26.0 +antsibull-changelog==0.30.0 # via antsibull-docs -antsibull-core==3.0.1 +antsibull-core==3.3.0 # via antsibull-docs -antsibull-docs==2.10.0 +antsibull-docs==2.15.0 # via # -c tests/constraints.in # -r tests/requirements-relaxed.in -antsibull-docs-parser==1.0.1 +antsibull-docs-parser==1.1.0 # via antsibull-docs -async-timeout==4.0.3 - # via aiohttp +antsibull-docutils==1.0.0 + # via antsibull-changelog +antsibull-fileutils==1.0.1 + # via + # antsibull-changelog + # antsibull-core + # antsibull-docs asyncio-pool==0.6.0 # via antsibull-docs -attrs==23.2.0 +attrs==24.2.0 # via aiohttp -babel==2.14.0 +babel==2.16.0 # via # sphinx # sphinx-intl -build==1.2.1 +build==1.2.2 # via antsibull-core -certifi==2024.2.2 +certifi==2024.8.30 # via requests charset-normalizer==3.3.2 # via requests @@ -52,6 +61,7 @@ docutils==0.18.1 # via # antsibull-changelog # antsibull-docs + # antsibull-docutils # rstcheck # sphinx # sphinx-rtd-theme @@ -59,24 +69,24 @@ frozenlist==1.4.1 # via # aiohttp # aiosignal -idna==3.7 +idna==3.9 # via # requests # yarl imagesize==1.4.1 # via sphinx -jinja2==3.1.3 +jinja2==3.1.4 # via # -r tests/requirements-relaxed.in # antsibull-docs # sphinx markupsafe==2.1.5 # via jinja2 -multidict==6.0.5 +multidict==6.1.0 # via # aiohttp # yarl -packaging==24.0 +packaging==24.1 # via # antsibull-changelog # antsibull-core @@ -85,25 +95,24 @@ packaging==24.0 # sphinx perky==0.9.2 # via antsibull-core -pydantic==2.7.0 +pydantic==2.9.1 # via # antsibull-core # antsibull-docs -pydantic-core==2.18.1 +pydantic-core==2.23.3 # via pydantic -pygments==2.17.2 +pygments==2.18.0 # via # ansible-pygments # sphinx -pyproject-hooks==1.0.0 +pyproject-hooks==1.1.0 # via build -pyyaml==6.0.1 +pyyaml==6.0.2 # via # -r tests/requirements-relaxed.in - # antsibull-changelog - # antsibull-core # antsibull-docs -requests==2.31.0 + # antsibull-fileutils +requests==2.32.3 # via sphinx resolvelib==1.0.1 # via -r tests/requirements-relaxed.in @@ -139,46 +148,42 @@ sphinx-copybutton==0.5.2 # via -r tests/requirements-relaxed.in sphinx-intl==2.2.0 # via -r tests/requirements-relaxed.in -sphinx-notfound-page==1.0.0 +sphinx-notfound-page==1.0.4 # via -r tests/requirements-relaxed.in sphinx-rtd-theme==2.0.0 # via # -c tests/constraints-base.in # sphinx-ansible-theme -sphinxcontrib-applehelp==1.0.8 +sphinxcontrib-applehelp==2.0.0 # via sphinx -sphinxcontrib-devhelp==1.0.6 +sphinxcontrib-devhelp==2.0.0 # via sphinx -sphinxcontrib-htmlhelp==2.0.5 +sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jquery==4.1 # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.7 +sphinxcontrib-qthelp==2.0.0 # via sphinx -sphinxcontrib-serializinghtml==1.1.10 +sphinxcontrib-serializinghtml==2.0.0 # via sphinx -tomli==2.0.1 - # via - # build - # pyproject-hooks twiggy==0.5.1 # via # antsibull-core # antsibull-docs types-docutils==0.18.3 # via rstcheck -typing-extensions==4.11.0 +typing-extensions==4.12.2 # via # pydantic # pydantic-core # rstcheck -urllib3==2.2.1 +urllib3==2.2.3 # via requests -yarl==1.9.4 +yarl==1.11.1 # via aiohttp # The following packages are considered to be unsafe in a requirements file: -setuptools==69.5.1 +setuptools==74.1.2 # via sphinx-intl diff --git a/tests/spelling.txt b/tests/spelling.txt index 1b5e6127689..9a0eb44df31 100644 --- a/tests/spelling.txt +++ b/tests/spelling.txt @@ -1,8 +1,8 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --allow-unsafe --output-file=tests/spelling.txt --strip-extras tests/spelling.in # -codespell==2.2.6 +codespell==2.3.0 # via -r tests/spelling.in diff --git a/tests/static.txt b/tests/static.txt index 9d83c82bd2b..eb7429b58a7 100644 --- a/tests/static.txt +++ b/tests/static.txt @@ -1,8 +1,8 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --allow-unsafe --output-file=tests/static.txt --strip-extras tests/static.in # -ruff==0.4.1 +ruff==0.6.5 # via -r tests/static.in diff --git a/hacking/tagger/requirements.txt b/tests/tag.in similarity index 100% rename from hacking/tagger/requirements.txt rename to tests/tag.in diff --git a/tests/tag.txt b/tests/tag.txt new file mode 100644 index 00000000000..177f3250cb7 --- /dev/null +++ b/tests/tag.txt @@ -0,0 +1,30 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --allow-unsafe --output-file=tests/tag.txt --strip-extras tests/tag.in +# +click==8.1.7 + # via typer +gitdb==4.0.11 + # via gitpython +gitpython==3.1.43 + # via -r tests/tag.in +markdown-it-py==3.0.0 + # via rich +mdurl==0.1.2 + # via markdown-it-py +packaging==24.1 + # via -r tests/tag.in +pygments==2.18.0 + # via rich +rich==13.8.1 + # via typer +shellingham==1.5.4 + # via typer +smmap==5.0.1 + # via gitdb +typer==0.12.5 + # via -r tests/tag.in +typing-extensions==4.12.2 + # via typer diff --git a/tests/typing.in b/tests/typing.in index 5eaee63794a..9701e2c5780 100644 --- a/tests/typing.in +++ b/tests/typing.in @@ -1,4 +1,4 @@ -r ../hacking/pr_labeler/requirements.txt --r ../hacking/tagger/requirements.txt +-r tag.in mypy nox diff --git a/tests/typing.txt b/tests/typing.txt index a3ab6d9d7c5..421cca04549 100644 --- a/tests/typing.txt +++ b/tests/typing.txt @@ -1,40 +1,42 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --allow-unsafe --output-file=tests/typing.txt --strip-extras tests/typing.in # -argcomplete==3.3.0 +argcomplete==3.5.0 # via nox -certifi==2024.2.2 +certifi==2024.8.30 # via requests -cffi==1.16.0 +cffi==1.17.1 # via # cryptography # pynacl charset-normalizer==3.3.2 # via requests click==8.1.7 - # via typer + # via + # typer + # typer-slim codeowners==0.7.0 # via -r tests/../hacking/pr_labeler/requirements.txt colorlog==6.8.2 # via nox -cryptography==42.0.5 +cryptography==43.0.1 # via pyjwt deprecated==1.2.14 # via pygithub distlib==0.3.8 # via virtualenv -filelock==3.13.4 +filelock==3.16.0 # via virtualenv gitdb==4.0.11 # via gitpython gitpython==3.1.43 - # via -r tests/../hacking/tagger/requirements.txt -idna==3.7 + # via -r tests/tag.in +idna==3.9 # via requests -jinja2==3.1.3 +jinja2==3.1.4 # via -r tests/../hacking/pr_labeler/requirements.txt markdown-it-py==3.0.0 # via rich @@ -42,55 +44,52 @@ markupsafe==2.1.5 # via jinja2 mdurl==0.1.2 # via markdown-it-py -mypy==1.9.0 +mypy==1.11.2 # via -r tests/typing.in mypy-extensions==1.0.0 # via mypy nox==2024.4.15 # via -r tests/typing.in -packaging==24.0 +packaging==24.1 # via - # -r tests/../hacking/tagger/requirements.txt + # -r tests/tag.in # nox -platformdirs==4.2.0 +platformdirs==4.3.3 # via virtualenv pycparser==2.22 # via cffi -pygithub==2.3.0 +pygithub==2.4.0 # via -r tests/../hacking/pr_labeler/requirements.txt -pygments==2.17.2 +pygments==2.18.0 # via rich -pyjwt==2.8.0 +pyjwt==2.9.0 # via pygithub pynacl==1.5.0 # via pygithub -requests==2.31.0 +requests==2.32.3 # via pygithub -rich==13.7.1 +rich==13.8.1 # via typer shellingham==1.5.4 # via typer smmap==5.0.1 # via gitdb -tomli==2.0.1 - # via - # mypy - # nox -typer==0.12.3 - # via - # -r tests/../hacking/pr_labeler/requirements.txt - # -r tests/../hacking/tagger/requirements.txt -typing-extensions==4.11.0 +typer==0.12.5 + # via -r tests/tag.in +typer-slim==0.12.5 + # via -r tests/../hacking/pr_labeler/requirements.txt +typing-extensions==4.12.2 # via # codeowners # mypy # pygithub # typer -urllib3==2.2.1 + # typer-slim +urllib3==2.2.3 # via # pygithub # requests -virtualenv==20.25.3 +virtualenv==20.26.4 # via nox wrapt==1.16.0 # via deprecated