-
Notifications
You must be signed in to change notification settings - Fork 76
/
validate_vars.yml
195 lines (178 loc) · 9.34 KB
/
validate_vars.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# 2020-01-21: Ansible Input Validation (basic sanity checking for now) to check
# that *_install and *_enabled variables (as set in places like
# /etc/iiab/local_vars.yml) appear coherent i.e. (1) are confirmed defined,
# (2) have type boolean (Ansible often inverts logic when boolean vars are
# accidentally declared as strings, see below!) and (3) have plausible values.
# 2020-01-23: *_installed variables (incrementally saved to
# /etc/iiab/iiab_state.yml) are not required to be boolean (or even defined!)
# for now. However if any of these are defined, the corresponding value of
# *_install must be True, as IIAB does not currently support uninstalling!
# Stricter validation is needed later, when roles/playbooks/tasks are invoked
# by various scripts, possibly bypassing 0-init? Either way, risks abound :/
# 1. "Ansible 2.8+ ADVISORY: avoid warnings by using 'when: var | bool' for
# top-level BARE vars (in case they're strings, instead of boolean)" per #1632.
# 2020-10-16: NO LONGER NEC, SEE: https://github.com/iiab/iiab/pull/2576
# 2. "How Exactly Does Ansible Parse Boolean Variables?"
# https://stackoverflow.com/questions/47877464/how-exactly-does-ansible-parse-boolean-variables/47877502#47877502
# ...is very helpful but has it slightly wrong, as Ansible implements only ~18
# of YAML's 22 definitions of boolean (https://yaml.org/type/bool.html).
# i.e. Ansible fails to implement y|Y|n|N, only allowing ~18 boolean values:
#
# yes|Yes|YES|no|No|NO
# |true|True|TRUE|false|False|FALSE
# |on|On|ON|off|Off|OFF
#
# Otherwise 'var != (var | bool)' is dangerously common, e.g. (1) when a var
# is not one of the above ~18 words (forcing it to become a string) or (2) when
# a var is accidentally set using quotes (forcing it to become a string) these
# ~18 words too WILL FAIL as strings (as will any non-empty string...so beware
# casting strings to boolean later on...can make the situation worse!)
# https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.8.html#bare-variables-in-conditionals
#
# 2020-07-08 - Excellent analysis & summary by Jon Spriggs: "In Ansible,
# determine the type of a value, and casting those values to other types"
# https://jon.sprig.gs/blog/post/1801
#
# 2021-01-29 - ansible-base 2.10.5 (1) is more strict about empty string vars
# (2) no longer supports "when: myvar is boolean", "is integer" & "is float"
# (3) brings yet more "Ansible Collections" dependency changes (undocumented!)
# Details: https://github.com/iiab/iiab/pull/2672 (see also #2669)
# 3. "How do i fail a task in Ansible if the variable contains a boolean value?
# I want to perform input validation for Ansible playbooks"
# https://stackoverflow.com/questions/46664127/how-do-i-fail-a-task-in-ansible-if-the-variable-contains-a-boolean-value-i-want/46667499#46667499
# 2020-01-23: Checks 53 + 53 + up-to-53 vars...for now...expect this to change!
# 2020-09-26: Commented out 14 vars that are {mandatory, dependencies, or
# unmaintained-for-years} for IIAB 7.2 release. Keeping in mind that vars
# will come and go as IIAB evolves, let's try to keep these 9 aligned:
#
# http://FAQ.IIAB.IO > "What services (IIAB apps) are suggested during installation?"
# https://github.com/iiab/iiab/blob/master/vars/local_vars_min.yml
# https://github.com/iiab/iiab/blob/master/vars/local_vars_medium.yml
# https://github.com/iiab/iiab/blob/master/vars/local_vars_big.yml
# https://github.com/iiab/iiab/blob/master/vars/default_vars.yml
# https://github.com/iiab/iiab/blob/master/unmaintained-roles.txt
# https://github.com/iiab/iiab/blob/master/roles/0-DEPRECATED-ROLES/
# https://github.com/iiab/iiab/blob/master/tests/test.yml
# https://github.com/iiab/iiab/blob/master/roles/0-init/tasks/validate_vars.yml
#
# 2020-11-04: Fix validation of 5 [now 4] core dependencies, for ./runrole etc
- name: Set vars_checklist for 45 + 45 + 40 vars ("XYZ_install" + "XYZ_enabled" + "XYZ_installed") to be checked
set_fact:
vars_checklist:
- hostapd
- dnsmasq
- bluetooth
- sshd
- openvpn
- remoteit
- admin_console
#- nginx # MANDATORY
#- apache # Unmaintained - former dependency
- squid
- cups
- samba
- usb_lib
- azuracast
- gitea
- jupyterhub
- lokole
- mysql # Dependency - excluded from _installed check below
- mediawiki
- mosquitto
- nodejs # Dependency - excluded from _installed check below
- nodered
- nextcloud
- wordpress
- kalite
- kolibri
- kiwix
- postgresql # Dependency - excluded from _installed check below
- moodle
- mongodb # Dependency - excluded from _installed check below
- sugarizer
- osm_vector_maps
- transmission
- awstats
- matomo
- monit
- munin
- phpmyadmin
- vnstat
- yarn # Dependency - excluded from _installed check below
- captiveportal
- internetarchive
- minetest
- calibreweb
- calibre
- pbx
- network
- name: Assert that {{ vars_checklist | length }} "XYZ_install" vars are all... defined
assert:
that: "{{ item }}_install is defined"
fail_msg: "VARIABLE MUST BE DEFINED: '{{ item }}_install' NEEDS A PROPER (UNQUOTED) ANSIBLE BOOLEAN VALUE e.g. IN: /etc/iiab/local_vars.yml"
quiet: yes
loop: "{{ vars_checklist }}"
- name: Assert that {{ vars_checklist | length }} "XYZ_enabled" vars are all... defined
assert:
that: "{{ item }}_enabled is defined"
fail_msg: "VARIABLE MUST BE DEFINED: '{{ item }}_enabled' NEEDS A PROPER (UNQUOTED) ANSIBLE BOOLEAN VALUE e.g. IN: /etc/iiab/local_vars.yml"
quiet: yes
loop: "{{ vars_checklist }}"
- name: Assert that {{ vars_checklist | length }} "XYZ_install" vars are all... type boolean (NOT type string, which can invert logic!)
assert:
that: "{{ item }}_install | type_debug == 'bool'"
fail_msg: "VARIABLE MUST BE BOOLEAN: '{{ item }}_install' now has type '{{ lookup('vars', item + '_install') | type_debug }}' and value '{{ lookup('vars', item + '_install') }}' -- PLEASE SET A PROPER (UNQUOTED) ANSIBLE BOOLEAN VALUE e.g. IN: /etc/iiab/local_vars.yml"
quiet: yes
loop: "{{ vars_checklist }}"
- name: Assert that {{ vars_checklist | length }} "XYZ_enabled" vars are all... type boolean (NOT type string, which can invert logic!)
assert:
that: "{{ item }}_enabled | type_debug == 'bool'"
fail_msg: "VARIABLE MUST BE BOOLEAN: '{{ item }}_enabled' now has type '{{ lookup('vars', item + '_enabled') | type_debug }}' and value '{{ lookup('vars', item + '_enabled') }}' -- PLEASE SET A PROPER (UNQUOTED) ANSIBLE BOOLEAN VALUE e.g. IN: /etc/iiab/local_vars.yml"
quiet: yes
loop: "{{ vars_checklist }}"
- name: 'DISALLOW "XYZ_install: False" WITH "XYZ_enabled: True" ...for all {{ vars_checklist | length }} var pairs'
assert:
that: "{{ item }}_install or not {{ item }}_enabled"
fail_msg: "DISALLOWED: '{{ item }}_install: False' WITH '{{ item }}_enabled: True' -- IIAB DOES NOT SUPPORT UNINSTALLS -- please verify those 2 variable values e.g. in /etc/iiab/local_vars.yml, and other places variables are defined?"
quiet: yes
loop: "{{ vars_checklist }}"
- name: 'DISALLOW "XYZ_install: False" WHEN "XYZ_installed is defined" IN /etc/iiab/iiab_state.yml ...for up-to-{{ vars_checklist | length }} var pairs'
assert:
that: "{{ item }}_install or {{ item }}_installed is undefined"
fail_msg: "DISALLOWED: '{{ item }}_install: False' (e.g. in /etc/iiab/local_vars.yml) WHEN '{{ item }}_installed' is defined (e.g. in /etc/iiab/iiab_state.yml) -- IIAB DOES NOT SUPPORT UNINSTALLS -- please verify those 2 files especially, and other places variables are defined?"
quiet: yes
when: item != 'mysql' and item != 'postgresql' and item != 'mongodb' and item != 'nodejs' and item != 'yarn' # Exclude auto-installed dependencies
loop: "{{ vars_checklist }}"
- name: Set vars_deprecated_list for 4+ vars ("XYZ_install") to be checked
set_fact:
vars_deprecated_list:
- dhcpd # Deprecated
- named # Deprecated
- wondershaper # Deprecated
- dansguardian # Deprecated
#- xo_services # Unmaintained
#- activity_server # Unmaintained
#- ejabberd_xs # Unmaintained
#- idmgr # Unmaintained
#- dokuwiki # Unmaintained
#- ejabberd # Unmaintained
#- elgg # Unmaintained
- name: 'DISALLOW "XYZ_install: True" if deprecated'
assert:
that: "{{ item }}_install is undefined or not {{ item }}_install"
fail_msg: "DISALLOWED: '{{ item }}_install: True' (e.g. in /etc/iiab/local_vars.yml)"
quiet: yes
loop: "{{ vars_deprecated_list }}"
# 2023-12-04: ansible-core 2.16.1 suddenly no longer allows 'assert' with
# 'with_items' below (whereas 'loop' construct above works!) BACKGROUND:
#
# '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.”'
# https://docs.ansible.com/ansible-core/2.16/porting_guides/porting_guide_core_2.16.html#playbook
#
# with_items:
# - dhcpd # Deprecated
# - named # Deprecated
# - wondershaper # Deprecated
# - dansguardian # Deprecated