Skip to content

Commit 42b7ead

Browse files
committed
feat(integration): INT-04 SuiteCRM SAML docker test + CI
- docker/suitecrm-ldap-seed.ldif: FreeIPA-compatible LDAP seed (3 inetOrgPerson users crmadmin/crmuser1/2, 2 groupOfNames groups) - docker/docker-compose.integration.yml: add suitecrm-i05-ldap-seed init service; KC depends_on seed completed; LDAP BaseDN -> FreeIPA path; switch LDAP bind to readonly account - tests/labs/test-lab-12-05.sh: Phase 3a (KC SAML client + LDAP federation + sync + IdP descriptor), Phase 3b (seed verify), 3c-3g (Wiremock/env), Phase 3h (SAML env vars + KC SAML reachable); removed dead code stub - .github/workflows/ci.yml: lab-05-smoke renamed INT-04, python3 added, wait order: MariaDB->OpenLDAP->seed->Keycloak->WireMock->MH->SuiteCRM
1 parent 028c31f commit 42b7ead

4 files changed

Lines changed: 330 additions & 82 deletions

File tree

.github/workflows/ci.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,24 +188,28 @@ jobs:
188188
run: docker compose -f docker/docker-compose.sso.yml down -v
189189

190190
lab-05-smoke:
191-
name: Lab 05 -- SuiteCRM Advanced Integration (WireMock Odoo-JSONRPC + Nextcloud-CalDAV)
191+
name: Lab 05 — INT-04 SuiteCRM↔Keycloak SAML (LDAP seed + federation + SAML client)
192192
runs-on: ubuntu-latest
193193
needs: validate
194194
continue-on-error: true
195195
steps:
196196
- uses: actions/checkout@v4
197197
- name: Install tools
198-
run: sudo apt-get install -y curl default-mysql-client netcat-openbsd ldap-utils
198+
run: sudo apt-get install -y curl default-mysql-client netcat-openbsd ldap-utils python3
199199
- name: Validate integration compose
200200
run: docker compose -f docker/docker-compose.integration.yml config -q && echo "Integration compose valid"
201201
- name: Start integration stack
202202
run: docker compose -f docker/docker-compose.integration.yml up -d
203203
- name: Wait for MariaDB
204204
run: timeout 120 bash -c 'until docker exec suitecrm-i05-db mysqladmin ping -uroot -pRootLab05! --silent; do sleep 5; done'
205-
- name: Wait for WireMock
206-
run: timeout 60 bash -c 'until curl -sf http://localhost:8363/__admin/health; do sleep 5; done'
205+
- name: Wait for OpenLDAP
206+
run: timeout 120 bash -c 'until docker exec suitecrm-i05-ldap ldapsearch -x -H ldap://localhost -b dc=lab,dc=local -D cn=admin,dc=lab,dc=local -w LdapLab05! >/dev/null 2>&1; do sleep 5; done'
207+
- name: Wait for LDAP seed to complete
208+
run: timeout 60 bash -c 'until [ "$(docker inspect --format={{.State.Status}} suitecrm-i05-ldap-seed 2>/dev/null)" = "exited" ]; do sleep 3; done'
207209
- name: Wait for Keycloak
208210
run: timeout 300 bash -c 'until curl -sf http://localhost:8461/realms/master; do sleep 10; done'
211+
- name: Wait for WireMock
212+
run: timeout 60 bash -c 'until curl -sf http://localhost:8363/__admin/health; do sleep 5; done'
209213
- name: Wait for Mailhog
210214
run: timeout 60 bash -c 'until curl -sf http://localhost:8661/api/v2/messages; do sleep 5; done'
211215
- name: Wait for SuiteCRM web

docker/docker-compose.integration.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,25 @@ services:
9999
memory: 256M
100100
cpus: "0.25"
101101

102+
# ── LDAP Seed (FreeIPA-compatible) ──────────────────────────────────────────
103+
suitecrm-i05-ldap-seed:
104+
image: osixia/openldap:1.5.0
105+
container_name: suitecrm-i05-ldap-seed
106+
command: >
107+
bash -c "sleep 5 &&
108+
ldapadd -x -H ldap://suitecrm-i05-ldap:389
109+
-D cn=admin,dc=lab,dc=local -w LdapLab05!
110+
-f /seed/suitecrm-ldap-seed.ldif &&
111+
echo 'Seed complete'"
112+
volumes:
113+
- ../docker/suitecrm-ldap-seed.ldif:/seed/suitecrm-ldap-seed.ldif:ro
114+
networks:
115+
- suitecrm-i05-net
116+
depends_on:
117+
suitecrm-i05-ldap:
118+
condition: service_healthy
119+
restart: "no"
120+
102121
# ── Keycloak ─────────────────────────────────────────────────────────────
103122
suitecrm-i05-kc:
104123
image: quay.io/keycloak/keycloak:24.0.3
@@ -121,6 +140,9 @@ services:
121140
timeout: 10s
122141
retries: 20
123142
start_period: 30s
143+
depends_on:
144+
suitecrm-i05-ldap-seed:
145+
condition: service_completed_successfully
124146
networks:
125147
- suitecrm-i05-net
126148
deploy:
@@ -202,9 +224,9 @@ services:
202224
# LDAP
203225
SUITECRM_LDAP_SERVER: suitecrm-i05-ldap
204226
SUITECRM_LDAP_PORT: "389"
205-
SUITECRM_LDAP_BASE_DN: dc=lab,dc=local
206-
SUITECRM_LDAP_ADMIN_DN: cn=admin,dc=lab,dc=local
207-
SUITECRM_LDAP_ADMIN_PASSWORD: LdapLab05!
227+
SUITECRM_LDAP_BASE_DN: cn=users,cn=accounts,dc=lab,dc=local
228+
SUITECRM_LDAP_ADMIN_DN: cn=readonly,dc=lab,dc=local
229+
SUITECRM_LDAP_ADMIN_PASSWORD: ReadOnly05!
208230
# Keycloak SAML
209231
KEYCLOAK_URL: http://suitecrm-i05-kc:8080
210232
KEYCLOAK_REALM: it-stack

docker/suitecrm-ldap-seed.ldif

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# suitecrm-ldap-seed.ldif
2+
# Seeds FreeIPA-compatible LDAP structure into the OpenLDAP integration test
3+
# container for SuiteCRM Lab 05 (INT-04: SuiteCRM ↔ Keycloak SAML).
4+
#
5+
# Used by: docker/docker-compose.integration.yml → suitecrm-i05-ldap-seed
6+
# SuiteCRM LDAP: basedn dc=lab,dc=local, uid attribute, mail attribute
7+
# Keycloak federation: cn=users,cn=accounts,dc=lab,dc=local (rhds vendor)
8+
9+
# ── FreeIPA-compatible accounts container ─────────────────────────────────────
10+
dn: cn=accounts,dc=lab,dc=local
11+
objectClass: organizationalRole
12+
objectClass: top
13+
cn: accounts
14+
description: FreeIPA-compatible accounts container
15+
16+
dn: cn=users,cn=accounts,dc=lab,dc=local
17+
objectClass: organizationalRole
18+
objectClass: top
19+
cn: users
20+
description: IPA user accounts
21+
22+
dn: cn=groups,cn=accounts,dc=lab,dc=local
23+
objectClass: organizationalRole
24+
objectClass: top
25+
cn: groups
26+
description: IPA user groups
27+
28+
# ── Test users ────────────────────────────────────────────────────────────────
29+
dn: uid=crmadmin,cn=users,cn=accounts,dc=lab,dc=local
30+
objectClass: inetOrgPerson
31+
objectClass: organizationalPerson
32+
objectClass: person
33+
objectClass: top
34+
uid: crmadmin
35+
cn: CRM Admin
36+
sn: Admin
37+
givenName: CRM
38+
displayName: CRM Administrator
39+
mail: crmadmin@lab.local
40+
telephoneNumber: +1-555-120-0001
41+
title: CRM Administrator
42+
userPassword: Lab05Password!
43+
44+
dn: uid=crmuser1,cn=users,cn=accounts,dc=lab,dc=local
45+
objectClass: inetOrgPerson
46+
objectClass: organizationalPerson
47+
objectClass: person
48+
objectClass: top
49+
uid: crmuser1
50+
cn: CRM User One
51+
sn: One
52+
givenName: CRM
53+
displayName: CRM User One
54+
mail: crmuser1@lab.local
55+
telephoneNumber: +1-555-120-0002
56+
title: Sales Representative
57+
userPassword: Lab05Password!
58+
59+
dn: uid=crmuser2,cn=users,cn=accounts,dc=lab,dc=local
60+
objectClass: inetOrgPerson
61+
objectClass: organizationalPerson
62+
objectClass: person
63+
objectClass: top
64+
uid: crmuser2
65+
cn: CRM User Two
66+
sn: Two
67+
givenName: CRM
68+
displayName: CRM User Two
69+
mail: crmuser2@lab.local
70+
telephoneNumber: +1-555-120-0003
71+
title: Account Manager
72+
userPassword: Lab05Password!
73+
74+
# ── Groups ────────────────────────────────────────────────────────────────────
75+
dn: cn=admins,cn=groups,cn=accounts,dc=lab,dc=local
76+
objectClass: groupOfNames
77+
objectClass: top
78+
cn: admins
79+
description: CRM administrators
80+
member: uid=crmadmin,cn=users,cn=accounts,dc=lab,dc=local
81+
82+
dn: cn=crm-users,cn=groups,cn=accounts,dc=lab,dc=local
83+
objectClass: groupOfNames
84+
objectClass: top
85+
cn: crm-users
86+
description: CRM regular users
87+
member: uid=crmuser1,cn=users,cn=accounts,dc=lab,dc=local
88+
member: uid=crmuser2,cn=users,cn=accounts,dc=lab,dc=local

0 commit comments

Comments
 (0)