Skip to content

Commit 0075e66

Browse files
committed
feat(integration): INT-07 GLPI SAML 2.0 docker test + CI
1 parent 62c431a commit 0075e66

4 files changed

Lines changed: 624 additions & 15 deletions

File tree

.github/workflows/ci.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,33 +229,39 @@ run: bash tests/labs/test-lab-17-01.sh
229229
run: docker compose -f docker/docker-compose.sso.yml down -v
230230

231231
lab-05-smoke:
232-
name: Lab 17-05 -- GLPI Advanced Integration (Zammad REST API)
232+
name: Lab 17-05 -- GLPI Advanced Integration (INT-07 GLPI<->Keycloak SAML 2.0 + LDAP)
233233
runs-on: ubuntu-latest
234234
needs: validate
235235
continue-on-error: true
236236
steps:
237237
- uses: actions/checkout@v4
238238

239239
- name: Install tools
240-
run: sudo apt-get install -y curl default-mysql-client netcat-openbsd ldap-utils
240+
run: sudo apt-get install -y curl default-mysql-client netcat-openbsd ldap-utils python3
241241

242242
- name: Validate integration compose
243243
run: docker compose -f docker/docker-compose.integration.yml config -q && echo "Integration compose valid"
244244

245245
- name: Start integration stack
246246
run: docker compose -f docker/docker-compose.integration.yml up -d
247247

248-
- name: Wait for WireMock
249-
run: timeout 90 bash -c 'until curl -sf http://localhost:8763/__admin/health; do sleep 5; done'
250-
251248
- name: Wait for MariaDB
252249
run: timeout 120 bash -c 'until docker exec glpi-i05-db mysqladmin ping -uroot -pRootLab05! --silent 2>/dev/null; do sleep 5; done'
253250

251+
- name: Wait for OpenLDAP
252+
run: timeout 120 bash -c 'until docker exec glpi-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'
253+
254+
- name: Wait for LDAP seed to complete
255+
run: timeout 120 bash -c 'until docker inspect glpi-i05-ldap-seed --format "{{.State.Status}}" 2>/dev/null | grep -q exited; do sleep 5; done'
256+
254257
- name: Wait for Keycloak
255-
run: timeout 300 bash -c 'until curl -sf http://localhost:8542/realms/master; do sleep 10; done'
258+
run: timeout 300 bash -c 'until curl -sf http://localhost:8542/health/ready | grep -q UP; do sleep 10; done'
259+
260+
- name: Wait for WireMock
261+
run: timeout 90 bash -c 'until curl -sf http://localhost:8763/__admin/health; do sleep 5; done'
256262

257263
- name: Wait for GLPI
258-
run: timeout 300 bash -c 'until curl -sf http://localhost:8442/ | grep -qi glpi; do sleep 15; done'
264+
run: timeout 300 bash -c 'until curl -sf http://localhost:8442/ > /dev/null 2>&1; do sleep 15; done'
259265

260266
- name: Run Lab 17-05 test script
261267
run: bash tests/labs/test-lab-17-05.sh --no-cleanup

docker/docker-compose.integration.yml

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
# IT-Stack: GLPI — Lab 05: Advanced Integration
33
# Module 17 · Phase 4 · Lab 05
44
# =============================================================================
5-
# Services: MariaDB · OpenLDAP · Keycloak · WireMock (Zammad-mock) · Mailhog · GLPI
5+
# Services: MariaDB · OpenLDAP · LDAP-Seed · Keycloak · WireMock (Zammad-mock) · Mailhog · GLPI
66
# Ports: App:8442 WireMock:8763 KC:8542 LDAP:3887 MH:8742
77
# Credentials:
88
# DB root: RootLab05! app: glpi / GlpiLab05!
99
# Keycloak: admin / Admin05!
10-
# LDAP: cn=admin,dc=lab,dc=local / LdapLab05!
10+
# LDAP: cn=admin,dc=lab,dc=local / LdapLab05! readonly: ReadOnly05!
11+
# LDAP users: glpiadmin/glpiuser1/glpiuser2 pw: Lab05Password!
1112
# What's new vs Lab 04:
12-
# + WireMock 3.x simulates Zammad REST API (ticket escalation)
13-
# + GLPI configured with ZAMMAD_URL for ticket escalation flow
14-
# + Integration tested: GLPI → Zammad REST API (ticket create/list)
13+
# + INT-07 Keycloak SAML 2.0 SSO for GLPI (SP-initiated SAML flow)
14+
# + LDAP seed init container (glpi-i05-ldap-seed) — FreeIPA-style tree
15+
# + KC depends on seed exit; SAML client "glpi" registered in realm
16+
# + GLPI container carries KC_SAML_* env vars for Ansible provisioner
1517
# =============================================================================
1618

1719
name: it-stack-glpi-lab05
@@ -75,6 +77,26 @@ services:
7577
memory: 256M
7678
cpus: "0.25"
7779

80+
# ── LDAP Seed (init container) ────────────────────────────────────────────
81+
glpi-i05-ldap-seed:
82+
image: osixia/openldap:1.5.0
83+
container_name: glpi-i05-ldap-seed
84+
entrypoint: ["/bin/sh", "-c"]
85+
command:
86+
- |
87+
sleep 5
88+
ldapadd -x -H ldap://glpi-i05-ldap:389 \
89+
-D cn=admin,dc=lab,dc=local -w LdapLab05! \
90+
-f /seed/glpi-ldap-seed.ldif && echo "LDAP seed complete" || echo "LDAP seed already exists (idempotent)"
91+
volumes:
92+
- ./glpi-ldap-seed.ldif:/seed/glpi-ldap-seed.ldif:ro
93+
depends_on:
94+
glpi-i05-ldap:
95+
condition: service_healthy
96+
networks:
97+
- glpi-i05-net
98+
restart: "no"
99+
78100
# ── Keycloak ───────────────────────────────────────────────────────────────
79101
glpi-i05-kc:
80102
image: quay.io/keycloak/keycloak:24.0.3
@@ -97,6 +119,9 @@ services:
97119
timeout: 10s
98120
retries: 20
99121
start_period: 30s
122+
depends_on:
123+
glpi-i05-ldap-seed:
124+
condition: service_completed_successfully
100125
networks:
101126
- glpi-i05-net
102127
deploy:
@@ -172,6 +197,9 @@ services:
172197
KEYCLOAK_URL: http://glpi-i05-kc:8080
173198
KEYCLOAK_REALM: it-stack
174199
KEYCLOAK_CLIENT_ID: glpi
200+
KC_SAML_IDP_METADATA_URL: http://glpi-i05-kc:8080/realms/it-stack/protocol/saml/descriptor
201+
KC_SAML_SP_ENTITY_ID: http://localhost:8442/glpi
202+
KC_SAML_ACS_URL: http://localhost:8442/glpi/index.php
175203
# Zammad integration (via WireMock)
176204
ZAMMAD_URL: http://glpi-i05-mock:8080
177205
ZAMMAD_TOKEN: lab-zammad-token-05

docker/glpi-ldap-seed.ldif

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# glpi-ldap-seed.ldif — INT-07 GLPI LDAP seed data
2+
# FreeIPA-style tree: cn=accounts, cn=users/groups inside it
3+
# Users: glpiadmin, glpiuser1, glpiuser2 (pw: Lab05Password!)
4+
# Groups: cn=admins (glpiadmin), cn=glpi-users (glpiuser1, glpiuser2)
5+
# Password hash: {SHA}qXfpnPbMmQGBSoY24+XFwHVzBpk= = "Lab05Password!"
6+
7+
dn: dc=lab,dc=local
8+
objectClass: top
9+
objectClass: dcObject
10+
objectClass: organization
11+
o: IT-Stack Lab
12+
dc: lab
13+
14+
dn: cn=accounts,dc=lab,dc=local
15+
objectClass: top
16+
objectClass: organizationalUnit
17+
ou: accounts
18+
19+
dn: cn=users,cn=accounts,dc=lab,dc=local
20+
objectClass: top
21+
objectClass: organizationalUnit
22+
ou: users
23+
24+
dn: cn=groups,cn=accounts,dc=lab,dc=local
25+
objectClass: top
26+
objectClass: organizationalUnit
27+
ou: groups
28+
29+
# ── Users ─────────────────────────────────────────────────────────────────────
30+
31+
dn: uid=glpiadmin,cn=users,cn=accounts,dc=lab,dc=local
32+
objectClass: top
33+
objectClass: inetOrgPerson
34+
objectClass: organizationalPerson
35+
objectClass: person
36+
uid: glpiadmin
37+
cn: GLPI Admin
38+
sn: Admin
39+
givenName: GLPI
40+
mail: glpiadmin@lab.local
41+
userPassword: Lab05Password!
42+
43+
dn: uid=glpiuser1,cn=users,cn=accounts,dc=lab,dc=local
44+
objectClass: top
45+
objectClass: inetOrgPerson
46+
objectClass: organizationalPerson
47+
objectClass: person
48+
uid: glpiuser1
49+
cn: GLPI User1
50+
sn: User1
51+
givenName: GLPI
52+
mail: glpiuser1@lab.local
53+
userPassword: Lab05Password!
54+
55+
dn: uid=glpiuser2,cn=users,cn=accounts,dc=lab,dc=local
56+
objectClass: top
57+
objectClass: inetOrgPerson
58+
objectClass: organizationalPerson
59+
objectClass: person
60+
uid: glpiuser2
61+
cn: GLPI User2
62+
sn: User2
63+
givenName: GLPI
64+
mail: glpiuser2@lab.local
65+
userPassword: Lab05Password!
66+
67+
# ── Groups ────────────────────────────────────────────────────────────────────
68+
69+
dn: cn=admins,cn=groups,cn=accounts,dc=lab,dc=local
70+
objectClass: top
71+
objectClass: groupOfNames
72+
cn: admins
73+
member: uid=glpiadmin,cn=users,cn=accounts,dc=lab,dc=local
74+
75+
dn: cn=glpi-users,cn=groups,cn=accounts,dc=lab,dc=local
76+
objectClass: top
77+
objectClass: groupOfNames
78+
cn: glpi-users
79+
member: uid=glpiuser1,cn=users,cn=accounts,dc=lab,dc=local
80+
member: uid=glpiuser2,cn=users,cn=accounts,dc=lab,dc=local

0 commit comments

Comments
 (0)