Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
5 changes: 2 additions & 3 deletions src/deployment/openldap/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
9 changes: 4 additions & 5 deletions src/deployment/openldap/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -237,10 +236,10 @@ spec:
resources:
requests:
cpu: 50m
memory: 128Mi
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
memory: 1Gi
volumes:
- name: seed
configMap:
Expand Down
79 changes: 79 additions & 0 deletions src/deployment/openldap/image/Containerfile
Original file line number Diff line number Diff line change
@@ -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"]
67 changes: 67 additions & 0 deletions src/deployment/openldap/image/README.md
Original file line number Diff line number Diff line change
@@ -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=<user>,<root>` |
| `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) |
67 changes: 67 additions & 0 deletions src/deployment/openldap/image/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -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}" <<EOF

TLSCertificateFile ${LDAP_TLS_CERT_FILE}
TLSCertificateKeyFile ${LDAP_TLS_KEY_FILE}
TLSCACertificateFile ${LDAP_TLS_CA_FILE}
TLSVerifyClient never
EOF
fi

# First boot: load seed into the MDB via slapadd (slapd must be stopped).
if [[ ! -f "${DATA_DIR}/data.mdb" ]]; then
echo "[openldap-pq] initializing MDB from ${LDAP_SEED_FILE}"
if [[ ! -f "${LDAP_SEED_FILE}" ]]; then
echo "[openldap-pq] seed file not found: ${LDAP_SEED_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
102 changes: 102 additions & 0 deletions src/deployment/openldap/image/seed.ldif
Original file line number Diff line number Diff line change
@@ -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
Loading
Loading