Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dev-tools/options_body
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ ProxyUseFdpass
PubkeyAcceptedKeyTypes
PubkeyAcceptedAlgorithms
PubkeyAuthentication
RefuseConnection
RekeyLimit
RemoteCommand
RemoteForward
Expand Down Expand Up @@ -113,4 +114,5 @@ UserKnownHostsFile
VerifyHostKeyDNS
VersionAddendum
VisualHostKey
WarnWeakCrypto
XAuthLocation
71 changes: 0 additions & 71 deletions .github/workflows/ansible-centos.yml

This file was deleted.

39 changes: 39 additions & 0 deletions .github/workflows/ansible-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Ansible CI
on: [push, pull_request]

env:
ANSIBLE_INJECT_FACT_VARS: "false"

jobs:
test:
if: |
!((github.event_name == 'pull_request' && contains(github.event.pull_request.title, '[citest_skip]')) ||
(github.event_name == 'push' && contains(github.event.head_commit.message, '[citest_skip]')))
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os_image:
- alpine:latest
- quay.io/centos/centos:stream8
- quay.io/centos/centos:stream9
- quay.io/centos/centos:stream10
- debian:bullseye
- debian:bookworm
- debian:latest
- fedora:latest
- ubuntu:22.04
- ubuntu:24.04
- ubuntu:latest

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Test Ansible SSH Role
uses: Jakuje/check-ansible-action@main
with:
Comment on lines +31 to +35
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "actions/checkout v6 SHA:"
git ls-remote https://github.com/actions/checkout refs/tags/v6

echo
echo "Jakuje/check-ansible-action main SHA:"
git ls-remote https://github.com/Jakuje/check-ansible-action refs/heads/main

Repository: spetrosi/ssh

Length of output: 231


🏁 Script executed:

sed -n '31,35p' .github/workflows/ansible-check.yml

Repository: spetrosi/ssh

Length of output: 188


Pin GitHub Actions to immutable commit SHAs instead of moving refs.

uses: ...@v6 and uses: ...@main allow upstream changes to alter CI behavior without any PR in this repo. Pin both actions to their resolved commit SHAs:

🔒 Suggested fix
-      - name: Checkout code
-        uses: actions/checkout@v6
+      - name: Checkout code
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

-      - name: Test Ansible SSH Role
-        uses: Jakuje/check-ansible-action@main
+      - name: Test Ansible SSH Role
+        uses: Jakuje/check-ansible-action@f64d87a5598747f49294b37d7302083afbc15c76
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions/checkout@v6
- name: Test Ansible SSH Role
uses: Jakuje/check-ansible-action@main
with:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Test Ansible SSH Role
uses: Jakuje/check-ansible-action@f64d87a5598747f49294b37d7302083afbc15c76
with:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ansible-check.yml around lines 31 - 35, The workflow
currently references mutable tags/refs (actions/checkout@v6 and
Jakuje/check-ansible-action@main); replace those uses entries with the exact
commit SHAs resolved for the versions you want to lock (e.g.,
actions/checkout@<commit-sha> and Jakuje/check-ansible-action@<commit-sha>) so
the CI cannot change unexpectedly—locate the two uses lines for actions/checkout
and Jakuje/check-ansible-action in the ansible-check.yml and substitute the
tag/ref with the corresponding immutable commit SHAs.

image: ${{ matrix.os_image }}
group: local
hosts: localhost
targets: "tests/tests_*.yml"
38 changes: 0 additions & 38 deletions .github/workflows/ansible-debian.yml

This file was deleted.

22 changes: 0 additions & 22 deletions .github/workflows/ansible-fedora.yml

This file was deleted.

38 changes: 0 additions & 38 deletions .github/workflows/ansible-ubuntu.yml

This file was deleted.

6 changes: 6 additions & 0 deletions templates/ssh_config.j2
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ Match {{ match["Condition"] }}
{{ render_option("PubkeyAcceptedKeyTypes", match["PubkeyAcceptedKeyTypes"], true) -}}
{{ render_option("PubkeyAcceptedAlgorithms", match["PubkeyAcceptedAlgorithms"], true) -}}
{{ render_option("PubkeyAuthentication", match["PubkeyAuthentication"], true) -}}
{{ render_option("RefuseConnection", match["RefuseConnection"], true) -}}
{{ render_option("RekeyLimit", match["RekeyLimit"], true) -}}
{{ render_option("RemoteCommand", match["RemoteCommand"], true) -}}
{{ render_option("RemoteForward", match["RemoteForward"], true) -}}
Expand Down Expand Up @@ -158,6 +159,7 @@ Match {{ match["Condition"] }}
{{ render_option("VerifyHostKeyDNS", match["VerifyHostKeyDNS"], true) -}}
{{ render_option("VersionAddendum", match["VersionAddendum"], true) -}}
{{ render_option("VisualHostKey", match["VisualHostKey"], true) -}}
{{ render_option("WarnWeakCrypto", match["WarnWeakCrypto"], true) -}}
{{ render_option("XAuthLocation", match["XAuthLocation"], true) -}}
{% endfor %}
{% endif %}
Expand Down Expand Up @@ -254,6 +256,7 @@ Host {{ host["Condition"] }}
{{ render_option("PubkeyAcceptedKeyTypes", host["PubkeyAcceptedKeyTypes"], true) -}}
{{ render_option("PubkeyAcceptedAlgorithms", host["PubkeyAcceptedAlgorithms"], true) -}}
{{ render_option("PubkeyAuthentication", host["PubkeyAuthentication"], true) -}}
{{ render_option("RefuseConnection", host["RefuseConnection"], true) -}}
{{ render_option("RekeyLimit", host["RekeyLimit"], true) -}}
{{ render_option("RemoteCommand", host["RemoteCommand"], true) -}}
{{ render_option("RemoteForward", host["RemoteForward"], true) -}}
Expand Down Expand Up @@ -284,6 +287,7 @@ Host {{ host["Condition"] }}
{{ render_option("VerifyHostKeyDNS", host["VerifyHostKeyDNS"], true) -}}
{{ render_option("VersionAddendum", host["VersionAddendum"], true) -}}
{{ render_option("VisualHostKey", host["VisualHostKey"], true) -}}
{{ render_option("WarnWeakCrypto", host["WarnWeakCrypto"], true) -}}
{{ render_option("XAuthLocation", host["XAuthLocation"], true) -}}
{% endfor %}
{% endif %}
Expand Down Expand Up @@ -373,6 +377,7 @@ Host {{ host["Condition"] }}
{{ body_option("PubkeyAcceptedKeyTypes", ssh_PubkeyAcceptedKeyTypes) -}}
{{ body_option("PubkeyAcceptedAlgorithms", ssh_PubkeyAcceptedAlgorithms) -}}
{{ body_option("PubkeyAuthentication", ssh_PubkeyAuthentication) -}}
{{ body_option("RefuseConnection", ssh_RefuseConnection) -}}
{{ body_option("RekeyLimit", ssh_RekeyLimit) -}}
{{ body_option("RemoteCommand", ssh_RemoteCommand) -}}
{{ body_option("RemoteForward", ssh_RemoteForward) -}}
Expand Down Expand Up @@ -403,6 +408,7 @@ Host {{ host["Condition"] }}
{{ body_option("VerifyHostKeyDNS", ssh_VerifyHostKeyDNS) -}}
{{ body_option("VersionAddendum", ssh_VersionAddendum) -}}
{{ body_option("VisualHostKey", ssh_VisualHostKey) -}}
{{ body_option("WarnWeakCrypto", ssh_WarnWeakCrypto) -}}
{{ body_option("XAuthLocation", ssh_XAuthLocation) -}}
{% if ssh['Match'] is defined %}
{{ match_block(ssh['Match']) -}}
Expand Down
3 changes: 2 additions & 1 deletion tests/tasks/setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@
- (ansible_facts['os_family'] in ['RedHat', 'Suse']
and ansible_facts['distribution_major_version'] | int >= 8) or
(ansible_facts['distribution'] == 'Ubuntu'
and ansible_facts['distribution_major_version'] | int >= 20)
and ansible_facts['distribution_major_version'] | int >= 20) or
ansible_facts['distribution'] == 'Alpine'
Comment on lines 44 to +48
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align Alpine bootstrap package with the new Alpine role defaults.

Line 48 opts Alpine into the Alpine-specific path, but the bootstrap package resolver still falls through to openssh-client (Line 24) while this PR’s vars/Alpine.yml declares openssh-client-default. This mismatch can fail setup before role execution on Alpine.

Suggested fix
 - name: Make sure openssh is installed before creating backup
   vars:
     __ssh_test_packages: >-
       {{
         "openssh-clients" if ansible_facts['os_family'] in ['RedHat', 'Suse']
-        else "openssh-client"
+        else ("openssh-client-default"
+              if ansible_facts['distribution'] == 'Alpine'
+              else "openssh-client")
       }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/tasks/setup.yml` around lines 44 - 48, The bootstrap package selection
includes Alpine in the OS-family conditional but still references the package
name openssh-client; update the Alpine-specific branch so the resolver uses the
Alpine-default variable name openssh-client-default (or map openssh-client to
openssh-client-default for Alpine) to match vars/Alpine.yml; specifically adjust
the conditional that handles ansible_facts['distribution'] == 'Alpine' so the
chosen package string matches the declared variable openssh-client-default used
by the Alpine role.

2 changes: 2 additions & 0 deletions tests/tests_additional_packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
openssh-keycat
{% elif ansible_facts['os_family'] == 'Suse' %}
openssh-helpers
{% elif ansible_facts['os_family'] == 'Alpine' %}
openssh-sk-helper
{% else %}
openssh-tests
{% endif %}
Expand Down
14 changes: 14 additions & 0 deletions tests/tests_all_options.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@
- not __ssh_is_ostree | bool
changed_when: true

- name: Make sure manual pages and bash are installed on Alpine
ansible.builtin.package:
name:
- mandoc
- man-pages
- openssh-doc
- bash
state: present
when:
- ansible_facts['distribution'] == "Alpine"

- name: Make sure manual pages, gawk and bash are installed
package:
name:
Expand All @@ -65,6 +76,8 @@
state: present
use: "{{ (__ssh_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- ansible_facts['distribution'] != "Alpine"

- name: Check if ssh_config man page is available
command: man -w ssh_config
Expand All @@ -79,6 +92,7 @@
- name: Get list of options from manual page
shell: >-
set -o pipefail && man ssh_config \
| sed 's/\x08.//g' \
| grep -o '^\( \| \)[A-Z][A-Za-z0-9]*\(.\| \)' \
| grep -v "[A-Za-z0-9] $" | grep -v "[^A-Za-z0-9 ]$" \
| awk '{ print $1 }' \
Expand Down
2 changes: 2 additions & 0 deletions tests/tests_no_skip_defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
(ansible_facts['distribution'] in ['RedHat', 'CentOS'] and
ansible_facts['distribution_version'] | int >= 8) %}
Include /etc/ssh/ssh_config.d/*.conf
{% elif ansible_facts['os_family'] == 'Alpine' %}
Include /etc/ssh/ssh_config.d/
Comment on lines +16 to +17
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix Alpine expectation to match the role’s Alpine defaults.

Line 17 expects Include /etc/ssh/ssh_config.d/, but this PR’s vars/Alpine.yml sets Include: /etc/ssh/ssh_config.d/*.conf. Keep these aligned to avoid false failures in the assertion.

Suggested fix
       {% elif ansible_facts['os_family'] == 'Alpine' %}
-        Include /etc/ssh/ssh_config.d/
+        Include /etc/ssh/ssh_config.d/*.conf
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{% elif ansible_facts['os_family'] == 'Alpine' %}
Include /etc/ssh/ssh_config.d/
{% elif ansible_facts['os_family'] == 'Alpine' %}
Include /etc/ssh/ssh_config.d/*.conf
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/tests_no_skip_defaults.yml` around lines 16 - 17, Update the Alpine
expectation in the test to match the role's Alpine default: replace the literal
"Include /etc/ssh/ssh_config.d/" expectation with the globbed form "Include:
/etc/ssh/ssh_config.d/*.conf" so it aligns with the value defined in
vars/Alpine.yml (ensure the test assertion that checks the SSH config content
uses the same "Include: /etc/ssh/ssh_config.d/*.conf" string).

{% else %}
GSSAPIAuthentication yes
{% endif %}
Expand Down
9 changes: 9 additions & 0 deletions vars/Alpine.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
__ssh_packages: ['openssh-client-default']

__ssh_supports_drop_in: true
__ssh_drop_in_name: "00-ansible"

# This default lists the main configuration file defaults
__ssh_defaults:
Include: /etc/ssh/ssh_config.d/*.conf
15 changes: 15 additions & 0 deletions vars/Ubuntu_26.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
__ssh_packages: ['openssh-client']

# This system supports drop in directory so defaults are adjusted
__ssh_supports_drop_in: true
__ssh_drop_in_name: "00-ansible"

# This default lists the main configuration file defaults
__ssh_defaults:
Include: /etc/ssh/ssh_config.d/*.conf
Host:
- Condition: "*"
SendEnv: LANG LC_* COLORTERM NO_COLOR
HashKnownHosts: true
GSSAPIAuthentication: true
Loading