Skip to content

Commit 1665f62

Browse files
afaranhaxekcursoragent
committed
[multiple] Add OIDC federation configuration on OSP17
Add Ansible playbooks and role tasks to configure OSP 17.1 for OIDC federation, enabling adoption testing with Keycloak as the identity provider. Changes: - Add federation-osp17-pre-deploy hook playbook that renders the Heat environment file and configures Keystone for OIDC - Add run_osp17_oidc_setup.yml tasks to create the federation domain, identity provider, mapping, group, project and protocol on OSP 17.1 - Add enable-federation-openidc.yaml.j2 Heat template for OIDC params - Refactor Keycloak operator deployment to use kubernetes.core.k8s instead of oc apply with a template file - Make operator namespace configurable via cifmw_federation_operator_namespace variable - Add passthrough Route for Keycloak and grant privileged SCC - Conditionally include the OIDC env file in overcloud deploy Jira: https://issues.redhat.com/browse/OSPRH-19960 Signed-off-by: Andre Aranha <afariasa@redhat.com> Co-authored-by: Grzegorz Grasza <xek@redhat.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 3bcd0bf commit 1665f62

8 files changed

Lines changed: 201 additions & 20 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
- name: Configure OSP 17.1 for OIDC federation (render env + Keystone setup)
3+
hosts: "{{ cifmw_target_host | default('localhost') }}"
4+
gather_facts: true
5+
vars:
6+
_cloud_name: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
7+
tasks:
8+
- name: Set urls for install type uni
9+
ansible.builtin.set_fact:
10+
cifmw_federation_keycloak_url: 'https://keycloak-openstack.apps.ocp.openstack.lab'
11+
when: cifmw_federation_deploy_type == "uni"
12+
13+
- name: Set urls for install type crc
14+
ansible.builtin.set_fact:
15+
cifmw_federation_keycloak_url: 'https://keycloak-openstack.apps-crc.testing'
16+
when: cifmw_federation_deploy_type == "crc"
17+
18+
- name: OSP 17.1 OIDC setup via federation role
19+
ansible.builtin.import_role:
20+
name: federation
21+
tasks_from: run_osp17_oidc_setup.yml

roles/adoption_osp_deploy/tasks/deploy_overcloud.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@
7474
dest: "{{ _private_overcloud_conf_file }}"
7575
mode: "0644"
7676

77+
- name: Check if OIDC federation env file exists
78+
delegate_to: "osp-undercloud-0"
79+
ansible.builtin.stat:
80+
path: "{{ ansible_user_dir }}/enable-federation-openidc.yaml"
81+
register: _oidc_env_stat
82+
7783
- name: Run overcloud deploy
7884
delegate_to: "osp-undercloud-0"
7985
vars:
@@ -84,6 +90,7 @@
8490
--roles-file {{ _roles_file_dest }}
8591
-n {{ _network_data_file_dest }}
8692
--ntp-server {{ cifmw_adoption_osp_deploy_ntp_server }}
93+
{{ _oidc_env_stat.stat.exists | ternary('-e ' ~ ansible_user_dir ~ '/enable-federation-openidc.yaml', '') }}
8794
-e {{ _overcloud_vars }}
8895
-e {{ ansible_user_dir }}/containers-prepare-parameters.yaml
8996
-e {{ ansible_user_dir }}/config_download_{{ _overcloud_name }}.yaml

roles/federation/defaults/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# Basic namespace and domain settings for the federation deployment
1313

1414
# Kubernetes namespaces
15+
cifmw_federation_operator_namespace: openstack-operators
1516
cifmw_federation_keycloak_namespace: openstack
1617
cifmw_federation_run_osp_cmd_namespace: openstack
1718

roles/federation/tasks/run_keycloak_setup.yml

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
kubernetes.core.k8s_info:
5353
api_version: operators.coreos.com/v1alpha1
5454
kind: InstallPlan
55+
namespace: "{{ cifmw_federation_operator_namespace }}"
56+
label_selectors:
57+
- "operators.coreos.com/rhsso-operator.{{ cifmw_federation_operator_namespace }}"
5558
register: ip_list
5659
until: >-
5760
ip_list.resources |
@@ -70,8 +73,9 @@
7073
PATH: "{{ cifmw_path }}"
7174
ansible.builtin.shell: >-
7275
oc patch installplan
73-
$(oc get ip
74-
-o=jsonpath='{.items[].metadata.name}')
76+
$(oc get installplan -n {{ cifmw_federation_operator_namespace }}
77+
-o=jsonpath='{.items[0].metadata.name}')
78+
-n {{ cifmw_federation_operator_namespace }}
7579
--type merge --patch '{"spec":{"approved":true}}'
7680
7781
- name: Add sso admin user secret
@@ -89,18 +93,72 @@
8993
ADMIN_USERNAME: "{{ cifmw_federation_keycloak_admin_username | b64encode }}"
9094
ADMIN_PASSWORD: "{{ cifmw_federation_keycloak_admin_password | b64encode }}"
9195

92-
- name: Read federation sso template
93-
ansible.builtin.template:
94-
src: sso.yaml.j2
95-
dest: "{{ [ ansible_user_dir, 'ci-framework-data', 'tmp', 'sso.yaml' ] | path_join }}"
96-
mode: "0644"
96+
- name: Install federation Keycloak instance
97+
kubernetes.core.k8s:
98+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
99+
state: present
100+
definition:
101+
apiVersion: keycloak.org/v1alpha1
102+
kind: Keycloak
103+
metadata:
104+
name: sso
105+
namespace: "{{ cifmw_federation_keycloak_namespace }}"
106+
labels:
107+
app: sso
108+
spec:
109+
instances: 1
110+
externalAccess:
111+
enabled: true
112+
113+
- name: Wait for Keycloak service to be created
114+
kubernetes.core.k8s_info:
115+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
116+
api_version: v1
117+
kind: Service
118+
name: keycloak
119+
namespace: "{{ cifmw_federation_keycloak_namespace }}"
120+
register: keycloak_service
121+
until: keycloak_service.resources | length > 0
122+
retries: 30
123+
delay: 10
97124

98-
- name: Install federation sso pod
125+
- name: Create Route for Keycloak
126+
kubernetes.core.k8s:
127+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
128+
state: present
129+
definition:
130+
apiVersion: route.openshift.io/v1
131+
kind: Route
132+
metadata:
133+
name: keycloak
134+
namespace: "{{ cifmw_federation_keycloak_namespace }}"
135+
spec:
136+
host: "keycloak-{{ cifmw_federation_keycloak_namespace }}.{{ cifmw_federation_domain }}"
137+
to:
138+
kind: Service
139+
name: keycloak
140+
port:
141+
targetPort: 8443
142+
tls:
143+
termination: passthrough
144+
register: _keycloak_route
145+
until: _keycloak_route is succeeded
146+
retries: 30
147+
delay: 10
148+
149+
- name: Grant privileged SCC to namespace default serviceaccount for Keycloak
99150
environment:
100151
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
101152
PATH: "{{ cifmw_path }}"
102153
ansible.builtin.command:
103-
cmd: "oc apply -n {{ cifmw_federation_keycloak_namespace }} -f {{ [ ansible_user_dir, 'ci-framework-data', 'tmp', 'sso.yaml' ] | path_join }}"
154+
cmd: >-
155+
oc adm policy add-scc-to-user privileged
156+
-n {{ cifmw_federation_keycloak_namespace }}
157+
-z default
158+
register: _scc_assignment
159+
changed_when: >-
160+
'clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added:'
161+
in _scc_assignment.stdout
104162
105163
- name: Add CRC IP address to hosts
106164
become: true
@@ -109,7 +167,7 @@
109167
block: |
110168
{{ hostvars['crc'].ansible_host }} api.crc.testing
111169
{{ hostvars['crc'].ansible_host }} oauth-openshift.apps-crc.testing
112-
{{ hostvars['crc'].ansible_host }} keycloak-openstack.apps-crc.testing
170+
{{ hostvars['crc'].ansible_host }} keycloak-{{ cifmw_federation_keycloak_namespace }}.{{ cifmw_federation_domain }}
113171
when: cifmw_federation_deploy_type == "crc"
114172

115173
- name: Wait for SSO pod to be avalable
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
- name: Render enable-federation-openidc.yaml to undercloud
3+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
4+
ansible.builtin.template:
5+
src: "enable-federation-openidc.yaml.j2"
6+
dest: "{{ ansible_user_dir }}/enable-federation-openidc.yaml"
7+
mode: "0644"
8+
9+
- name: Create federation mapping file on undercloud
10+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
11+
ansible.builtin.copy:
12+
dest: "{{ ansible_user_dir }}/mapping.json"
13+
mode: "0644"
14+
content: |
15+
[
16+
{
17+
"local": [
18+
{
19+
"user": {"name": "{0}"},
20+
"group": {
21+
"domain": {"name": "{{ cifmw_federation_keystone_domain }}"},
22+
"name": "{{ cifmw_federation_group_name }}"
23+
}
24+
}
25+
],
26+
"remote": [
27+
{"type": "OIDC-preferred_username"}
28+
]
29+
}
30+
]
31+
32+
- name: Ensure federation domain exists (OSP 17.1)
33+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
34+
environment:
35+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
36+
ansible.builtin.shell: |
37+
set -e
38+
openstack domain show {{ cifmw_federation_keystone_domain }} >/dev/null 2>&1 || \
39+
openstack domain create {{ cifmw_federation_keystone_domain }}
40+
41+
- name: Ensure identity provider exists (OSP 17.1)
42+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
43+
environment:
44+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
45+
ansible.builtin.shell: |
46+
set -e
47+
IDP_URL="{{ cifmw_federation_keycloak_url }}/auth/realms/{{ cifmw_federation_keycloak_realm }}"
48+
openstack identity provider show {{ cifmw_federation_IdpName }} >/dev/null 2>&1 || \
49+
openstack identity provider create --remote-id ${IDP_URL} --domain {{ cifmw_federation_keystone_domain }} {{ cifmw_federation_IdpName }}
50+
51+
- name: Ensure mapping exists (OSP 17.1)
52+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
53+
environment:
54+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
55+
ansible.builtin.shell: |
56+
set -e
57+
openstack mapping show {{ cifmw_federation_mapping_name }} >/dev/null 2>&1 || \
58+
openstack mapping create --rules {{ ansible_user_dir }}/mapping.json {{ cifmw_federation_mapping_name }}
59+
60+
- name: Ensure federated group exists (OSP 17.1)
61+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
62+
environment:
63+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
64+
ansible.builtin.shell: |
65+
set -e
66+
openstack group show {{ cifmw_federation_group_name }} --domain {{ cifmw_federation_keystone_domain }} >/dev/null 2>&1 || \
67+
openstack group create --domain {{ cifmw_federation_keystone_domain }} {{ cifmw_federation_group_name }}
68+
69+
- name: Ensure project exists (OSP 17.1)
70+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
71+
environment:
72+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
73+
ansible.builtin.shell: |
74+
set -e
75+
openstack project show {{ cifmw_federation_project_name }} --domain {{ cifmw_federation_keystone_domain }} >/dev/null 2>&1 || \
76+
openstack project create --domain {{ cifmw_federation_keystone_domain }} {{ cifmw_federation_project_name }}
77+
78+
- name: Ensure role binding exists (OSP 17.1)
79+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
80+
environment:
81+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
82+
ansible.builtin.shell: |
83+
set -e
84+
openstack role add --group {{ cifmw_federation_group_name }} --group-domain {{ cifmw_federation_keystone_domain }} --project {{ cifmw_federation_project_name }} --project-domain {{ cifmw_federation_keystone_domain }} member || true
85+
86+
- name: Ensure federation protocol exists (OSP 17.1)
87+
delegate_to: "{{ cifmw_federation_undercloud_host | default('osp-undercloud-0') }}"
88+
environment:
89+
OS_CLOUD: "{{ cifmw_adoption_osp_deploy_scenario.stacks[0].stackname | default('overcloud') }}"
90+
ansible.builtin.shell: |
91+
set -e
92+
openstack federation protocol show openid --identity-provider {{ cifmw_federation_IdpName }} >/dev/null 2>&1 || \
93+
openstack federation protocol create openid --mapping {{ cifmw_federation_mapping_name }} --identity-provider {{ cifmw_federation_IdpName }}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
parameter_defaults:
2+
KeystoneAuthMethods: password,token,oauth1,mapped,application_credential,openid
3+
KeystoneOpenIdcClientId: {{ cifmw_keystone_OIDC_ClientID | quote }}
4+
KeystoneOpenIdcClientSecret: {{ cifmw_keystone_OIDC_ClientSecret | quote }}
5+
KeystoneOpenIdcCryptoPassphrase: {{ cifmw_keystone_OIDC_CryptoPassphrase | default('openstack') | quote }}
6+
KeystoneOpenIdcIdpName: {{ cifmw_keystone_OIDC_provider_name | default('kcIDP') | quote }}
7+
KeystoneOpenIdcIntrospectionEndpoint: {{ cifmw_keystone_OIDC_OAuthIntrospectionEndpoint | quote }}
8+
KeystoneOpenIdcProviderMetadataUrl: {{ cifmw_keystone_OIDC_ProviderMetadataURL | quote }}
9+
KeystoneOpenIdcRemoteIdAttribute: HTTP_OIDC_ISS

roles/federation/templates/rhsso-operator-olm.yaml.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ apiVersion: operators.coreos.com/v1
22
kind: OperatorGroup
33
metadata:
44
name: rhsso-operator-group
5+
namespace: {{ cifmw_federation_operator_namespace }}
56
spec:
67
targetNamespaces:
78
- {{ cifmw_federation_keycloak_namespace }}
@@ -10,6 +11,7 @@ apiVersion: operators.coreos.com/v1alpha1
1011
kind: Subscription
1112
metadata:
1213
name: rhsso-operator
14+
namespace: {{ cifmw_federation_operator_namespace }}
1315
spec:
1416
channel: stable
1517
installPlanApproval: Manual

roles/federation/templates/sso.yaml.j2

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)