chore(opencloud): Remove external OpenLDAP deployment

OpenCloud has been migrated to use the built-in IDM service which
provides an internal LDAP server (localhost:9236). The external
OpenLDAP deployment is no longer needed.

Changes:
- Remove openldap-deployment.yaml and related configuration files
- Remove openldap-admin-sealed.yaml (admin credentials)
- Remove ldap-init-structure.ldif (initialization script)
- Remove opencloud-ldap-schema files (schema configuration)
- Remove OPENLDAP_DEPLOYMENT.md documentation
- Remove OPENLDAP_ADMIN_PASSWORD env var from OpenCloud deployment

The OpenCloud deployment now relies solely on the built-in IDM
service for user and group storage via its internal LDAP interface.

Resolves: DEV-421

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
CTO Agent 2026-08-01 08:16:14 +00:00
parent b06c994c9d
commit 2c1cd9c239
7 changed files with 0 additions and 590 deletions

View file

@ -1,257 +0,0 @@
# OpenCloud with External OpenLDAP Deployment Guide
## Architecture Overview
This deployment uses:
- **External OpenLDAP** for user/group storage
- **Pocket ID** (auth.basicstack.de) for authentication via OIDC
- **OpenCloud** as the file storage platform
### Authentication Flow
1. User accesses `https://opencloud.basicstack.de`
2. OpenCloud redirects to Pocket ID for authentication
3. User logs in at `https://auth.basicstack.de`
4. Pocket ID returns OIDC token to OpenCloud
5. OpenCloud auto-provisions user in external OpenLDAP
6. User is granted access based on OIDC group claims
## Deployment Steps
### 1. Create OpenLDAP Admin Secret
First, generate strong passwords and create the sealed secret:
```bash
# Generate passwords
ADMIN_PASSWORD=$(openssl rand -base64 32)
CONFIG_PASSWORD=$(openssl rand -base64 32)
# Save them securely (e.g., password manager)
echo "Admin Password: $ADMIN_PASSWORD"
echo "Config Password: $CONFIG_PASSWORD"
# Create sealed secret
kubectl create secret generic openldap-admin-secret \
--namespace opencloud \
--from-literal=admin-password="$ADMIN_PASSWORD" \
--from-literal=config-password="$CONFIG_PASSWORD" \
--dry-run=client -o yaml | \
kubeseal --format yaml > openldap-admin-sealed.yaml
# Apply sealed secret
kubectl apply -f openldap-admin-sealed.yaml
```
### 2. Deploy OpenLDAP
```bash
# Deploy OpenLDAP
kubectl apply -f openldap-deployment.yaml
# Wait for OpenLDAP to be ready
kubectl wait --for=condition=ready pod -l app=openldap -n opencloud --timeout=120s
# Check OpenLDAP pod status
kubectl get pods -n opencloud -l app=openldap
kubectl logs -n opencloud -l app=openldap -f
```
### 3. Initialize LDAP Directory Structure
Once OpenLDAP is running, initialize the directory with required OUs:
```bash
# Get the OpenLDAP pod name
LDAP_POD=$(kubectl get pods -n opencloud -l app=openldap -o jsonpath='{.items[0].metadata.name}')
# Copy the LDIF file to the pod
kubectl cp ldap-init-structure.ldif opencloud/$LDAP_POD:/tmp/init-structure.ldif
# Apply the LDIF (replace <admin-password> with your actual password)
kubectl exec -n opencloud $LDAP_POD -- \
ldapadd -x -D "cn=admin,dc=basicstack,dc=de" -w "<admin-password>" -f /tmp/init-structure.ldif
# Verify structure was created
kubectl exec -n opencloud $LDAP_POD -- \
ldapsearch -x -D "cn=admin,dc=basicstack,dc=de" -w "<admin-password>" -b "dc=basicstack,dc=de" -LLL
```
### 4. Deploy OpenCloud
**Important:** Make sure the old OpenCloud PVC is deleted first to ensure fresh initialization with new LDAP configuration.
```bash
# Scale down existing OpenCloud deployment (if running)
kubectl scale deployment -n opencloud opencloud --replicas=0
# Delete old PVC
kubectl delete pvc -n opencloud opencloud-data
# Apply updated deployment
kubectl apply -f opencloud-deployment.yaml
kubectl apply -f opencloud-configmap.yaml
# Scale up
kubectl scale deployment -n opencloud opencloud --replicas=1
# Watch initialization
kubectl logs -n opencloud -l app=opencloud -f
```
### 5. Verify Configuration
```bash
# Check all pods are running
kubectl get pods -n opencloud
# Verify OpenCloud can connect to LDAP
kubectl exec -n opencloud deployment/opencloud -- \
ldapsearch -x -H ldap://openldap.opencloud.svc.cluster.local:389 \
-D "cn=admin,dc=basicstack,dc=de" -w "<admin-password>" \
-b "dc=basicstack,dc=de" -LLL
# Check OpenCloud logs for LDAP connection
kubectl logs -n opencloud -l app=opencloud | grep -i ldap
```
### 6. Test OIDC Authentication
1. Open browser to `https://opencloud.basicstack.de`
2. Should redirect to `https://auth.basicstack.de`
3. Login with Pocket ID credentials
4. Should redirect back to OpenCloud
5. User auto-provisioned in OpenLDAP
## LDAP Directory Structure
```
dc=basicstack,dc=de
├── cn=admin (admin user)
├── ou=users
│ └── (auto-provisioned users from OIDC)
└── ou=groups
├── cn=opencloudUsers (default users group)
└── cn=opencloudAdmins (administrators group)
```
## Configuration Details
### OpenLDAP Connection Details
- **Service:** `openldap.opencloud.svc.cluster.local`
- **Port:** 389 (LDAP), 636 (LDAPS - disabled for internal use)
- **Base DN:** `dc=basicstack,dc=de`
- **Admin DN:** `cn=admin,dc=basicstack,dc=de`
- **User Base:** `ou=users,dc=basicstack,dc=de`
- **Group Base:** `ou=groups,dc=basicstack,dc=de`
### OpenCloud Services Excluded
- **search** - Broken in v7.2.0
- **idp** - Using external Pocket ID for authentication
- **idm** - Using external OpenLDAP for user storage
### OIDC Configuration
- **Issuer:** `https://auth.basicstack.de`
- **Client ID:** (from `opencloud-oidc-secret`)
- **Scopes:** `openid profile email groups offline_access`
- **Auto-provisioning:** Enabled
- **User claim:** `email`
- **Role claim:** `groups`
### Role Mapping
OIDC groups → OpenCloud roles:
- `opencloudAdmin` → admin
- `opencloudSpaceAdmin` → spaceadmin
- `opencloudUser` → user
- `opencloudGuest` → guest
## Troubleshooting
### OpenLDAP not starting
```bash
# Check logs
kubectl logs -n opencloud -l app=openldap
# Check PVCs
kubectl get pvc -n opencloud
# Check events
kubectl get events -n opencloud --sort-by='.lastTimestamp' | tail -20
```
### OpenCloud can't connect to LDAP
```bash
# Test LDAP connectivity from OpenCloud pod
kubectl exec -n opencloud deployment/opencloud -- \
nc -zv openldap.opencloud.svc.cluster.local 389
# Check LDAP service
kubectl get svc -n opencloud openldap
# Check LDAP endpoints
kubectl get endpoints -n opencloud openldap
```
### Users not auto-provisioning
```bash
# Check OpenCloud proxy logs
kubectl logs -n opencloud -l app=opencloud | grep -i provision
# Check OIDC flow
kubectl logs -n opencloud -l app=opencloud | grep -i oidc
# Verify LDAP directory structure
kubectl exec -n opencloud deployment/openldap -- \
ldapsearch -x -D "cn=admin,dc=basicstack,dc=de" -w "<password>" \
-b "ou=users,dc=basicstack,dc=de" -LLL
```
### View auto-provisioned users
```bash
# List all users in LDAP
kubectl exec -n opencloud deployment/openldap -- \
ldapsearch -x -D "cn=admin,dc=basicstack,dc=de" -w "<password>" \
-b "ou=users,dc=basicstack,dc=de" -LLL "(objectClass=inetOrgPerson)"
```
## Backup and Maintenance
### Backup LDAP Data
```bash
# Backup entire LDAP directory
kubectl exec -n opencloud deployment/openldap -- \
slapcat -l /tmp/backup.ldif
kubectl cp opencloud/$LDAP_POD:/tmp/backup.ldif ./ldap-backup-$(date +%Y%m%d).ldif
```
### Monitor LDAP Performance
```bash
# Check LDAP stats
kubectl exec -n opencloud deployment/openldap -- \
ldapsearch -x -H ldapi:/// -Y EXTERNAL -b "cn=Monitor" -LLL
```
## Files
- `openldap-deployment.yaml` - OpenLDAP Kubernetes deployment
- `openldap-admin-sealed.yaml` - Admin credentials (sealed secret)
- `ldap-init-structure.ldif` - Initial directory structure
- `opencloud-deployment.yaml` - OpenCloud deployment (updated for external LDAP)
- `opencloud-configmap.yaml` - OpenCloud configuration (updated for external LDAP)
## References
- OpenLDAP: https://www.openldap.org/
- OpenCloud LDAP Configuration: https://docs.opencloud.eu/
- Pocket ID: https://github.com/stonith404/pocket-id

View file

@ -1,37 +0,0 @@
# OpenLDAP Directory Structure Initialization
# This LDIF creates the organizational units needed by OpenCloud
#
# Apply with:
# kubectl exec -n opencloud deployment/openldap -- \
# ldapadd -x -D "cn=admin,dc=basicstack,dc=de" -w <admin-password> -f /tmp/init-structure.ldif
#
# Or copy to pod and apply:
# kubectl cp ldap-init-structure.ldif opencloud/openldap-<pod-id>:/tmp/init-structure.ldif
# kubectl exec -n opencloud openldap-<pod-id> -- \
# ldapadd -x -D "cn=admin,dc=basicstack,dc=de" -w <admin-password> -f /tmp/init-structure.ldif
# Create Users Organizational Unit
dn: ou=users,dc=basicstack,dc=de
objectClass: organizationalUnit
ou: users
description: OpenCloud Users
# Create Groups Organizational Unit
dn: ou=groups,dc=basicstack,dc=de
objectClass: organizationalUnit
ou: groups
description: OpenCloud Groups
# Example: Create default user group
dn: cn=opencloudUsers,ou=groups,dc=basicstack,dc=de
objectClass: groupOfNames
cn: opencloudUsers
description: Default OpenCloud Users Group
member: cn=admin,dc=basicstack,dc=de
# Example: Create admin group
dn: cn=opencloudAdmins,ou=groups,dc=basicstack,dc=de
objectClass: groupOfNames
cn: opencloudAdmins
description: OpenCloud Administrators
member: cn=admin,dc=basicstack,dc=de

View file

@ -290,13 +290,6 @@ spec:
name: opencloud-config-secrets
key: ldap-bind-password
# External OpenLDAP admin password (for user/group storage)
- name: OPENLDAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: openldap-admin-secret
key: admin-password
# IDM service user passwords
- name: OC_IDM_ADMIN_PASSWORD
valueFrom:

View file

@ -1,68 +0,0 @@
---
# One-shot Job to load the OpenCloud LDAP schema into the running OpenLDAP instance.
# Connect via network LDAP as cn=admin,cn=config (rootdn of the config database).
# Re-run by deleting and recreating the Job; idempotent (exits 0 if schema already present).
apiVersion: batch/v1
kind: Job
metadata:
name: opencloud-ldap-schema-loader
namespace: opencloud
spec:
ttlSecondsAfterFinished: 86400
backoffLimit: 10
template:
spec:
restartPolicy: OnFailure
containers:
- name: schema-loader
image: osixia/openldap:1.5.0
command:
- /bin/bash
- -c
- |
set -e
echo "Waiting for OpenLDAP to be ready..."
until ldapsearch -x -H ldap://openldap:389 \
-D "cn=admin,dc=basicstack,dc=de" \
-w "$LDAP_ADMIN_PASSWORD" \
-b "dc=basicstack,dc=de" \
-s base "(objectClass=*)" dn 2>&1 | grep -q "result: 0"; do
echo "Not ready yet, retrying in 5s..."
sleep 5
done
echo "OpenLDAP is ready"
if ldapsearch -x -H ldap://openldap:389 \
-D "cn=admin,cn=config" \
-w "$LDAP_CONFIG_PASSWORD" \
-b "cn=schema,cn=config" \
"(cn={*}opencloud)" dn 2>/dev/null | grep -qi "opencloud"; then
echo "OpenCloud schema already present, nothing to do"
exit 0
fi
echo "Loading OpenCloud LDAP schema..."
ldapadd -x -H ldap://openldap:389 \
-D "cn=admin,cn=config" \
-w "$LDAP_CONFIG_PASSWORD" \
-f /schemas/10_opencloud_schema.ldif
echo "OpenCloud schema loaded successfully"
env:
- name: LDAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: openldap-admin-secret
key: admin-password
- name: LDAP_CONFIG_PASSWORD
valueFrom:
secretKeyRef:
name: openldap-admin-secret
key: config-password
volumeMounts:
- name: schemas
mountPath: /schemas
volumes:
- name: schemas
configMap:
name: opencloud-ldap-schema

View file

@ -1,58 +0,0 @@
---
# OpenCloud LDAP schema ConfigMap
# Defines openCloudUser objectClass and related attributes (OIDs under 1.3.6.1.4.1.63016)
# Mounted into OpenLDAP pod and loaded via lifecycle postStart hook
apiVersion: v1
kind: ConfigMap
metadata:
name: opencloud-ldap-schema
namespace: opencloud
data:
10_opencloud_schema.ldif: |
dn: cn=opencloud,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: opencloud
olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.1
NAME 'openCloudUUID'
DESC 'A non-reassignable and persistent account ID'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.2
NAME 'openCloudExternalIdentity'
DESC 'Represents the objectIdentity resource type of the Graph API'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.3
NAME 'openCloudUserEnabled'
DESC 'Indicates if the user account is enabled'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.4
NAME 'openCloudUserType'
DESC 'Specifies the user type (Member or Guest)'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.5
NAME 'openCloudLastSignInTimestamp'
DESC 'Timestamp of the most recent authentication event'
EQUALITY generalizedTimeMatch
ORDERING generalizedTimeOrderingMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
SINGLE-VALUE )
olcObjectClasses: ( 1.3.6.1.4.1.63016.1.2.1
NAME 'openCloudObject'
DESC 'Base auxiliary class for OpenCloud objects'
AUXILIARY
MAY ( openCloudUUID ) )
olcObjectClasses: ( 1.3.6.1.4.1.63016.1.2.2
NAME 'openCloudUser'
DESC 'Auxiliary class for OpenCloud user accounts'
AUXILIARY
SUP openCloudObject
MAY ( openCloudExternalIdentity $ openCloudUserEnabled $ openCloudUserType $ openCloudLastSignInTimestamp ) )

View file

@ -1,16 +0,0 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: openldap-admin-secret
namespace: opencloud
spec:
encryptedData:
admin-password: AgCfe8Y89Uy1gGJtkD/8QUn0KJMGKHvVc53f8N0tJk0KECT5Bxas9zNxL6UF+3Uxz/IgP4F3ZMgQ0AEy5GpnOHHZkWxjXjs64WGiUauA59MCxMQT6kwKtLkTX7M632S0HKwbS+vJi2S/r6JmMjSfCQJrsf2XKrfeyeg3+MqxwDSjIYdfyUTvNJ190QA0guqEpJltch8+Mr7Va0oxbwO64gDSXyjIipOCEHiGlMEiYlFXgEI/xUBEsvWN5jwgjmCkNTvx0id5+5ZhZHtWbLVBTP0caAqPhgsxjI0OhNPb8ZSzLx2uPgBK4m2jw6Kw4TvL+mJq1tvGjxnxVnDil4GhB4sjm0PKsL1EOeXzJphQWHvk6wDgrf3KW9uQPBODfVH1xUYCkrFWa/YzYM+rYJtnKdUVfqV6U//Vd64BXjz0Opx8twd9ljwlMBnW+8RRy8940m1bGEaKWeZNdXU+gVGEd+E4dYdqycz46UvktQmyFQgNjesGNbpwc+fVw4E2uDCLM8Lo35PnIcGeaMRQeurQuSFbKntFazB6nggkweesiFcPLSoHWUsvrdyK7h9lkLOg0KG5SoUs4aUkd2L4UpLHGMxV2PioxMPI6epe3AFIkcuMO/ukJuA7Cg58P9ZUZiED2dhkF9hOoUibaAKndwdPtQzBQUofj0LMVqHcSKjH3jC1eOAbKzvTHELfdWql5fldE5IEFP/HkfguGAqvV8XGm4QPb4D1Tj2raMHiiG39rq4mHgcdF++9IGjxdTYnaw==
config-password: AgBtWsvBgzOq6mHKZ7HLd/SqEVGFozSkXKWyqLUVKFNNnjwVwvZU/vUFKzKxC7xqoNjccqrQjcxbAPAA8USxZyUrW+Qws/v7J4w2bvtg3nklZfG8FGZZvaLFkUJKV0ZWa+kg3CFoFk5hHH3IpesfZTOCJPTiCey61os0m8DS1g9fre1eKVZz5RFk3d79Pv+O8P4ao9RF+dXPYuBMLHxg+b77p/LzeV0sCIicdLKNrQaPGj8OP9JyGpD8XLX3enWFtFNtX48gLnVGrzNLWo/Ic2LQZoqM7XUB2d/zlB6CN6KrnkZEoR3L5GPU7fVXAga6L1JqTiPD8SG7BnWlxdKZEeoko94NciBQcIG1igE4+HTMBx3kbES+eh+kV2ImLzKTYuUuoN7TUJnOXP10x2zf1OhdKumqFqNFVPPJW8zDtzIflkzwFN79cY+WP5XOL/XUnLIISIGGpW4tTyfsLL3BnoWtkfuSjeH6JEsq8xOcVSyg0/6hCmz9ZztkmqMjTEkL0++agaXxPQgyvsxX8r/8TCwVt02RGRbPUQqH9r6/xdIX4SQEzoFhbINqPgCVuY7U/cNqAOxwP7FmG6Dcm8wAEtFTEFqU3T5eo0iuQqpfN3iXsFahf7e28Jh2N5JS344RiqA0HAmu4QT67maXLQrvkbL6zYY5pROsm2y2xgZP432AZ98hw3BooDelkLZZ9A5HNgBg8I/kSBgX2xLZR+Nc5L7KH240zR5/0Hc0jh9fjzdibISQ76y4gTEp1Y2KSg==
template:
metadata:
creationTimestamp: null
name: openldap-admin-secret
namespace: opencloud

View file

@ -1,147 +0,0 @@
---
# OpenLDAP Deployment for OpenCloud
# Provides external LDAP directory for user and group storage
# OpenLDAP Data Storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: openldap-data
namespace: opencloud
spec:
accessModes:
- ReadWriteOnce
storageClassName: hcloud-volumes-encrypted
resources:
requests:
storage: 10Gi
---
# OpenLDAP Config Storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: openldap-config
namespace: opencloud
spec:
accessModes:
- ReadWriteOnce
storageClassName: hcloud-volumes-encrypted
resources:
requests:
storage: 1Gi
---
# OpenLDAP Service
apiVersion: v1
kind: Service
metadata:
name: openldap
namespace: opencloud
spec:
type: ClusterIP
selector:
app: openldap
ports:
- name: ldap
port: 389
targetPort: 389
protocol: TCP
- name: ldaps
port: 636
targetPort: 636
protocol: TCP
---
# OpenLDAP Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: openldap
namespace: opencloud
spec:
replicas: 1
selector:
matchLabels:
app: openldap
template:
metadata:
labels:
app: openldap
spec:
containers:
- name: openldap
image: osixia/openldap:1.5.0
env:
# Organization and domain
- name: LDAP_ORGANISATION
value: "BasicStack"
- name: LDAP_DOMAIN
value: "basicstack.de"
# Admin credentials
- name: LDAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: openldap-admin-secret
key: admin-password
# Config admin password
- name: LDAP_CONFIG_PASSWORD
valueFrom:
secretKeyRef:
name: openldap-admin-secret
key: config-password
# Base DN will be: dc=basicstack,dc=de
# Admin DN will be: cn=admin,dc=basicstack,dc=de
# Logging
- name: LDAP_LOG_LEVEL
value: "256"
# TLS disabled for internal cluster communication
- name: LDAP_TLS
value: "false"
# Remove default database and start fresh
- name: LDAP_REMOVE_CONFIG_AFTER_SETUP
value: "false"
ports:
- containerPort: 389
name: ldap
- containerPort: 636
name: ldaps
volumeMounts:
- name: openldap-data
mountPath: /var/lib/ldap
- name: openldap-config
mountPath: /etc/ldap/slapd.d
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
tcpSocket:
port: 389
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
tcpSocket:
port: 389
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 3
volumes:
- name: openldap-data
persistentVolumeClaim:
claimName: openldap-data
- name: openldap-config
persistentVolumeClaim:
claimName: openldap-config