Skip to content

Commit 0e7f737

Browse files
committed
(multiple) Enable FreeIPA for OSP 17.1 adoption CI
This commit introduces support for deploying a FreeIPA server within the OSP 17.1 adoption CI. The following has been added: - Tasks for the initial setup and configuration of a FreeIPA server. - DNS configuration for the undercloud, followed by the execution of `undercloud-ipa-install.yaml`. - DNS configuration for the overcloud to use the new FreeIPA instance. Following code has been modified: - hci adoption scenario is updated to include the creation of the FreeIPA vm - do not add the unique ID to osp-underclud name. Predicted hostname is required for tls-e Signed-off-by: Mikolaj Ciecierski <mciecier@redhat.com>
1 parent daa7918 commit 0e7f737

File tree

9 files changed

+341
-1
lines changed

9 files changed

+341
-1
lines changed

docs/dictionary/en-custom.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ flbxutz
200200
fmw
201201
fqdn
202202
freefonts
203+
FreeIPA
203204
frmo
204205
fsid
205206
fultonj

roles/adoption_osp_deploy/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ configure the OSP17.1 deployment.
3131
* `cifmw_adoption_osp_deploy_bgp`: (Boolean) Enable BGP support for the OSP
3232
deployment. When enabled, uses BGP-specific network configurations and
3333
templates. Defaults to `false`.
34+
* `cifmw_adoption_osp_deploy_freeipa_admin_password`: (String) FreeIPA server admin password.
3435

3536
### Break point
3637

roles/adoption_osp_deploy/defaults/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ cifmw_adoption_osp_deploy_adoption_vars_exclude_nets:
3232
cifmw_adoption_osp_deploy_overcloud_extra_args: ''
3333

3434
cifmw_adoption_osp_deploy_bgp: false
35+
36+
cifmw_adoption_osp_deploy_freeipa_admin_password: "nomoresecrets"

roles/adoption_osp_deploy/tasks/main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
loop_control:
4646
loop_var: overcloud_vars
4747

48+
- name: Prepare FreeIPA environment
49+
tags:
50+
- tlse
51+
ansible.builtin.import_tasks: prepare_freeipa.yml
52+
when: cifmw_adoption_osp_deploy_scenario.tlse | default(false)
53+
4854
- name: Prepare undercloud enviornment
4955
tags:
5056
- undercloud
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Ensure freeipa vm is started and reachable
18+
vars:
19+
_cifmw_libvirt_manager_layout:
20+
vms:
21+
free-ipas:
22+
start: true
23+
disk_file_name: "dummy"
24+
cifmw_libvirt_manager_all_vms: >-
25+
{%- set vms = {} -%}
26+
{%- for vm in _vm_groups['free-ipas'] -%}
27+
{%- set _ = vms.update({vm: 'free-ipas'}) -%}
28+
{%- endfor -%}
29+
{{ vms }}
30+
ansible_libvirt_pools: {}
31+
ansible.builtin.include_role:
32+
name: "libvirt_manager"
33+
tasks_from: "start_vms.yml"
34+
apply:
35+
delegate_to: "{{ cifmw_target_host | default('localhost') }}"
36+
37+
- name: Run prepration tasks on freeipa
38+
delegate_to: "free-ipa-0"
39+
vars:
40+
_freeipa_name: "{{ _vm_groups['free-ipas'] | first }}"
41+
_freeipa_net: "{{ cifmw_networking_env_definition.instances[_freeipa_name] }}"
42+
freeipa_ip: "{{ _freeipa_net.networks.ocpbm[ip_version|default('ip_v4')] }}"
43+
_undercloud_name: "{{ _vm_groups['osp-underclouds'] | first }}"
44+
_undercloud_net: "{{ cifmw_networking_env_definition.instances[_undercloud_name] }}"
45+
undercloud_ip: "{{ _undercloud_net.networks.ocpbm[ip_version|default('ip_v4')] }}"
46+
cloud_domain: "{{ cifmw_adoption_osp_deploy_scenario.cloud_domain }}"
47+
block:
48+
- name: Ensure needed logins
49+
ansible.builtin.include_tasks: login_registries.yml
50+
args:
51+
apply:
52+
delegate_to: "free-ipa-0"
53+
54+
- name: Set hostname to freeipa-0.{{ cloud_domain }}
55+
become: true
56+
ansible.builtin.hostname:
57+
name: "freeipa-0.{{ cloud_domain }}"
58+
use: "systemd"
59+
60+
- name: Ensure /etc/hosts file correctly maps the FQDN to freeipa IP address
61+
become: true
62+
ansible.builtin.lineinfile:
63+
path: /etc/hosts
64+
line: "{{ freeipa_ip }} {{ ansible_hostname }}.{{ cloud_domain }} {{ ansible_hostname }}"
65+
create: true
66+
state: present
67+
mode: "0644"
68+
69+
- name: Install FreeIPA server packages
70+
become: true
71+
ansible.builtin.package:
72+
name:
73+
- ipa-server
74+
- ipa-server-dns
75+
- curl
76+
- iptables
77+
state: present
78+
79+
- name: Update NSS (required for CA server to launch during deploy)
80+
become: true
81+
ansible.builtin.package:
82+
name: nss
83+
state: latest # noqa: package-latest
84+
85+
- name: Deploy FreeIPA server
86+
become: true
87+
ansible.builtin.command:
88+
cmd: >-
89+
ipa-server-install -U
90+
--hostname freeipa-0.{{ cloud_domain }}
91+
--realm {{ cloud_domain.upper() }}
92+
--admin-password {{ cifmw_adoption_osp_deploy_freeipa_admin_password }}
93+
--ds-password {{ cifmw_adoption_osp_deploy_freeipa_admin_password }}
94+
--ip-address={{ freeipa_ip }}
95+
--setup-dns
96+
--auto-reverse
97+
--no-dnssec-validation
98+
--allow-zone-overlap
99+
--forwarder=192.168.111.1
100+
101+
- name: Create systemd resolv.conf
102+
become: true
103+
ansible.builtin.copy:
104+
dest: "/usr/lib/systemd/resolv.conf"
105+
content: |
106+
search {{ cloud_domain }}
107+
nameserver 127.0.0.1
108+
mode: '0644'
109+
110+
- name: Create a symbolic link of systemd resolv.conf
111+
become: true
112+
ansible.builtin.file:
113+
src: "/usr/lib/systemd/resolv.conf"
114+
dest: "/etc/resolv.conf"
115+
owner: root
116+
group: root
117+
state: link
118+
force: true
119+
120+
- name: Does the DNS ACL exist
121+
become: true
122+
ansible.builtin.shell: >-
123+
ldapsearch -LLL -x -D "cn=Directory Manager" -w {{ cifmw_adoption_osp_deploy_freeipa_admin_password }} -s base
124+
-b cn=dns,dc={{ cloud_domain.split(".")[0] }},dc={{ cloud_domain.split(".")[1] }}
125+
aci='*Allow hosts to read DNS A/AAA/CNAME/PTR records*' numSubordinates |
126+
sed -n 's/^[ \t]*numSubordinates:[ \t]*\(.*\)/\1/p'
127+
register: dns_aci_count
128+
ignore_errors: true
129+
130+
- name: Add ACL to allow hosts access to DNS
131+
become: true
132+
ansible.builtin.shell:
133+
cmd: |
134+
set -o pipefail
135+
cat << EOF | ldapmodify -x -D "cn=Directory Manager" -w {{ cifmw_adoption_osp_deploy_freeipa_admin_password }}
136+
dn: cn=dns,dc={{ cloud_domain.split(".")[0] }},dc={{ cloud_domain.split(".")[1] }}
137+
changetype: modify
138+
add: aci
139+
aci: (targetattr = "aaaarecord || arecord || cnamerecord || idnsname || objectclass || ptrrecord")(targetfilter = "(&(objectclass=idnsrecord)(|(aaaarecord=*)(arecord=*)(cnamerecord=*)(ptrrecord=*)(idnsZoneActive=TRUE)))")(version 3.0; acl "Allow hosts to read DNS A/AAA/CNAME/PTR records"; allow (read,search,compare) userdn = "ldap:///fqdn=*,cn=computers,cn=accounts,dc={{ freeipa_domain.split('.')[0] }},dc={{ freeipa_domain.split('.')[1] }}";)
140+
EOF
141+
when: dns_aci_count.stdout|default(0)|int == 0
142+
143+
- name: Update /etc/hosts with undercloud's details
144+
become: true
145+
ansible.builtin.lineinfile:
146+
dest: "/etc/hosts"
147+
line: "{{ undercloud_ip }} {{ _undercloud_name }}.{{ cloud_domain }} {{ _undercloud_name }}"
148+
state: present
149+
150+
- name: Ensure DNS query is not blocked by iptables
151+
become: true
152+
ansible.builtin.iptables:
153+
action: insert
154+
comment: "Allow DNS query"
155+
table: filter
156+
chain: INPUT
157+
jump: ACCEPT
158+
protocol: "udp"
159+
destination_port: 53
160+
161+
- name: Restart FreeIPA server
162+
become: true
163+
ansible.builtin.service:
164+
name: ipa
165+
state: restarted

roles/adoption_osp_deploy/tasks/prepare_overcloud.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,61 @@
371371
dest_file: /usr/share/openstack-tripleo-heat-templates/deployment/cinder/cinder-api-container-puppet.yaml
372372
- patch_file: files/bgp-tht-frr-patch
373373
dest_file: /usr/share/openstack-tripleo-heat-templates/deployment/frr/frr-container-ansible.yaml
374+
375+
- name: Run FreeIPA preparation tasks for overcloud nodes
376+
when: cifmw_adoption_osp_deploy_scenario.tlse | default(false)
377+
vars:
378+
cloud_domain: "{{ cifmw_adoption_osp_deploy_scenario.cloud_domain }}"
379+
_freeipa_name: "{{ _vm_groups['free-ipas'] | first }}"
380+
_freeipa_net: "{{ cifmw_networking_env_definition.instances[_freeipa_name] }}"
381+
block:
382+
- name: Set 'dns=none' in /etc/NetworkManager/NetworkManager.conf
383+
become: true
384+
delegate_to: "{{ overcloud_vm }}"
385+
community.general.ini_file:
386+
path: /etc/NetworkManager/NetworkManager.conf
387+
state: present
388+
no_extra_spaces: true
389+
section: main
390+
option: dns
391+
value: none
392+
backup: true
393+
mode: '0644'
394+
loop: "{{ _tripleo_nodes_stack[_overcloud_name] }}"
395+
loop_control:
396+
loop_var: overcloud_vm
397+
398+
- name: Set PEERDNS to 'no' for eth0
399+
become: true
400+
delegate_to: "{{ overcloud_vm }}"
401+
ansible.builtin.lineinfile:
402+
path: "/etc/sysconfig/network-scripts/ifcfg-eth0"
403+
regexp: '^PEERDNS=.*'
404+
line: 'PEERDNS=no'
405+
loop: "{{ _tripleo_nodes_stack[_overcloud_name] }}"
406+
loop_control:
407+
loop_var: overcloud_vm
408+
409+
- name: Set dns nameservers for etho0
410+
become: true
411+
delegate_to: "{{ overcloud_vm }}"
412+
ansible.builtin.lineinfile:
413+
path: "/etc/sysconfig/network-scripts/ifcfg-eth0"
414+
regexp: '^DNS1=.*'
415+
line: "DNS1={{ _freeipa_net.networks.ocpbm[ip_version|default('ip_v4')] }}"
416+
loop: "{{ _tripleo_nodes_stack[_overcloud_name] }}"
417+
loop_control:
418+
loop_var: overcloud_vm
419+
420+
- name: Set resolv.conf content
421+
become: true
422+
delegate_to: "{{ overcloud_vm }}"
423+
ansible.builtin.copy:
424+
dest: "/etc/resolv.conf"
425+
content: |
426+
search {{ cloud_domain }}
427+
nameserver {{ _freeipa_net.networks.ocpbm[ip_version|default('ip_v4')] }}
428+
mode: "0644"
429+
loop: "{{ _tripleo_nodes_stack[_overcloud_name] }}"
430+
loop_control:
431+
loop_var: overcloud_vm

roles/adoption_osp_deploy/tasks/prepare_undercloud.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,95 @@
272272
state: "present"
273273
mode: "0644"
274274
loop: "{{ _undercloud_conf.config }}"
275+
276+
- name: Run undercloud FreeIPA enablement tasks
277+
when: cifmw_adoption_osp_deploy_scenario.tlse | default(false)
278+
vars:
279+
cloud_domain: "{{ cifmw_adoption_osp_deploy_scenario.cloud_domain }}"
280+
_freeipa_name: "{{ _vm_groups['free-ipas'] | first }}"
281+
_freeipa_net: "{{ cifmw_networking_env_definition.instances[_freeipa_name] }}"
282+
freeipa_ip: "{{ _freeipa_net.networks.ocpbm[ip_version|default('ip_v4')] }}"
283+
delegate_to: "osp-undercloud-0"
284+
block:
285+
- name: Set resolv.conf content
286+
become: true
287+
ansible.builtin.copy:
288+
dest: "/etc/resolv.conf"
289+
content: |
290+
search {{ cloud_domain }}
291+
nameserver {{ freeipa_ip }}
292+
mode: "0644"
293+
294+
- name: Set hostname on undercloud
295+
become: true
296+
ansible.builtin.shell: |
297+
sudo hostnamectl set-hostname osp-undercloud-0.{{ cloud_domain }}
298+
sudo hostnamectl set-hostname --transient osp-undercloud-0.{{ cloud_domain }}
299+
300+
- name: Create ssh key pair
301+
ansible.builtin.user:
302+
name: zuul
303+
generate_ssh_key: true
304+
ssh_key_bits: 2048
305+
ssh_key_file: "{{ ansible_user_dir }}/.ssh/id_rsa"
306+
307+
- name: Slurp pub key
308+
ansible.builtin.slurp:
309+
src: "{{ ansible_user_dir ~ '/.ssh/id_rsa.pub' }}"
310+
register: pub_key
311+
312+
- name: Ensure zuul can ssh to localhost
313+
ansible.posix.authorized_key:
314+
user: zuul
315+
key: "{{ pub_key['content'] | b64decode }}"
316+
317+
- name: Run undercloud ipa installer
318+
become: true
319+
become_user: zuul
320+
ansible.builtin.command:
321+
cmd: |-
322+
ansible-playbook
323+
--ssh-extra-args "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
324+
/usr/share/ansible/tripleo-playbooks/undercloud-ipa-install.yaml
325+
environment:
326+
IPA_DOMAIN: "{{ cloud_domain }}"
327+
IPA_REALM: "{{ cloud_domain|upper }}"
328+
IPA_ADMIN_USER: admin
329+
IPA_ADMIN_PASSWORD: "{{ cifmw_adoption_osp_deploy_freeipa_admin_password }}"
330+
IPA_SERVER_HOSTNAME: "freeipa-0.{{ cloud_domain }}"
331+
UNDERCLOUD_FQDN: "osp-undercloud-0.{{ cloud_domain }}"
332+
USER: zuul
333+
CLOUD_DOMAIN: "{{ cloud_domain }}"
334+
335+
- name: Run undercloud ipa installer
336+
delegate_to: "osp-undercloud-0"
337+
become: true
338+
become_user: zuul
339+
vars:
340+
_undercloud_ipa_install_cmd: >-
341+
export IPA_DOMAIN="{{ cloud_domain }}"
342+
export IPA_REALM="{{ cloud_domain|upper }}"
343+
export IPA_ADMIN_USER=admin
344+
export IPA_ADMIN_PASSWORD="{{ cifmw_adoption_osp_deploy_freeipa_admin_password }}"
345+
export IPA_SERVER_HOSTNAME="freeipa-0.{{ cloud_domain }}"
346+
export UNDERCLOUD_FQDN="osp-undercloud-0.{{ cloud_domain }}"
347+
export USER=zuul
348+
export CLOUD_DOMAIN="{{ cloud_domain }}"
349+
ansible-playbook
350+
--ssh-extra-args "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
351+
/usr/share/ansible/tripleo-playbooks/undercloud-ipa-install.yaml
352+
cifmw.general.ci_script:
353+
output_dir: "{{ cifmw_basedir }}/artifacts"
354+
script: "{{ _undercloud_ipa_install_cmd }}"
355+
356+
- name: Edit undercloud.conf for ipa
357+
community.general.ini_file:
358+
path: ~/undercloud.conf
359+
backup: true
360+
mode: "0644"
361+
section: "{{ item.section }}"
362+
option: "{{ item.option }}"
363+
value: "{{ item.value }}"
364+
with_items:
365+
- { section: "DEFAULT", option: "undercloud_nameservers", value: "{{ freeipa_ip }} " }
366+
- { section: "DEFAULT", option: "overcloud_domain_name", value: "{{ cloud_domain }}" }

roles/libvirt_manager/tasks/generate_networking_data.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
{% set _amount = _cifmw_libvirt_manager_layout.vms[_type].amount |
5454
default(1) | int -%}
5555
{% set _range = range(0, _amount) -%}
56-
{% if _type is not match('^(controller|ocp|crc).*') -%}
56+
{% if _type is not match('^(controller|ocp|crc|osp-undercloud).*') -%}
5757
{% set _name = _type ~ _run_id -%}
5858
{% else -%}
5959
{% if _type == 'ocp' -%}

scenarios/adoption/hci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ libvirt_manager_patch_layout:
2626
# OSP ones
2727
compute:
2828
amount: 0
29+
free-ipa:
30+
<<: *osp_base_conf
31+
amount: 1
32+
memory: 4
33+
cpus: 2
34+
disksize: 40
35+
nets:
36+
- ocpbm
37+
- osp_trunk
2938
osp-undercloud:
3039
<<: *osp_base_conf
3140
amount: 1
@@ -100,3 +109,9 @@ networking_mapper_definition_patch:
100109
start: 100
101110
length: 1
102111
networks: *osp_nets
112+
free-ipas:
113+
network-template:
114+
range:
115+
start: 190
116+
length: 1
117+
networks: *osp_nets

0 commit comments

Comments
 (0)