|
| 1 | +# Assisted-by: Cursor using models Cursor Grok 4.5, Composer 2.5, Sonnet 5. |
| 2 | +--- |
| 3 | +- name: Test NTP server authentication keys |
| 4 | + hosts: all |
| 5 | + vars: |
| 6 | + timesync_secure_logging: false |
| 7 | + timesync_ntp_provider: chrony |
| 8 | + timesync_ntp_servers: |
| 9 | + - hostname: 172.16.124.1 |
| 10 | + key: "{{ __timesync_test_key_simple }}" |
| 11 | + - hostname: 172.16.124.2 |
| 12 | + key: "{{ __timesync_test_key_simple }}" |
| 13 | + - hostname: 172.16.124.3 |
| 14 | + key: "{{ __timesync_test_key_md5 }}" |
| 15 | + - hostname: 172.16.124.4 |
| 16 | + key: "{{ __timesync_test_key_md5 }}" |
| 17 | + - hostname: 172.16.124.5 |
| 18 | + key: "{{ __timesync_test_key_sha1 }}" |
| 19 | + - hostname: 172.16.124.6 |
| 20 | + key: "{{ __timesync_test_key_sha1 }}" |
| 21 | + |
| 22 | + tasks: |
| 23 | + - name: Run key tests |
| 24 | + tags: tests::verify |
| 25 | + block: |
| 26 | + - name: Run the role |
| 27 | + include_tasks: tasks/run_role_with_clear_facts.yml |
| 28 | + vars: |
| 29 | + __sr_public: true |
| 30 | + |
| 31 | + - name: Flush handlers |
| 32 | + meta: flush_handlers |
| 33 | + |
| 34 | + - name: Fetch chrony.conf file |
| 35 | + slurp: |
| 36 | + src: "{{ timesync_chrony_conf_path }}" |
| 37 | + register: __keys_chrony_conf_encoded |
| 38 | + |
| 39 | + - name: Decode chrony.conf file |
| 40 | + set_fact: |
| 41 | + __keys_chrony_conf: "{{ __keys_chrony_conf_encoded.content | b64decode }}" |
| 42 | + |
| 43 | + - name: Fetch chrony key file |
| 44 | + slurp: |
| 45 | + src: "{{ timesync_chrony_keyfile_path }}" |
| 46 | + register: __keys_chrony_keys_encoded |
| 47 | + |
| 48 | + - name: Decode chrony key file |
| 49 | + set_fact: |
| 50 | + __keys_chrony_keys: "{{ __keys_chrony_keys_encoded.content | b64decode }}" |
| 51 | + |
| 52 | + - name: Check chrony.conf key settings on ansible 2.10 and later |
| 53 | + assert: |
| 54 | + that: |
| 55 | + - __keys_chrony_conf is search('keyfile ' ~ timesync_chrony_keyfile_path) |
| 56 | + - __keys_chrony_conf is search('172\.16\.124\.1.* key 10') |
| 57 | + - __keys_chrony_conf is search('172\.16\.124\.2.* key 10') |
| 58 | + - __keys_chrony_conf is search('172\.16\.124\.3.* key 20') |
| 59 | + - __keys_chrony_conf is search('172\.16\.124\.4.* key 20') |
| 60 | + - __keys_chrony_conf is search('172\.16\.124\.5.* key 30') |
| 61 | + - __keys_chrony_conf is search('172\.16\.124\.6.* key 30') |
| 62 | + when: ansible_version.full is version('2.10', '>=') |
| 63 | + |
| 64 | + # the unique filter does not preserve order on ansible 2.9 |
| 65 | + - name: Check chrony.conf key settings on ansible 2.9 |
| 66 | + assert: |
| 67 | + that: |
| 68 | + - __keys_chrony_conf is search('keyfile ' ~ timesync_chrony_keyfile_path) |
| 69 | + - __keys_chrony_conf is search('172\.16\.124\.1.* key [1-3]0') |
| 70 | + - __keys_chrony_conf is search('172\.16\.124\.2.* key [1-3]0') |
| 71 | + - __keys_chrony_conf is search('172\.16\.124\.3.* key [1-3]0') |
| 72 | + - __keys_chrony_conf is search('172\.16\.124\.4.* key [1-3]0') |
| 73 | + - __keys_chrony_conf is search('172\.16\.124\.5.* key [1-3]0') |
| 74 | + - __keys_chrony_conf is search('172\.16\.124\.6.* key [1-3]0') |
| 75 | + when: ansible_version.full is version('2.10', '<') |
| 76 | + |
| 77 | + - name: Check chrony key file contents on ansible 2.10 and later |
| 78 | + assert: |
| 79 | + that: |
| 80 | + - __keys_chrony_keys is search('10 timesync-test-simple-key-32chars') |
| 81 | + - __keys_chrony_keys is search('20 MD5 ASCII:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') |
| 82 | + - __keys_chrony_keys is search('30 SHA1 HEX:933F62BE1D604E68A81B557F18CFA200483F5B70') |
| 83 | + when: ansible_version.full is version('2.10', '>=') |
| 84 | + |
| 85 | + - name: Check chrony key file contents on ansible 2.9 |
| 86 | + assert: |
| 87 | + that: |
| 88 | + - __keys_chrony_keys is search('[1-3]0 timesync-test-simple-key-32chars') |
| 89 | + - __keys_chrony_keys is search('[1-3]0 MD5 ASCII:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') |
| 90 | + - __keys_chrony_keys is search('[1-3]0 SHA1 HEX:933F62BE1D604E68A81B557F18CFA200483F5B70') |
| 91 | + when: ansible_version.full is version('2.10', '<') |
| 92 | + |
| 93 | + - name: Check chrony key file permissions |
| 94 | + stat: |
| 95 | + path: "{{ timesync_chrony_keyfile_path }}" |
| 96 | + register: __keys_chrony_keys_stat |
| 97 | + |
| 98 | + - name: Verify chrony key file permissions |
| 99 | + assert: |
| 100 | + that: |
| 101 | + - __keys_chrony_keys_stat.stat.pw_name == 'root' |
| 102 | + - __keys_chrony_keys_stat.stat.gr_name == 'chrony' |
| 103 | + - __keys_chrony_keys_stat.stat.mode == '0640' |
| 104 | + |
| 105 | + - name: Check chrony conf for ansible_managed, fingerprint |
| 106 | + include_tasks: tasks/check_header.yml |
| 107 | + vars: |
| 108 | + __file_content: "{{ __keys_chrony_conf_encoded }}" |
| 109 | + __fingerprint: "system_role:timesync" |
| 110 | + |
| 111 | + - name: Grab the journal for chronyd |
| 112 | + command: journalctl -u chronyd |
| 113 | + register: __keys_chrony_journal |
| 114 | + changed_when: false |
| 115 | + |
| 116 | + - name: Check for chrony entries in the journal |
| 117 | + assert: |
| 118 | + that: |
| 119 | + - __keys_chrony_journal.stdout is not search("Key .* is too short") |
| 120 | + - __keys_chrony_journal.stdout is not search("Key .* is missing") |
| 121 | + |
| 122 | + - name: Test timesync_remove_keyfile_if_no_keys |
| 123 | + block: |
| 124 | + - name: Run the role without keys and default remove keyfile setting |
| 125 | + include_tasks: tasks/run_role_with_clear_facts.yml |
| 126 | + vars: |
| 127 | + __sr_public: true |
| 128 | + timesync_ntp_provider: chrony |
| 129 | + timesync_ntp_servers: |
| 130 | + - hostname: 172.16.124.1 |
| 131 | + |
| 132 | + - name: Check chrony key file is retained by default |
| 133 | + stat: |
| 134 | + path: "{{ timesync_chrony_keyfile_path }}" |
| 135 | + register: __keys_chrony_keys_retained_stat |
| 136 | + |
| 137 | + - name: Verify chrony key file is retained by default |
| 138 | + assert: |
| 139 | + that: __keys_chrony_keys_retained_stat.stat.exists |
| 140 | + |
| 141 | + - name: Run the role without keys and remove keyfile enabled |
| 142 | + include_tasks: tasks/run_role_with_clear_facts.yml |
| 143 | + vars: |
| 144 | + __sr_public: true |
| 145 | + timesync_ntp_provider: chrony |
| 146 | + timesync_ntp_servers: |
| 147 | + - hostname: 172.16.124.1 |
| 148 | + timesync_remove_keyfile_if_no_keys: true |
| 149 | + |
| 150 | + - name: Flush handlers |
| 151 | + meta: flush_handlers |
| 152 | + |
| 153 | + - name: Check chrony key file was removed |
| 154 | + stat: |
| 155 | + path: "{{ timesync_chrony_keyfile_path }}" |
| 156 | + register: __keys_chrony_keys_removed_stat |
| 157 | + |
| 158 | + - name: Verify chrony key file was removed |
| 159 | + assert: |
| 160 | + that: not __keys_chrony_keys_removed_stat.stat.exists |
| 161 | + |
| 162 | + always: |
| 163 | + - name: Cleanup after tests |
| 164 | + tags: tests::cleanup |
| 165 | + include_tasks: tasks/cleanup.yml |
0 commit comments