diff --git a/docs/changelog.md b/docs/changelog.md index 9d20b34..3889ba5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. -## [2.2.6] - Current +## [2.2.7] - Current + +### Changed + +- Switch the OpenLDAP e2e helper from Bitnami legacy to `quay.io/rhdh-test/security/openldap-ubi10.2:latest` (UBI 10.2 / OpenSSL 3.5.5+), raise memory requests/limits, set `imagePullPolicy: Always`, and add image build sources under `src/deployment/openldap/image`. + +## [2.2.6] ### Fixed diff --git a/package.json b/package.json index 4826ff7..c4b54c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@red-hat-developer-hub/e2e-test-utils", - "version": "2.2.6", + "version": "2.2.7", "description": "Test utilities for RHDH E2E tests", "license": "Apache-2.0", "repository": { diff --git a/src/deployment/openldap/constants.ts b/src/deployment/openldap/constants.ts index 88387c4..0a0c4cf 100644 --- a/src/deployment/openldap/constants.ts +++ b/src/deployment/openldap/constants.ts @@ -15,9 +15,8 @@ export const DEFAULT_OPENLDAP_CONFIG = { usersOu: "users", groupsOu: "groups", port: 1389, - // Bitnami public Helm chart for OpenLDAP was removed; use the Bitnami legacy image. - imageRepository: "bitnamilegacy/openldap", - imageTag: "2.6.10-debian-12-r4", + imageRepository: "quay.io/rhdh-test/security/openldap-ubi10.2", + imageTag: "latest", }; export const DEFAULT_CONFIG_PATHS = { diff --git a/src/deployment/openldap/deployment.ts b/src/deployment/openldap/deployment.ts index 95aae5f..a4dba73 100644 --- a/src/deployment/openldap/deployment.ts +++ b/src/deployment/openldap/deployment.ts @@ -15,7 +15,7 @@ import type { } from "./types.js"; /** - * Orchestrator-style OpenLDAP helper (Bitnami legacy image). + * Orchestrator-style OpenLDAP helper (quay.io/rhdh-test/security/openldap-ubi10.2). * Call from test.runOnce — not globalSetup. Deploys into the Playwright project namespace. */ export class OpenLDAPHelper { @@ -192,11 +192,10 @@ spec: containers: - name: openldap image: ${cfg.imageRepository}:${cfg.imageTag} - imagePullPolicy: IfNotPresent + imagePullPolicy: Always ports: - name: ldap containerPort: ${cfg.port} - # Bitnami slapd/slappasswd carry setcap CAP_NET_BIND_SERVICE; OpenShift # restricted-v2 drops ALL capabilities unless NET_BIND_SERVICE is added # explicitly (otherwise: "slappasswd: Operation not permitted"). securityContext: @@ -237,10 +236,10 @@ spec: resources: requests: cpu: 50m - memory: 128Mi + memory: 256Mi limits: cpu: 500m - memory: 512Mi + memory: 1Gi volumes: - name: seed configMap: diff --git a/src/deployment/openldap/image/Containerfile b/src/deployment/openldap/image/Containerfile new file mode 100644 index 0000000..6ccf79a --- /dev/null +++ b/src/deployment/openldap/image/Containerfile @@ -0,0 +1,79 @@ +# OpenLDAP peer for LDAP PQC e2e — UBI 10.2 ships OpenSSL 3.5.x (ML-KEM capable). +# UBI does not package openldap-servers; build slapd from source with --with-tls=openssl +# so LDAPS uses libssl (not NSS). +# +# Verify after build: +# openssl version # expect 3.5.x +# ldd /opt/openldap/libexec/slapd | grep ssl + +FROM registry.access.redhat.com/ubi10/ubi:10.2 AS build + +ARG OPENLDAP_VERSION=2.6.10 + +RUN dnf -y install \ + gcc make curl-minimal tar gzip diffutils groff-base \ + openssl openssl-devel \ + cyrus-sasl-devel \ + && dnf clean all + +# Build libraries/clients/slapd only — skip doc/ (soelim/man) for a leaner image. +RUN curl -fsSL \ + "https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-${OPENLDAP_VERSION}.tgz" \ + -o /tmp/openldap.tgz \ + && tar -xzf /tmp/openldap.tgz -C /tmp \ + && cd "/tmp/openldap-${OPENLDAP_VERSION}" \ + && ./configure \ + --prefix=/opt/openldap \ + --enable-slapd \ + --enable-mdb=yes \ + --with-tls=openssl \ + --without-systemd \ + --disable-static \ + && make -j"$(nproc)" depend \ + && make -j"$(nproc)" -C include \ + && make -j"$(nproc)" -C libraries \ + && make -j"$(nproc)" -C clients \ + && make -j"$(nproc)" -C servers \ + && make -C include install \ + && make -C libraries install \ + && make -C clients install \ + && make -C servers install \ + && make -C include install \ + && cp -a servers/slapd/schema /opt/openldap/etc/openldap/schema \ + && rm -rf /tmp/openldap* + +FROM registry.access.redhat.com/ubi10/ubi:10.2 + +LABEL name="rhdh-e2e-openldap-pq" \ + summary="OpenLDAP (OpenSSL TLS) on UBI 10.2 for RHDH LDAP PQC e2e" \ + description="slapd built with --with-tls=openssl against OpenSSL 3.5.x" + +RUN dnf -y install openssl openssl-libs cyrus-sasl-lib shadow-utils \ + && dnf clean all \ + && openssl version \ + && useradd --uid 1001 --gid 0 --home-dir /opt/openldap --no-create-home --shell /sbin/nologin ldap + +COPY --from=build /opt/openldap /opt/openldap + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +COPY slapd.conf.template /opt/openldap/etc/openldap/slapd.conf.template +COPY seed.ldif /ldifs/seed.ldif + +RUN chmod +x /usr/local/bin/entrypoint.sh \ + && mkdir -p /var/lib/ldap /certs /opt/openldap/var/run \ + && chown -R 1001:0 /opt/openldap /var/lib/ldap /ldifs /certs \ + && chmod -R g=u /opt/openldap /var/lib/ldap /ldifs /certs \ + && ldd /opt/openldap/libexec/slapd | tee /tmp/slapd-ldd.txt \ + && grep -E 'libssl|libcrypto' /tmp/slapd-ldd.txt + +ENV PATH="/opt/openldap/libexec:/opt/openldap/sbin:/opt/openldap/bin:${PATH}" \ + LDAP_ROOT="dc=rhdh,dc=test" \ + LDAP_ADMIN_USERNAME="admin" \ + LDAP_ADMIN_PASSWORD="user1pass" \ + LDAP_PORT_NUMBER="1389" \ + LDAP_LDAPS_PORT_NUMBER="1636" \ + LDAP_ENABLE_TLS="no" + +USER 1001 +EXPOSE 1389 1636 +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/src/deployment/openldap/image/README.md b/src/deployment/openldap/image/README.md new file mode 100644 index 0000000..1eafeb8 --- /dev/null +++ b/src/deployment/openldap/image/README.md @@ -0,0 +1,67 @@ +# OpenLDAP UBI 10.2 image + +Container sources for the OpenLDAP peer used by RHDH LDAP / PQC e2e. + +**Published image:** `quay.io/rhdh-test/security/openldap-ubi10.2:latest` + +## Why this image exists + +We need OpenLDAP on a base image that ships **OpenSSL 3.5.5+** (UBI 10.2). UBI does not package `openldap-servers`, and typical distro builds link TLS to NSS — so slapd is built **from source** with `--with-tls=openssl` against that OpenSSL. + +## Files + +| File | Role | +| --------------------- | ------------------------------------------------------ | +| `Containerfile` | Multi-stage build: compile slapd, then runtime image | +| `entrypoint.sh` | Renders config, loads seed on first boot, starts slapd | +| `slapd.conf.template` | slapd config template (`__LDAP_*__` placeholders) | +| `seed.ldif` | Default tree: `dc=rhdh,dc=test`, users, groups | + +## Build and push + +Run from this directory: + +```bash +podman build -t quay.io/rhdh-test/security/openldap-ubi10.2:latest -f Containerfile . +podman push quay.io/rhdh-test/security/openldap-ubi10.2:latest +``` + +Optional: pin OpenLDAP version with `--build-arg OPENLDAP_VERSION=2.6.10`. + +### Sanity checks after build + +```bash +podman run --rm quay.io/rhdh-test/security/openldap-ubi10.2:latest openssl version +# expect OpenSSL 3.5.x + +podman run --rm --entrypoint ldd quay.io/rhdh-test/security/openldap-ubi10.2:latest \ + /opt/openldap/libexec/slapd | grep -E 'libssl|libcrypto' +``` + +## Defaults + +| Setting | Value | +| ---------- | ---------------------------------------- | +| Base DN | `dc=rhdh,dc=test` | +| Admin | `cn=admin,dc=rhdh,dc=test` / `user1pass` | +| LDAP port | `1389` | +| LDAPS port | `1636` (only if TLS enabled) | +| TLS | off (`LDAP_ENABLE_TLS=no`) | +| User | UID `1001` (OpenShift-friendly) | + +Seed users: `user1`, `user2`, `user3`, `rhdh-admin` (password `user1pass`). + +## Environment variables + +| Variable | Default | Purpose | +| ------------------------ | ------------------ | ------------------------------- | +| `LDAP_ROOT` | `dc=rhdh,dc=test` | Directory suffix | +| `LDAP_ADMIN_USERNAME` | `admin` | Root DN `cn=,` | +| `LDAP_ADMIN_PASSWORD` | `user1pass` | Root password | +| `LDAP_PORT_NUMBER` | `1389` | Plain LDAP listen port | +| `LDAP_LDAPS_PORT_NUMBER` | `1636` | LDAPS listen port | +| `LDAP_ENABLE_TLS` | `no` | `yes` / `true` to enable LDAPS | +| `LDAP_SEED_FILE` | `/ldifs/seed.ldif` | LDIF loaded once into empty MDB | +| `LDAP_TLS_CERT_FILE` | `/certs/tls.crt` | Server cert (TLS on) | +| `LDAP_TLS_KEY_FILE` | `/certs/tls.key` | Server key (TLS on) | +| `LDAP_TLS_CA_FILE` | `/certs/ca.crt` | CA file (TLS on) | diff --git a/src/deployment/openldap/image/entrypoint.sh b/src/deployment/openldap/image/entrypoint.sh new file mode 100755 index 0000000..0be1ff2 --- /dev/null +++ b/src/deployment/openldap/image/entrypoint.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# Minimal slapd entrypoint for RHDH LDAP PQC e2e (UBI 10.2 / OpenSSL TLS). +set -euo pipefail + +export PATH="/opt/openldap/libexec:/opt/openldap/sbin:/opt/openldap/bin:${PATH}" +SLAPD=/opt/openldap/libexec/slapd + +: "${LDAP_ROOT:=dc=rhdh,dc=test}" +: "${LDAP_ADMIN_USERNAME:=admin}" +: "${LDAP_ADMIN_PASSWORD:=user1pass}" +: "${LDAP_PORT_NUMBER:=1389}" +: "${LDAP_LDAPS_PORT_NUMBER:=1636}" +: "${LDAP_ENABLE_TLS:=no}" +: "${LDAP_SEED_FILE:=/ldifs/seed.ldif}" +: "${LDAP_TLS_CERT_FILE:=/certs/tls.crt}" +: "${LDAP_TLS_KEY_FILE:=/certs/tls.key}" +: "${LDAP_TLS_CA_FILE:=/certs/ca.crt}" + +CONF_DIR=/opt/openldap/etc/openldap +CONF_FILE="${CONF_DIR}/slapd.conf" +DATA_DIR=/var/lib/ldap +RUN_DIR=/opt/openldap/var/run + +mkdir -p "${DATA_DIR}" "${RUN_DIR}" + +sed \ + -e "s|__LDAP_ROOT__|${LDAP_ROOT}|g" \ + -e "s|__LDAP_ADMIN_USERNAME__|${LDAP_ADMIN_USERNAME}|g" \ + -e "s|__LDAP_ADMIN_PASSWORD__|${LDAP_ADMIN_PASSWORD}|g" \ + "${CONF_DIR}/slapd.conf.template" >"${CONF_FILE}" + +if [[ "${LDAP_ENABLE_TLS}" == "yes" || "${LDAP_ENABLE_TLS}" == "true" ]]; then + for f in "${LDAP_TLS_CERT_FILE}" "${LDAP_TLS_KEY_FILE}" "${LDAP_TLS_CA_FILE}"; do + if [[ ! -f "${f}" ]]; then + echo "[openldap-pq] TLS enabled but missing ${f}" >&2 + exit 1 + fi + done + cat >>"${CONF_FILE}" <&2 + exit 1 + fi + slapadd -f "${CONF_FILE}" -l "${LDAP_SEED_FILE}" +fi + +LISTEN="ldap://:${LDAP_PORT_NUMBER}" +if [[ "${LDAP_ENABLE_TLS}" == "yes" || "${LDAP_ENABLE_TLS}" == "true" ]]; then + LISTEN="${LISTEN} ldaps://:${LDAP_LDAPS_PORT_NUMBER}" +fi + +echo "[openldap-pq] openssl=$(openssl version)" +echo "[openldap-pq] starting slapd on ${LISTEN} (OPENSSL_CONF=${OPENSSL_CONF:-unset})" +# -d keeps slapd in the foreground (required for containers). Keep the level +# low — high debug (e.g. 256) OOMs under OpenLDAPHelper's 512Mi memory limit. +exec "${SLAPD}" -f "${CONF_FILE}" -h "${LISTEN}" -d 1 diff --git a/src/deployment/openldap/image/seed.ldif b/src/deployment/openldap/image/seed.ldif new file mode 100644 index 0000000..b64e598 --- /dev/null +++ b/src/deployment/openldap/image/seed.ldif @@ -0,0 +1,102 @@ +# Bootstrap tree for RHDH LDAP e2e (OpenLDAP / Bitnami). +# Loaded via LDAP_CUSTOM_LDIF_DIR=/ldifs — must include root + OUs. + +dn: dc=rhdh,dc=test +objectClass: dcObject +objectClass: organization +o: RHDH Test +dc: rhdh + +dn: ou=users,dc=rhdh,dc=test +objectClass: organizationalUnit +ou: users + +dn: ou=groups,dc=rhdh,dc=test +objectClass: organizationalUnit +ou: groups + +dn: uid=user1,ou=users,dc=rhdh,dc=test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +uid: user1 +cn: User 1 +sn: One +givenName: User +mail: user1@rhdh.test +userPassword: user1pass + +dn: uid=user2,ou=users,dc=rhdh,dc=test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +uid: user2 +cn: User 2 +sn: Two +givenName: User +mail: user2@rhdh.test +userPassword: user1pass + +dn: uid=user3,ou=users,dc=rhdh,dc=test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +uid: user3 +cn: User 3 +sn: Three +givenName: User +mail: user3@rhdh.test +userPassword: user1pass + +dn: uid=rhdh-admin,ou=users,dc=rhdh,dc=test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +uid: rhdh-admin +cn: RHDH Admin +sn: Admin +givenName: RHDH +mail: rhdh-admin@rhdh.test +userPassword: user1pass + +dn: cn=Admins,ou=groups,dc=rhdh,dc=test +objectClass: groupOfNames +objectClass: top +cn: Admins +member: uid=rhdh-admin,ou=users,dc=rhdh,dc=test + +dn: cn=All_Users,ou=groups,dc=rhdh,dc=test +objectClass: groupOfNames +objectClass: top +cn: All_Users +member: uid=user1,ou=users,dc=rhdh,dc=test +member: uid=user2,ou=users,dc=rhdh,dc=test + +dn: cn=SubAdmins,ou=groups,dc=rhdh,dc=test +objectClass: groupOfNames +objectClass: top +cn: SubAdmins +member: uid=rhdh-admin,ou=users,dc=rhdh,dc=test + +# Nested groups: create leaves before parents so member DNs resolve. +dn: cn=testSubSubGroup,ou=groups,dc=rhdh,dc=test +objectClass: groupOfNames +objectClass: top +cn: testSubSubGroup +member: uid=user3,ou=users,dc=rhdh,dc=test + +dn: cn=testSubGroup,ou=groups,dc=rhdh,dc=test +objectClass: groupOfNames +objectClass: top +cn: testSubGroup +member: cn=testSubSubGroup,ou=groups,dc=rhdh,dc=test + +dn: cn=testGroup,ou=groups,dc=rhdh,dc=test +objectClass: groupOfNames +objectClass: top +cn: testGroup +member: cn=testSubGroup,ou=groups,dc=rhdh,dc=test diff --git a/src/deployment/openldap/image/slapd.conf.template b/src/deployment/openldap/image/slapd.conf.template new file mode 100644 index 0000000..d60c878 --- /dev/null +++ b/src/deployment/openldap/image/slapd.conf.template @@ -0,0 +1,18 @@ +# Generated at container start from entrypoint.sh (e2e only). +include /opt/openldap/etc/openldap/schema/core.schema +include /opt/openldap/etc/openldap/schema/cosine.schema +include /opt/openldap/etc/openldap/schema/inetorgperson.schema +include /opt/openldap/etc/openldap/schema/nis.schema + +pidfile /opt/openldap/var/run/slapd.pid +argsfile /opt/openldap/var/run/slapd.args + +database mdb +suffix "__LDAP_ROOT__" +rootdn "cn=__LDAP_ADMIN_USERNAME__,__LDAP_ROOT__" +rootpw "__LDAP_ADMIN_PASSWORD__" +directory /var/lib/ldap +maxsize 1073741824 +index objectClass eq +index cn,uid eq +index uidNumber,gidNumber eq