/
install.yml
467 lines (420 loc) · 19.7 KB
/
install.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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
---
# tasks file for ipaclient
- name: Install - Ensure that IPA client packages are installed
ansible.builtin.package:
name: "{{ ipaclient_packages }}"
state: present
when: ipaclient_install_packages | bool
- name: Install - Set ipaclient_servers
ansible.builtin.set_fact:
ipaclient_servers: "{{ groups['ipaservers'] | list }}"
when: groups.ipaservers is defined and ipaclient_servers is not defined
- name: Install - Set ipaclient_servers from cluster inventory
ansible.builtin.set_fact:
ipaclient_servers: "{{ groups['ipaserver'] | list }}"
when: ipaclient_no_dns_lookup | bool and groups.ipaserver is defined and
ipaclient_servers is not defined
- name: Install - Check that either password or keytab is set
ansible.builtin.fail:
msg: "ipaadmin_password and ipaadmin_keytab cannot be used together"
when: ipaadmin_keytab is defined and ipaadmin_password is defined
- name: Install - Set default principal if no keytab is given
ansible.builtin.set_fact:
ipaadmin_principal: admin
when: ipaadmin_principal is undefined and ipaclient_keytab is undefined
- name: Install - DNS resolver configuration
when: ipaclient_configure_dns_resolver | bool
and not ipaclient_on_master | bool
block:
- name: Install - Fail on missing ipaclient_domain and ipaserver_domain
ansible.builtin.fail:
msg: "ipaclient_domain or ipaserver_domain is required for ipaclient_configure_dns_resolver"
when: ipaserver_domain is not defined and ipaclient_domain is not defined
- name: Install - Fail on missing ipaclient_servers
ansible.builtin.fail:
msg: "ipaclient_dns_servers is required for ipaclient_configure_dns_resolver"
when: ipaclient_dns_servers is not defined
- name: Install - Configure DNS resolver
ipaclient_configure_dns_resolver:
nameservers: "{{ ipaclient_dns_servers }}"
searchdomains: "{{ ipaserver_domain | default(ipaclient_domain) }}"
state: present
- name: Install - IPA client test
ipaclient_test:
### basic ###
domain: "{{ ipaserver_domain | default(ipaclient_domain) | default(omit) }}"
servers: "{{ ipaclient_servers | default(omit) }}"
realm: "{{ ipaserver_realm | default(ipaclient_realm) | default(omit) }}"
hostname: "{{ ipaclient_hostname | default(ansible_facts['fqdn']) }}"
ntp_servers: "{{ ipaclient_ntp_servers | default(omit) }}"
ntp_pool: "{{ ipaclient_ntp_pool | default(omit) }}"
no_ntp: "{{ ipaclient_no_ntp }}"
force_ntpd: "{{ ipaclient_force_ntpd }}"
nisdomain: "{{ ipaclient_nisdomain | default(omit) }}"
no_nisdomain: "{{ ipaclient_no_nisdomain }}"
kinit_attempts: "{{ ipaclient_kinit_attempts }}"
ca_cert_files: "{{ ipaclient_ca_cert_file | default(omit) }}"
configure_firefox: "{{ ipaclient_configure_firefox }}"
firefox_dir: "{{ ipaclient_firefox_dir | default(omit) }}"
ip_addresses: "{{ ipaclient_ip_addresses | default(omit) }}"
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
on_master: "{{ ipaclient_on_master }}"
### sssd ###
enable_dns_updates: "{{ ipassd_enable_dns_updates
| default(ipasssd_enable_dns_updates) }}"
register: result_ipaclient_test
- name: Install - Client deployment
when: not ansible_check_mode and
not (result_ipaclient_test.client_already_configured and
not ipaclient_allow_repair | bool and not ipaclient_force_join | bool)
block:
- name: Install - Cleanup leftover ccache
ansible.builtin.file:
path: "/etc/ipa/.dns_ccache"
state: absent
- name: Install - Configure NTP
ipaclient_setup_ntp:
### basic ###
ntp_servers: "{{ result_ipaclient_test.ntp_servers | default(omit) }}"
ntp_pool: "{{ result_ipaclient_test.ntp_pool | default(omit) }}"
no_ntp: "{{ ipaclient_no_ntp }}"
# force_ntpd: "{{ ipaclient_force_ntpd }}"
on_master: "{{ ipaclient_on_master }}"
### additional ###
servers: "{{ result_ipaclient_test.servers }}"
domain: "{{ result_ipaclient_test.domain }}"
- name: Install - Make sure One-Time Password is enabled if it's already defined
ansible.builtin.set_fact:
ipaclient_use_otp: "yes"
when: ipaclient_otp is defined
- name: Install - Disable One-Time Password for on_master
ansible.builtin.set_fact:
ipaclient_use_otp: "no"
when: ipaclient_use_otp | bool and ipaclient_on_master | bool
- name: Install - Test if IPA client has working krb5.keytab
ipaclient_test_keytab:
servers: "{{ result_ipaclient_test.servers }}"
domain: "{{ result_ipaclient_test.domain }}"
realm: "{{ result_ipaclient_test.realm }}"
hostname: "{{ result_ipaclient_test.hostname }}"
kdc: "{{ result_ipaclient_test.kdc }}"
kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}"
register: result_ipaclient_test_keytab
- name: Install - Disable One-Time Password for client with working
krb5.keytab
ansible.builtin.set_fact:
ipaclient_use_otp: "no"
when: ipaclient_use_otp | bool and
result_ipaclient_test_keytab.krb5_keytab_ok and
not ipaclient_force_join | bool
# The following block is executed when using OTP to enroll IPA client and
# the OTP isn't predefined, ie when ipaclient_use_otp is set and
# ipaclient_otp is not set.
# It connects to ipaserver and add the host with --random option in order
# to create a OneTime Password
# If a keytab is specified in the hostent, then the hostent will be disabled
# if ipaclient_use_otp is set.
- name: Install - Obtain OTP
when: ipaclient_use_otp | bool and ipaclient_otp is not defined
block:
- name: Install - Keytab or password is required for getting otp
ansible.builtin.fail:
msg: "Keytab or password is required for getting otp"
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
- name: Install - Create temporary file for keytab
ansible.builtin.tempfile:
state: file
prefix: ipaclient_temp_
path: /root
register: keytab_temp
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
when: ipaadmin_keytab is defined
- name: Install - Copy keytab to server temporary file
ansible.builtin.copy:
src: "{{ ipaadmin_keytab }}"
dest: "{{ keytab_temp.path }}"
mode: 0600
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
when: ipaadmin_keytab is defined
- name: Install - Get One-Time Password for client enrollment
no_log: yes
ipaclient_get_otp:
ipaadmin_principal: "{{ ipaadmin_principal | default(omit) }}"
ipaadmin_password: "{{ ipaadmin_password | default(omit) }}"
ipaadmin_keytab: "{{ keytab_temp.path | default(omit) }}"
hostname: "{{ result_ipaclient_test.hostname }}"
register: result_ipaclient_get_otp
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
- name: Install - Store the previously obtained OTP
no_log: yes
ansible.builtin.set_fact:
ipaadmin_orig_password: "{{ ipaadmin_password | default(omit) }}"
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword
if result_ipaclient_get_otp.host is defined }}"
rescue:
- name: Install - Report error for OTP generation
ansible.builtin.debug:
msg: "{{ result_ipaclient_get_otp.msg }}"
when: result_ipaclient_get_otp is failed
failed_when: yes
always:
- name: Install - Remove keytab temporary file
ansible.builtin.file:
path: "{{ keytab_temp.path }}"
state: absent
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
when: keytab_temp.path is defined
- name: Store predefined OTP in admin_password
no_log: yes
ansible.builtin.set_fact:
ipaadmin_orig_password: "{{ ipaadmin_password | default(omit) }}"
ipaadmin_password: "{{ ipaclient_otp }}"
when: ipaclient_otp is defined
- name: Install - Check keytab, principal and keytab
when: not ipaclient_on_master | bool
block:
# This block is executed only when
# not (not ipaclient_on_master | bool and
# not result_ipaclient_join.changed and
# not ipaclient_allow_repair | bool and
# (result_ipaclient_test_keytab.krb5_keytab_ok or
# (result_ipaclient_join.already_joined is defined and
# result_ipaclient_join.already_joined)))
- name: Install - Check if principal and keytab are set
ansible.builtin.fail:
msg: "Admin principal and client keytab cannot be used together"
when: ipaadmin_principal is defined and ipaclient_keytab is defined
- name: Install - Check if one of password or keytabs are set
ansible.builtin.fail:
msg: "At least one of password or keytabs must be specified"
when: not result_ipaclient_test_keytab.krb5_keytab_ok
and ipaadmin_password is undefined
and ipaadmin_keytab is undefined
and ipaclient_keytab is undefined
- name: "Install - From host keytab, purge {{ result_ipaclient_test.realm }}"
ansible.builtin.command: >
/usr/sbin/ipa-rmkeytab
-k /etc/krb5.keytab
-r "{{ result_ipaclient_test.realm }}"
register: result_ipa_rmkeytab
# Do not fail on error codes 3 and 5:
# 3 - Unable to open keytab
# 5 - Principal name or realm not found in keytab
# 7 - Failed to set cursor, typically when errcode
# would be issued in past
failed_when: result_ipa_rmkeytab.rc != 0 and
result_ipa_rmkeytab.rc != 3 and
result_ipa_rmkeytab.rc != 5 and
result_ipa_rmkeytab.rc != 7
when: (ipaclient_use_otp | bool or ipaclient_force_join | bool) and not ipaclient_on_master | bool
- name: Install - Backup and set hostname
ipaclient_set_hostname:
hostname: "{{ result_ipaclient_test.hostname }}"
when: not ipaclient_on_master | bool
- name: Install - Create temporary krb5 configuration
ipaclient_temp_krb5:
servers: "{{ result_ipaclient_test.servers }}"
domain: "{{ result_ipaclient_test.domain }}"
realm: "{{ result_ipaclient_test.realm }}"
hostname: "{{ result_ipaclient_test.hostname }}"
kdc: "{{ result_ipaclient_test.kdc }}"
register: result_ipaclient_temp_krb5
- name: Install - Join IPA
ipaclient_join:
servers: "{{ result_ipaclient_test.servers }}"
realm: "{{ result_ipaclient_test.realm }}"
basedn: "{{ result_ipaclient_test.basedn }}"
hostname: "{{ result_ipaclient_test.hostname }}"
force_join: "{{ ipaclient_force_join | default(omit) }}"
principal: "{{ ipaadmin_principal if not ipaclient_use_otp | bool and
ipaclient_keytab is not defined else omit }}"
password: "{{ ipaadmin_password | default(omit) }}"
keytab: "{{ ipaclient_keytab | default(omit) }}"
admin_keytab: "{{ ipaadmin_keytab if ipaadmin_keytab is defined and not ipaclient_use_otp | bool else omit }}"
# ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}"
krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}"
register: result_ipaclient_join
when: not ipaclient_on_master | bool and
(not result_ipaclient_test_keytab.krb5_keytab_ok or
ipaclient_force_join)
- name: Install - Allow repair checks
when: not ipaclient_on_master | bool and
not result_ipaclient_join.changed and
not ipaclient_allow_repair | bool and
(result_ipaclient_test_keytab.krb5_keytab_ok or
(result_ipaclient_join.already_joined is defined and
result_ipaclient_join.already_joined))
block:
- name: The krb5 configuration is not correct
ansible.builtin.fail:
msg: >
The krb5 configuration is not correct, please enable allow_repair
to fix this.
when: not result_ipaclient_test_keytab.krb5_conf_ok
- name: IPA test failed
ansible.builtin.fail:
msg: "The IPA test failed, please enable allow_repair to fix this."
when: not result_ipaclient_test_keytab.ping_test_ok
- name: Fail due to missing ca.crt file
ansible.builtin.fail:
msg: >
The ca.crt file is missing, please enable allow_repair to fix this.
when: not result_ipaclient_test_keytab.ca_crt_exists
- name: Install - Configuration
when: not (not ipaclient_on_master | bool and
not result_ipaclient_join.changed and
not ipaclient_allow_repair | bool
and (result_ipaclient_test_keytab.krb5_keytab_ok
or (result_ipaclient_join.already_joined is defined
and result_ipaclient_join.already_joined)))
block:
- name: Install - Configure IPA default.conf
ipaclient_ipa_conf:
servers: "{{ result_ipaclient_test.servers }}"
domain: "{{ result_ipaclient_test.domain }}"
realm: "{{ result_ipaclient_test.realm }}"
hostname: "{{ result_ipaclient_test.hostname }}"
basedn: "{{ result_ipaclient_test.basedn }}"
when: not ipaclient_on_master | bool
- name: Install - Configure SSSD
ipaclient_setup_sssd:
servers: "{{ result_ipaclient_test.servers }}"
domain: "{{ result_ipaclient_test.domain }}"
realm: "{{ result_ipaclient_test.realm }}"
hostname: "{{ result_ipaclient_test.hostname }}"
on_master: "{{ ipaclient_on_master }}"
no_ssh: "{{ ipaclient_no_ssh }}"
no_sshd: "{{ ipaclient_no_sshd }}"
no_sudo: "{{ ipaclient_no_sudo }}"
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
fixed_primary: "{{ ipassd_fixed_primary
| default(ipasssd_fixed_primary) }}"
permit: "{{ ipassd_permit | default(ipasssd_permit) }}"
enable_dns_updates: "{{ ipassd_enable_dns_updates
| default(ipasssd_enable_dns_updates) }}"
preserve_sssd: "{{ ipassd_preserve_sssd
| default(ipasssd_preserve_sssd) }}"
no_krb5_offline_passwords:
"{{ ipassd_no_krb5_offline_passwords
| default(ipasssd_no_krb5_offline_passwords) }}"
- name: Install - IPA API calls for remaining enrollment parts
ipaclient_api:
servers: "{{ result_ipaclient_test.servers }}"
realm: "{{ result_ipaclient_test.realm }}"
hostname: "{{ result_ipaclient_test.hostname }}"
# debug: yes
krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}"
register: result_ipaclient_api
- name: Install - Fix IPA ca
ipaclient_fix_ca:
servers: "{{ result_ipaclient_test.servers }}"
realm: "{{ result_ipaclient_test.realm }}"
basedn: "{{ result_ipaclient_test.basedn }}"
allow_repair: "{{ ipaclient_allow_repair }}"
krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}"
when: not ipaclient_on_master | bool and
result_ipaclient_test_keytab.krb5_keytab_ok and
not result_ipaclient_test_keytab.ca_crt_exists
- name: Install - Create IPA NSS database
ipaclient_setup_nss:
servers: "{{ result_ipaclient_test.servers }}"
domain: "{{ result_ipaclient_test.domain }}"
realm: "{{ result_ipaclient_test.realm }}"
basedn: "{{ result_ipaclient_test.basedn }}"
hostname: "{{ result_ipaclient_test.hostname }}"
subject_base: "{{ result_ipaclient_api.subject_base }}"
principal: "{{ ipaadmin_principal | default(omit) }}"
mkhomedir: "{{ ipaclient_mkhomedir }}"
ca_enabled: "{{ result_ipaclient_api.ca_enabled }}"
on_master: "{{ ipaclient_on_master }}"
dnsok: "{{ result_ipaclient_test.dnsok }}"
enable_dns_updates: "{{ ipassd_enable_dns_updates
| default(ipasssd_enable_dns_updates) }}"
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
ip_addresses: "{{ ipaclient_ip_addresses | default(omit) }}"
request_cert: "{{ ipaclient_request_cert }}"
preserve_sssd: "{{ ipassd_preserve_sssd
| default(ipasssd_preserve_sssd) }}"
no_ssh: "{{ ipaclient_no_ssh }}"
no_sshd: "{{ ipaclient_no_sshd }}"
no_sudo: "{{ ipaclient_no_sudo }}"
subid: "{{ ipaclient_subid }}"
fixed_primary: "{{ ipassd_fixed_primary
| default(ipasssd_fixed_primary) }}"
permit: "{{ ipassd_permit | default(ipasssd_permit) }}"
no_krb5_offline_passwords:
"{{ ipassd_no_krb5_offline_passwords
| default(ipasssd_no_krb5_offline_passwords) }}"
no_dns_sshfp: "{{ ipaclient_no_dns_sshfp }}"
nosssd_files: "{{ result_ipaclient_test.nosssd_files }}"
selinux_works: "{{ result_ipaclient_test.selinux_works }}"
krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}"
- name: Install - Configure SSH and SSHD
ipaclient_setup_ssh:
servers: "{{ result_ipaclient_test.servers }}"
sssd: "{{ result_ipaclient_test.sssd }}"
no_ssh: "{{ ipaclient_no_ssh }}"
ssh_trust_dns: "{{ ipaclient_ssh_trust_dns }}"
no_sshd: "{{ ipaclient_no_sshd }}"
- name: Install - Configure automount
ipaclient_setup_automount:
servers: "{{ result_ipaclient_test.servers }}"
sssd: "{{ result_ipaclient_test.sssd }}"
automount_location: "{{ ipaclient_automount_location | default(omit) }}"
- name: Install - Configure firefox
ipaclient_setup_firefox:
firefox_dir: "{{ ipaclient_firefox_dir | default(omit) }}"
domain: "{{ result_ipaclient_test.domain }}"
when: ipaclient_configure_firefox | bool
- name: Install - Configure NIS
ipaclient_setup_nis:
domain: "{{ result_ipaclient_test.domain }}"
nisdomain: "{{ ipaclient_nisdomain | default(omit) }}"
when: not ipaclient_no_nisdomain | bool
- name: Remove temporary krb5.conf
ansible.builtin.file:
path: "{{ result_ipaclient_temp_krb5.krb_name }}"
state: absent
when: result_ipaclient_temp_krb5.krb_name is defined
- name: Install - Configure krb5 for IPA realm
ipaclient_setup_krb5:
realm: "{{ result_ipaclient_test.realm }}"
domain: "{{ result_ipaclient_test.domain }}"
servers: "{{ result_ipaclient_test.servers }}"
kdc: "{{ result_ipaclient_test.kdc }}"
dnsok: "{{ result_ipaclient_test.dnsok }}"
client_domain: "{{ result_ipaclient_test.client_domain }}"
hostname: "{{ result_ipaclient_test.hostname }}"
sssd: "{{ result_ipaclient_test.sssd }}"
force: "{{ ipaclient_force }}"
# on_master: "{{ ipaclient_on_master }}"
when: not ipaclient_on_master | bool
- name: Install - Configure certmonger
ipaclient_setup_certmonger:
realm: "{{ result_ipaclient_test.realm }}"
hostname: "{{ result_ipaclient_test.hostname }}"
subject_base: "{{ result_ipaclient_api.subject_base }}"
ca_enabled: "{{ result_ipaclient_api.ca_enabled }}"
request_cert: "{{ ipaclient_request_cert }}"
when: not ipaclient_on_master | bool
always:
- name: Install - Restore original admin password if overwritten by OTP
no_log: yes
ansible.builtin.set_fact:
ipaadmin_password: "{{ ipaadmin_orig_password }}"
when: ipaclient_use_otp | bool and ipaadmin_orig_password is defined
- name: Cleanup leftover ccache
ansible.builtin.file:
path: "/etc/ipa/.dns_ccache"
state: absent
- name: Remove temporary krb5.conf
ansible.builtin.file:
path: "{{ result_ipaclient_temp_krb5.krb_name }}"
state: absent
when: result_ipaclient_temp_krb5.krb_name is defined
- name: Remove temporary krb5.conf backup
ansible.builtin.file:
path: "{{ result_ipaclient_temp_krb5.krb_name }}.ipabkp"
state: absent
when: result_ipaclient_temp_krb5.krb_name is defined