ci: add root Jenkinsfile and update keycloak ldap job

This commit is contained in:
Brad Stein 2026-01-20 18:11:13 -03:00
parent 163f98c594
commit c846d2c1ba
2 changed files with 126 additions and 1 deletions

77
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,77 @@
// Mirror of ci/Jenkinsfile.titan-iac for multibranch discovery.
pipeline {
agent {
kubernetes {
defaultContainer 'python'
yaml """
apiVersion: v1
kind: Pod
spec:
nodeSelector:
hardware: rpi5
kubernetes.io/arch: arm64
node-role.kubernetes.io/worker: "true"
containers:
- name: python
image: python:3.12-slim
command:
- cat
tty: true
"""
}
}
environment {
PIP_DISABLE_PIP_VERSION_CHECK = '1'
PYTHONUNBUFFERED = '1'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install deps') {
steps {
sh 'pip install --no-cache-dir -r ci/requirements.txt'
}
}
stage('Glue tests') {
steps {
sh 'pytest -q ci/tests/glue'
}
}
stage('Resolve Flux branch') {
steps {
script {
env.FLUX_BRANCH = sh(
returnStdout: true,
script: "awk '/branch:/{print $2; exit}' clusters/atlas/flux-system/gotk-sync.yaml"
).trim()
if (!env.FLUX_BRANCH) {
error('Flux branch not found in gotk-sync.yaml')
}
echo "Flux branch: ${env.FLUX_BRANCH}"
}
}
}
stage('Promote') {
when {
expression {
def branch = env.BRANCH_NAME ?: (env.GIT_BRANCH ?: '').replaceFirst('origin/', '')
return env.FLUX_BRANCH && branch == env.FLUX_BRANCH
}
}
steps {
withCredentials([usernamePassword(credentialsId: 'gitea-pat', usernameVariable: 'GIT_USER', passwordVariable: 'GIT_TOKEN')]) {
sh '''
set +x
git config user.email "jenkins@bstein.dev"
git config user.name "jenkins"
git remote set-url origin https://${GIT_USER}:${GIT_TOKEN}@scm.bstein.dev/bstein/titan-iac.git
git push origin HEAD:${FLUX_BRANCH}
'''
}
}
}
}
}

View File

@ -2,7 +2,7 @@
apiVersion: batch/v1
kind: Job
metadata:
name: keycloak-ldap-federation-11
name: keycloak-ldap-federation-12
namespace: sso
spec:
backoffLimit: 2
@ -325,6 +325,54 @@ spec:
if status not in (201, 204):
raise SystemExit(f"Unexpected group mapper create status: {status}")
def ensure_user_attr_mapper(name: str, ldap_attr: str, user_attr: str):
mapper = None
for c in components:
if c.get("name") == name and c.get("parentId") == ldap_component_id:
mapper = c
break
payload = {
"name": name,
"providerId": "user-attribute-ldap-mapper",
"providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper",
"parentId": ldap_component_id,
"config": {
"ldap.attribute": [ldap_attr],
"user.model.attribute": [user_attr],
"read.only": ["false"],
"always.read.value.from.ldap": ["false"],
"is.mandatory.in.ldap": ["false"],
},
}
if mapper:
payload["id"] = mapper["id"]
payload["parentId"] = mapper.get("parentId", payload["parentId"])
print(f"Updating LDAP user mapper: {payload['id']} ({name})")
status, _, _ = http_json(
"PUT",
f"{base_url}/admin/realms/{realm}/components/{payload['id']}",
token,
payload,
)
if status not in (200, 204):
raise SystemExit(f"Unexpected user mapper update status for {name}: {status}")
else:
print(f"Creating LDAP user mapper: {name}")
status, _, _ = http_json(
"POST",
f"{base_url}/admin/realms/{realm}/components",
token,
payload,
)
if status not in (201, 204):
raise SystemExit(f"Unexpected user mapper create status for {name}: {status}")
ensure_user_attr_mapper("openldap-email", "mail", "email")
ensure_user_attr_mapper("openldap-first-name", "givenName", "firstName")
ensure_user_attr_mapper("openldap-last-name", "sn", "lastName")
# Cleanup duplicate LDAP federation providers and their child components (mappers, etc).
# Keep only the canonical provider we updated/created above.
try: