diff --git a/.github/workflows/ansible-lint.yml b/.github/workflows/ansible-lint.yml index abf36bb..52dcc2a 100644 --- a/.github/workflows/ansible-lint.yml +++ b/.github/workflows/ansible-lint.yml @@ -10,7 +10,7 @@ jobs: - name: Lint Ansible Playbook uses: ansible/ansible-lint-action@master with: - targets: "tests/test.yml" + targets: "tests/test_*.yml" override-deps: | ansible==2.8 args: "" @@ -21,7 +21,7 @@ jobs: - name: Lint Ansible Playbook uses: ansible/ansible-lint-action@master with: - targets: "tests/test.yml" + targets: "tests/test_*.yml override-deps: | ansible==2.9 args: "" @@ -32,7 +32,8 @@ jobs: - name: Lint Ansible Playbook uses: ansible/ansible-lint-action@master with: - targets: "tests/test.yml" + targets: "tests/test_*.yml" override-deps: | ansible==2.10 args: "" + diff --git a/.travis.yml b/.travis.yml index 7f1917d..43ebef9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ --- +os: linux dist: focal -language: c -sudo: required +language: python notifications: webhooks: https://galaxy.ansible.com/api/v1/notifications/ @@ -14,14 +14,36 @@ install: - "{ echo '[defaults]'; echo 'roles_path = ../'; echo 'deprecation_warnings=False'; } >> ansible.cfg" script: - # Check the roles syntax. - - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test.yml --syntax-check" + # Test 0: Check the roles syntax. + - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test_default.yml --syntax-check" - # Run the role - - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test.yml --connection=local --become -v" + # Test 1a: Run the role + - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test_default.yml --connection=local --become -v" - # Run the role/playbook again, checking to make sure it's idempotent. + # Test 1b: Run the role through include + - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test_default_include.yml --connection=local --become -v" + + # Test 2: Run the role/playbook again, checking to make sure it's idempotent. - > - ansible-playbook -i tests/inventory tests/test.yml --connection=local --become | grep -q 'changed=0.*failed=0' + ansible-playbook -i tests/inventory tests/test_default.yml --connection=local --become | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) + + # Test 3: Check we can set arbitrary configuration options + - > + ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test_set_common.yml --connection=local --become -v + && (echo 'Common variables test: pass' && exit 0) + || (echo 'Common variables test: fail' && exit 1) + + # Test 4: Check if we set uncommon or unsupported configuration option, it will not fail hard + - > + ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test_set_uncommon.yml --connection=local --become -v + && (echo 'Uncommon configuration test: pass' && exit 0) + || (echo 'Uncommon configuration test: fail' && exit 1) + + # Test 5: Make sure we can modify other files, for example for inclusion + # in the main sshd_config or second sshd service + - > + ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/test_alternative_file.yml --connection=local --become -v + && (echo 'Alternative configuration file test: pass' && exit 0) + || (echo 'Alternative configuration file test: fail' && exit 1) diff --git a/README.md b/README.md index 1881da8..5ae4a46 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,34 @@ Match Group xusers X11Forwarding yes ``` +Since Ansible 2.4, the role can be invoked using `include_role` keyword, +for example: + +```yaml +--- +- hosts: all + become: true + tasks: + - name: "Configure sshd" + include_role: + name: willshersystems.sshd + vars: + sshd_skip_defaults: true + sshd: + Compression: true + ListenAddress: + - "0.0.0.0" + - "::" + GSSAPIAuthentication: no + Match: + - Condition: "Group user" + GSSAPIAuthentication: yes + sshd_UsePrivilegeSeparation: no + sshd_match: + - Condition: "Group xusers" + X11Forwarding: yes + + Template Generation ------------------- diff --git a/tests/test_alternative_file.yml b/tests/test_alternative_file.yml new file mode 100644 index 0000000..ad45868 --- /dev/null +++ b/tests/test_alternative_file.yml @@ -0,0 +1,31 @@ +--- +- hosts: all + become: true + tasks: + - name: Configure alternative sshd_config file + include_role: + name: ansible-sshd + vars: + # just anything -- will not get processed by sshd + sshd_config_file: /etc/ssh/sshd_config_custom + sshd_skip_defaults: true + sshd: + AcceptEnv: LANG + Banner: /etc/issue + Ciphers: aes256-gcm@openssh.com + + - name: Verify the options are correctly set + block: + - meta: flush_handlers + + - name: Print current configuration file + command: cat /etc/ssh/sshd_config_custom + register: config + + - name: Check the options are in configuration file + assert: + that: + - "'AcceptEnv LANG' in config.stdout" + - "'Banner /etc/issue' in config.stdout" + - "'Ciphers aes256-gcm@openssh.com' in config.stdout" + tags: tests::verify diff --git a/tests/test.yml b/tests/test_default.yml similarity index 100% rename from tests/test.yml rename to tests/test_default.yml diff --git a/tests/test_default_include.yml b/tests/test_default_include.yml new file mode 100644 index 0000000..de17c23 --- /dev/null +++ b/tests/test_default_include.yml @@ -0,0 +1,7 @@ +--- +- hosts: all + become: true + tasks: + - name: "Configure sshd" + include_role: + name: ansible-sshd diff --git a/tests/test_set_common.yml b/tests/test_set_common.yml new file mode 100644 index 0000000..e2fd624 --- /dev/null +++ b/tests/test_set_common.yml @@ -0,0 +1,43 @@ +--- +- hosts: all + become: true + tasks: + - name: Configure sshd + include_role: + name: ansible-sshd + vars: + sshd: + AcceptEnv: LANG + Banner: /etc/issue + Ciphers: aes256-gcm@openssh.com + Subsystem: "sftp internal-sftp" + + - name: Verify the options are correctly set + block: + - meta: flush_handlers + + - name: List effective configuration using sshd -T + command: sshd -T + register: runtime + + - name: Print current configuration file + command: cat /etc/ssh/sshd_config + register: config + + - name: Check the options are effective + # note, the options are in lower-case here + assert: + that: + - "'acceptenv LANG' in runtime.stdout" + - "'banner /etc/issue' in runtime.stdout" + - "'ciphers aes256-gcm@openssh.com' in runtime.stdout" + - "'subsystem sftp internal-sftp' in runtime.stdout" + + - name: Check the options are in configuration file + assert: + that: + - "'AcceptEnv LANG' in config.stdout" + - "'Banner /etc/issue' in config.stdout" + - "'Ciphers aes256-gcm@openssh.com' in config.stdout" + - "'Subsystem sftp internal-sftp' in config.stdout" + tags: tests::verify diff --git a/tests/test_set_uncommon.yml b/tests/test_set_uncommon.yml new file mode 100644 index 0000000..d3a55fc --- /dev/null +++ b/tests/test_set_uncommon.yml @@ -0,0 +1,51 @@ +--- +- hosts: all + become: true + tasks: + - name: Configure sshd with uncommon options, making sure it keeps running + block: + - name: Configure ssh with unsupported options + include_role: + name: ansible-sshd + vars: + sshd: + # Unsupported in new versions, but ignored ? + Protocol: 1 + UsePrivilegeSeparation: no + UseLogin: yes + # Debian only + DebianBanner: /etc/motd + # Used in FreeBSD ? + VersionAddendum: FreeBSD-20180909 + # HPN only + HPNDisabled: yes + HPNBufferSize: 2MB + TcpRcvBufPoll: yes + NoneEnabled: yes + # some builds might be without kerberos/GSSAPI + KerberosAuthentication: yes + GSSAPIStoreCredentialsOnRekey: yes + # SSHv1 options + KeyRegenerationInterval: 1h + ServerKeyBits: 1024 + # This one is pretty new, but works on OpenBSD only + RDomain: 2 + register: role_result + + - name: unreachable task + fail: + msg: UNREACH + rescue: + - name: Check that we failed in the role + assert: + that: + - ansible_failed_result.msg != 'UNREACH' + - not role_result.changed + msg: "Role has not failed when it should have" + + - name: Make sure service is still running + service: + name: sshd + state: started + register: result + failed_when: result.changed