Skip to content

Commit 7944d18

Browse files
authored
refactor: Ansible 2.19 support (#311)
Ansible 2.19 introduces some big changes https://docs.ansible.com/ansible/devel/porting_guides/porting_guide_core_2.19.html A big change is that a boolean expression in a `when` or similar construct must be converted to a boolean - we cannot rely on the implicit evaluation in a boolean context. For example, if `var` is some iterable, like a `dict`, `list`, or `string`, you used to be able to evaluate an empty value in a boolean context: ```yaml when: var # do this only if var is not empty ``` You now have to explicitly test for empty using `length`: ```yaml when: var | length > 0 # do this only if var is not empty ``` Similarly for `int` values - you cannot rely on `0` being evaluated as false and non-zero true - you must explicitly compare the values with `==` or `!=` In macros in templates, the implicit return value is now `none` - we have to ensure that the macro returns an empty string in these cases - to do this, use `{{- '' -}}` The `ansible_managed` variable cannot be overwritten - use a temp variable. This also fixes some ansible-lint issues with the new ansible-lint * Task names in the same file must be unique * Stricter checking for spacing * Stricter enforcement of the "no quotes in when/that expressions" These are the biggest changes. See the porting guide for others. Signed-off-by: Rich Megginson <rmeggins@redhat.com>
1 parent 1f47150 commit 7944d18

File tree

12 files changed

+72
-51
lines changed

12 files changed

+72
-51
lines changed

meta/10_top.j2

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,46 @@
11
{% macro render_option(key,value,indent=false) %}
2-
{% if value is defined %}
2+
{% if value is defined and value is not none %}
33
{% if value is sameas true %}
4-
{% if indent %} {% endif %}
4+
{% if indent %} {% endif %}
55
{{ key }} yes
66
{% elif value is sameas false %}
7-
{% if indent %} {% endif %}
7+
{% if indent %} {% endif %}
88
{{ key }} no
99
{% elif value is string or value is number %}
10-
{% if indent %} {% endif %}
10+
{% if indent %} {% endif %}
1111
{{ key }} {{ value | string }}
1212
{% else %}
1313
{% for i in value %}
14-
{% if indent %} {% endif %}
14+
{% if i is none %}
15+
{{- '' -}}
16+
{% else %}
17+
{% if indent %} {% endif %}
1518
{{ key }} {{ i | string }}
19+
{% endif %}
1620
{% endfor %}
1721
{% endif %}
22+
{% else %}
23+
{{- '' -}}
1824
{% endif %}
1925
{% endmacro %}
2026
{% macro body_option(key,override) %}
21-
{% set value = undefined %}
2227
{% if override is defined %}
23-
{% set value = override %}
28+
{{ render_option(key, override) -}}
2429
{% elif __sshd_config[key] is defined %}
25-
{% set value = __sshd_config[key] %}
30+
{{ render_option(key, __sshd_config[key]) -}}
2631
{% elif sshd_main_config_file is not none
2732
and sshd_config_file | dirname == sshd_main_config_file ~ '.d' %}
2833
{# Do not use the defaults from main file to avoid recursion #}
34+
{{- '' -}}
2935
{% elif __sshd_defaults[key] is defined and not sshd_skip_defaults %}
3036
{% if key == 'HostKey' and __sshd_fips_mode %}
31-
{% set value = __sshd_defaults[key] | difference(__sshd_hostkeys_nofips) %}
37+
{{ render_option(key, __sshd_defaults[key] | difference(__sshd_hostkeys_nofips)) -}}
3238
{% else %}
33-
{% set value = __sshd_defaults[key] %}
39+
{{ render_option(key, __sshd_defaults[key]) -}}
3440
{% endif %}
41+
{% else %}
42+
{{- '' -}}
3543
{% endif %}
36-
{{ render_option(key,value) -}}
3744
{% endmacro %}
3845
{% macro match_block(match_list) %}
3946
{% if match_list["Condition"] is defined %}

tasks/install.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030
- name: Check FIPS mode
3131
ansible.builtin.include_tasks: check_fips.yml
3232
when:
33-
- __sshd_hostkeys_nofips | d([])
33+
- __sshd_hostkeys_nofips | d([]) | length > 0
3434

3535
- name: Make sure hostkeys are available and have expected permissions
3636
vars:
3737
&share_vars # 'MAo=' evaluates to '0\n' in base 64 encoding, which is default
3838
__sshd_fips_mode: >-
39-
{{ __sshd_hostkeys_nofips | d([]) and
39+
{{ __sshd_hostkeys_nofips | d([]) | length > 0 and
4040
(__sshd_kernel_fips_mode.content | d('MAo=') | b64decode | trim == '1' or
4141
__sshd_userspace_fips_mode.content | d('MAo=') | b64decode | trim != '0') }}
4242
# This mimics the macro body_option() in sshd_config.j2

templates/sshd_config.j2

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,48 @@
11
{{ ansible_managed | comment }}
22
{{ "willshersystems:ansible-sshd" | comment(prefix="", postfix="") }}
33
{% macro render_option(key,value,indent=false) %}
4-
{% if value is defined %}
4+
{% if value is defined and value is not none %}
55
{% if value is sameas true %}
6-
{% if indent %} {% endif %}
6+
{% if indent %} {% endif %}
77
{{ key }} yes
88
{% elif value is sameas false %}
9-
{% if indent %} {% endif %}
9+
{% if indent %} {% endif %}
1010
{{ key }} no
1111
{% elif value is string or value is number %}
12-
{% if indent %} {% endif %}
12+
{% if indent %} {% endif %}
1313
{{ key }} {{ value | string }}
1414
{% else %}
1515
{% for i in value %}
16-
{% if indent %} {% endif %}
16+
{% if i is none %}
17+
{{- '' -}}
18+
{% else %}
19+
{% if indent %} {% endif %}
1720
{{ key }} {{ i | string }}
21+
{% endif %}
1822
{% endfor %}
1923
{% endif %}
24+
{% else %}
25+
{{- '' -}}
2026
{% endif %}
2127
{% endmacro %}
2228
{% macro body_option(key,override) %}
23-
{% set value = undefined %}
2429
{% if override is defined %}
25-
{% set value = override %}
30+
{{ render_option(key, override) -}}
2631
{% elif __sshd_config[key] is defined %}
27-
{% set value = __sshd_config[key] %}
32+
{{ render_option(key, __sshd_config[key]) -}}
2833
{% elif sshd_main_config_file is not none
2934
and sshd_config_file | dirname == sshd_main_config_file ~ '.d' %}
3035
{# Do not use the defaults from main file to avoid recursion #}
36+
{{- '' -}}
3137
{% elif __sshd_defaults[key] is defined and not sshd_skip_defaults %}
3238
{% if key == 'HostKey' and __sshd_fips_mode %}
33-
{% set value = __sshd_defaults[key] | difference(__sshd_hostkeys_nofips) %}
39+
{{ render_option(key, __sshd_defaults[key] | difference(__sshd_hostkeys_nofips)) -}}
3440
{% else %}
35-
{% set value = __sshd_defaults[key] %}
41+
{{ render_option(key, __sshd_defaults[key]) -}}
3642
{% endif %}
43+
{% else %}
44+
{{- '' -}}
3745
{% endif %}
38-
{{ render_option(key,value) -}}
3946
{% endmacro %}
4047
{% macro match_block(match_list) %}
4148
{% if match_list["Condition"] is defined %}

templates/sshd_config_snippet.j2

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,46 @@
11
{% macro render_option(key,value,indent=true) %}
2-
{% if value is defined %}
2+
{% if value is defined and value is not none %}
33
{% if value is sameas true %}
4-
{% if indent %} {% endif %}
4+
{% if indent %} {% endif %}
55
{{ key }} yes
66
{% elif value is sameas false %}
7-
{% if indent %} {% endif %}
7+
{% if indent %} {% endif %}
88
{{ key }} no
99
{% elif value is string or value is number %}
10-
{% if indent %} {% endif %}
10+
{% if indent %} {% endif %}
1111
{{ key }} {{ value | string }}
1212
{% else %}
1313
{% for i in value %}
14-
{% if indent %} {% endif %}
14+
{% if i is none %}
15+
{{- '' -}}
16+
{% else %}
17+
{% if indent %} {% endif %}
1518
{{ key }} {{ i | string }}
19+
{% endif %}
1620
{% endfor %}
1721
{% endif %}
22+
{% else %}
23+
{{- '' -}}
1824
{% endif %}
1925
{% endmacro %}
2026
{% macro body_option(key,override) %}
21-
{% set value = undefined %}
2227
{% if override is defined %}
23-
{% set value = override %}
28+
{{ render_option(key, override) -}}
2429
{% elif __sshd_config[key] is defined %}
25-
{% set value = __sshd_config[key] %}
30+
{{ render_option(key, __sshd_config[key]) -}}
2631
{% elif sshd_main_config_file is not none
2732
and sshd_config_file | dirname == sshd_main_config_file ~ '.d' %}
2833
{# Do not use the defaults from main file to avoid recursion #}
34+
{{- '' -}}
2935
{% elif __sshd_defaults[key] is defined and not sshd_skip_defaults %}
3036
{% if key == 'HostKey' and __sshd_fips_mode %}
31-
{% set value = __sshd_defaults[key] | difference(__sshd_hostkeys_nofips) %}
37+
{{ render_option(key, __sshd_defaults[key] | difference(__sshd_hostkeys_nofips)) -}}
3238
{% else %}
33-
{% set value = __sshd_defaults[key] %}
39+
{{ render_option(key, __sshd_defaults[key]) -}}
3440
{% endif %}
41+
{% else %}
42+
{{- '' -}}
3543
{% endif %}
36-
{{ render_option(key,value) -}}
3744
{% endmacro %}
3845
{% macro match_block(match_list) %}
3946
{% if match_list["Condition"] is defined %}

tests/tasks/check_header.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
- name: Check for presence of ansible managed header, fingerprint
1010
ansible.builtin.assert:
1111
that:
12-
- ansible_managed in content
12+
- __ansible_managed in content
1313
- __fingerprint in content
1414
vars:
1515
content: "{{ (__file_content | d(__content)).content | b64decode }}"
16-
ansible_managed: "{{ lookup('template', 'get_ansible_managed.j2') }}"
16+
__ansible_managed: "{{ lookup('template', 'get_ansible_managed.j2') }}"

tests/tests_all_options.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
- ansible_facts['os_family'] != "RedHat" or
8484
ansible_facts['distribution_major_version'] | int == 6
8585

86-
- name: Get list of options from manual page
86+
- name: Show list of options from manual page
8787
ansible.builtin.shell: >-
8888
set -eu; set -o | grep -q pipefail && set -o pipefail; man sshd_config | cat
8989
changed_when: false

tests/tests_backup.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
sshd_Banner: /tmp/banner # noqa var-naming
4141
register: second_run
4242

43-
- name: Find new backups files
43+
- name: Find new backups files after reconfiguration
4444
ansible.builtin.find:
4545
paths: "{{ main_sshd_config_path }}"
4646
patterns: "{{ main_sshd_config_name }}.*@*~"

tests/tests_config_namespace.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,16 @@
6868
- name: Check content of configuration file (blocks)
6969
ansible.builtin.assert:
7070
that:
71-
- "config.content | b64decode | regex_search('Match all\\s*PasswordAuthentication yes')"
72-
- "config.content | b64decode | regex_search('Match all\\s*PasswordAuthentication no')"
71+
- config.content | b64decode | regex_search('Match all\\s*PasswordAuthentication yes') | length > 0
72+
- config.content | b64decode | regex_search('Match all\\s*PasswordAuthentication no') | length > 0
7373
when:
7474
- ansible_facts['os_family'] != 'RedHat' or ansible_facts['distribution_major_version'] != '6'
7575

7676
- name: Check content of configuration file (blocks for RHEL 6)
7777
ansible.builtin.assert:
7878
that:
79-
- "config.content | b64decode | regex_search('Match address \\*\\s*PasswordAuthentication yes')"
80-
- "config.content | b64decode | regex_search('Match address \\*\\s*PasswordAuthentication no')"
79+
- config.content | b64decode | regex_search('Match address \\*\\s*PasswordAuthentication yes') | length > 0
80+
- config.content | b64decode | regex_search('Match address \\*\\s*PasswordAuthentication no') | length > 0
8181
when:
8282
- ansible_facts['os_family'] == 'RedHat'
8383
- ansible_facts['distribution_major_version'] == '6'
@@ -89,12 +89,12 @@
8989
- "'PasswordAuthentication yes' in config.content | b64decode"
9090
- "'Match user root' in config.content | b64decode"
9191
- "'AllowAgentForwarding no' in config.content | b64decode"
92-
- "config.content | b64decode | regex_search('Match user root\\s*AllowAgentForwarding no')"
92+
- config.content | b64decode | regex_search('Match user root\\s*AllowAgentForwarding no') | length > 0
9393
- "'PermitRootLogin no' in config.content | b64decode"
9494
- "'PasswordAuthentication no' in config.content | b64decode"
9595
- "'Match Address 127.0.0.1' in config.content | b64decode"
9696
- "'Banner /etc/issue' in config.content | b64decode"
97-
- "config.content | b64decode | regex_search('Match Address 127.0.0.1\\s*Banner /etc/issue')"
97+
- config.content | b64decode | regex_search('Match Address 127.0.0.1\\s*Banner /etc/issue') | length > 0
9898

9999
- name: Check the configuration values are effective
100100
# note, the options are in lower-case here

tests/tests_firewall_selinux.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
sshd_config:
6969
Port: 222
7070

71-
- name: Verify the options are correctly set
71+
- name: Verify the options are correctly set with non-standard port
7272
tags: tests::verify
7373
block:
7474
- name: Flush handlers
@@ -98,7 +98,7 @@
9898
- 22
9999
- 222
100100

101-
- name: Verify the options are correctly set
101+
- name: Verify the options are correctly set with multiple ports
102102
tags: tests::verify
103103
block:
104104
- name: Flush handlers

tests/tests_hostkeys_fips.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
ansible.builtin.include_role:
9999
name: ansible-sshd
100100

101-
- name: Verify the options are correctly set
101+
- name: Verify the options are correctly set after reconfiguration
102102
when:
103103
- ansible_facts['os_family'] == 'RedHat'
104104
- ansible_facts['distribution_major_version'] | int > 6

0 commit comments

Comments
 (0)