diff --git a/Chart.yaml b/Chart.yaml index 6d7d89b..36033a2 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: ldap-stack description: OpenLDAP + phpLDAPadmin + Keycloak stack for centralized identity management with SSO support type: application -version: 1.1.2 +version: 1.3.0 appVersion: "2.6.0" annotations: artifacthub.io/signKey: | @@ -24,11 +24,17 @@ annotations: image: osixia/phpldapadmin:latest - name: keycloak image: quay.io/keycloak/keycloak:latest + - name: ldap-sync-google + image: startcodex/ldap-sync-google:latest artifacthub.io/containsSecurityUpdates: "false" artifacthub.io/prerelease: "false" artifacthub.io/changes: | - - kind: fixed - description: Fix Keycloak production mode proxy configuration (KC_PROXY_HEADERS, KC_HTTP_ENABLED) + - kind: added + description: Add LDAP to Google Workspace sync component (startcodex/ldap-sync-google) + - kind: added + description: Support for Deployment or CronJob modes for Google sync + - kind: added + description: Support external LDAP secret for Google sync (existingSecret for LDAP credentials) keywords: - ldap - openldap @@ -41,6 +47,8 @@ keywords: - saml - directory - iam + - google-workspace + - sync home: https://github.com/start-codex/ldap-stack-helm-chart icon: https://www.openldap.org/images/openldap-logo-96x96.png sources: diff --git a/templates/google-sync-cronjob.yaml b/templates/google-sync-cronjob.yaml new file mode 100644 index 0000000..d16b9bf --- /dev/null +++ b/templates/google-sync-cronjob.yaml @@ -0,0 +1,203 @@ +{{- if and .Values.googleSync.enabled .Values.googleSync.cronJob.enabled }} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "ldap-stack.fullname" . }}-google-sync + labels: + {{- include "ldap-stack.labels" . | nindent 4 }} + app.kubernetes.io/component: google-sync +spec: + schedule: {{ .Values.googleSync.cronJob.schedule | quote }} + concurrencyPolicy: {{ .Values.googleSync.cronJob.concurrencyPolicy }} + successfulJobsHistoryLimit: {{ .Values.googleSync.cronJob.successfulJobsHistoryLimit }} + failedJobsHistoryLimit: {{ .Values.googleSync.cronJob.failedJobsHistoryLimit }} + jobTemplate: + spec: + template: + metadata: + labels: + {{- include "ldap-stack.selectorLabels" . | nindent 12 }} + app.kubernetes.io/component: google-sync + spec: + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 12 }} + {{- end }} + restartPolicy: OnFailure + containers: + - name: google-sync + image: "{{ .Values.googleSync.image.repository }}:{{ .Values.googleSync.image.tag }}" + imagePullPolicy: {{ .Values.googleSync.image.pullPolicy }} + env: + # No interval for CronJob - runs once per execution + - name: SYNC_INTERVAL + value: "0" + # LDAP Connection + {{- if .Values.googleSync.ldap.existingSecret }} + # Using external LDAP secret + - name: LDAP_HOST + {{- if .Values.googleSync.ldap.host }} + value: {{ .Values.googleSync.ldap.host | quote }} + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.host | default "host" }} + optional: true + {{- end }} + - name: LDAP_BIND_DN + {{- if .Values.googleSync.ldap.bindDN }} + value: {{ .Values.googleSync.ldap.bindDN | quote }} + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.bindDN | default "bind-dn" }} + {{- end }} + - name: LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.bindPassword | default "bind-password" }} + - name: LDAP_BASE_DN + {{- if .Values.googleSync.ldap.baseDN }} + value: {{ .Values.googleSync.ldap.baseDN | quote }} + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.baseDN | default "base-dn" }} + optional: true + {{- end }} + {{- else }} + # Using internal OpenLDAP + - name: LDAP_HOST + {{- if .Values.googleSync.ldap.host }} + value: {{ .Values.googleSync.ldap.host | quote }} + {{- else }} + value: {{ include "ldap-stack.openldap.fullname" . }} + {{- end }} + - name: LDAP_BIND_DN + {{- if .Values.googleSync.ldap.bindDN }} + value: {{ .Values.googleSync.ldap.bindDN | quote }} + {{- else }} + value: {{ include "ldap-stack.openldap.adminDN" . | quote }} + {{- end }} + - name: LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "ldap-stack.openldap.secretName" . }} + key: {{ .Values.openldap.secretKeys.adminPassword | default "admin-password" }} + - name: LDAP_BASE_DN + {{- if .Values.googleSync.ldap.baseDN }} + value: {{ .Values.googleSync.ldap.baseDN | quote }} + {{- else }} + value: {{ include "ldap-stack.openldap.baseDN" . | quote }} + {{- end }} + {{- end }} + - name: LDAP_PORT + value: {{ .Values.googleSync.ldap.port | quote }} + - name: LDAP_USE_TLS + value: {{ .Values.googleSync.ldap.useTLS | quote }} + {{- if .Values.googleSync.ldap.groupBaseDN }} + - name: LDAP_GROUP_BASE_DN + value: {{ .Values.googleSync.ldap.groupBaseDN | quote }} + {{- end }} + - name: LDAP_USER_FILTER + value: {{ .Values.googleSync.ldap.userFilter | quote }} + - name: LDAP_GROUP_FILTER + value: {{ .Values.googleSync.ldap.groupFilter | quote }} + # LDAP Attributes + - name: LDAP_ATTR_UID + value: {{ .Values.googleSync.ldapAttributes.uid | quote }} + - name: LDAP_ATTR_EMAIL + value: {{ .Values.googleSync.ldapAttributes.email | quote }} + - name: LDAP_ATTR_FIRSTNAME + value: {{ .Values.googleSync.ldapAttributes.firstName | quote }} + - name: LDAP_ATTR_LASTNAME + value: {{ .Values.googleSync.ldapAttributes.lastName | quote }} + - name: LDAP_ATTR_PHONE + value: {{ .Values.googleSync.ldapAttributes.phone | quote }} + - name: LDAP_ATTR_DEPARTMENT + value: {{ .Values.googleSync.ldapAttributes.department | quote }} + - name: LDAP_ATTR_TITLE + value: {{ .Values.googleSync.ldapAttributes.title | quote }} + - name: LDAP_ATTR_ORG_UNIT + value: {{ .Values.googleSync.ldapAttributes.orgUnit | quote }} + - name: LDAP_ATTR_GROUP_NAME + value: {{ .Values.googleSync.ldapAttributes.groupName | quote }} + - name: LDAP_ATTR_GROUP_EMAIL + value: {{ .Values.googleSync.ldapAttributes.groupEmail | quote }} + - name: LDAP_ATTR_GROUP_DESC + value: {{ .Values.googleSync.ldapAttributes.groupDescription | quote }} + - name: LDAP_ATTR_GROUP_MEMBER + value: {{ .Values.googleSync.ldapAttributes.groupMember | quote }} + # Google Configuration + - name: GOOGLE_CREDENTIALS_FILE + value: "/secrets/google/credentials.json" + - name: GOOGLE_ADMIN_EMAIL + value: {{ required "googleSync.google.adminEmail is required" .Values.googleSync.google.adminEmail | quote }} + - name: GOOGLE_DOMAIN + value: {{ required "googleSync.google.domain is required" .Values.googleSync.google.domain | quote }} + # Sync Options + - name: SYNC_DRY_RUN + value: {{ .Values.googleSync.sync.dryRun | quote }} + # User Sync Options + - name: SYNC_USERS + value: {{ .Values.googleSync.sync.users.enabled | quote }} + - name: SYNC_CREATE_USERS + value: {{ .Values.googleSync.sync.users.create | quote }} + - name: SYNC_UPDATE_USERS + value: {{ .Values.googleSync.sync.users.update | quote }} + - name: SYNC_SUSPEND_MISSING_USERS + value: {{ .Values.googleSync.sync.users.suspendMissing | quote }} + - name: SYNC_DELETE_INSTEAD_OF_SUSPEND + value: {{ .Values.googleSync.sync.users.deleteInsteadOfSuspend | quote }} + - name: SYNC_DEFAULT_ORG_UNIT + value: {{ .Values.googleSync.sync.users.defaultOrgUnit | quote }} + # Group Sync Options + - name: SYNC_GROUPS + value: {{ .Values.googleSync.sync.groups.enabled | quote }} + - name: SYNC_CREATE_GROUPS + value: {{ .Values.googleSync.sync.groups.create | quote }} + - name: SYNC_UPDATE_GROUPS + value: {{ .Values.googleSync.sync.groups.update | quote }} + - name: SYNC_DELETE_MISSING_GROUPS + value: {{ .Values.googleSync.sync.groups.deleteMissing | quote }} + - name: SYNC_GROUP_MEMBERS + value: {{ .Values.googleSync.sync.groups.syncMembers | quote }} + {{- if .Values.googleSync.sync.groups.emailSuffix }} + - name: SYNC_GROUP_EMAIL_SUFFIX + value: {{ .Values.googleSync.sync.groups.emailSuffix | quote }} + {{- end }} + # OU Sync Options + - name: SYNC_ORG_UNITS + value: {{ .Values.googleSync.sync.orgUnits.enabled | quote }} + - name: SYNC_CREATE_ORG_UNITS + value: {{ .Values.googleSync.sync.orgUnits.create | quote }} + volumeMounts: + - name: google-credentials + mountPath: /secrets/google + readOnly: true + resources: + {{- toYaml .Values.googleSync.resources | nindent 16 }} + volumes: + - name: google-credentials + secret: + secretName: {{ required "googleSync.google.existingSecret is required" .Values.googleSync.google.existingSecret }} + items: + - key: {{ .Values.googleSync.google.secretKey | default "credentials.json" }} + path: credentials.json + {{- with .Values.googleSync.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.googleSync.affinity }} + affinity: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.googleSync.tolerations }} + tolerations: + {{- toYaml . | nindent 12 }} + {{- end }} +{{- end }} diff --git a/templates/google-sync-deployment.yaml b/templates/google-sync-deployment.yaml new file mode 100644 index 0000000..97e0518 --- /dev/null +++ b/templates/google-sync-deployment.yaml @@ -0,0 +1,201 @@ +{{- if and .Values.googleSync.enabled (not .Values.googleSync.cronJob.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ldap-stack.fullname" . }}-google-sync + labels: + {{- include "ldap-stack.labels" . | nindent 4 }} + app.kubernetes.io/component: google-sync +spec: + replicas: 1 + selector: + matchLabels: + {{- include "ldap-stack.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: google-sync + template: + metadata: + labels: + {{- include "ldap-stack.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: google-sync + spec: + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: google-sync + image: "{{ .Values.googleSync.image.repository }}:{{ .Values.googleSync.image.tag }}" + imagePullPolicy: {{ .Values.googleSync.image.pullPolicy }} + env: + # Sync interval + - name: SYNC_INTERVAL + value: {{ .Values.googleSync.syncInterval | quote }} + # LDAP Connection + {{- if .Values.googleSync.ldap.existingSecret }} + # Using external LDAP secret + - name: LDAP_HOST + {{- if .Values.googleSync.ldap.host }} + value: {{ .Values.googleSync.ldap.host | quote }} + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.host | default "host" }} + optional: true + {{- end }} + - name: LDAP_BIND_DN + {{- if .Values.googleSync.ldap.bindDN }} + value: {{ .Values.googleSync.ldap.bindDN | quote }} + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.bindDN | default "bind-dn" }} + {{- end }} + - name: LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.bindPassword | default "bind-password" }} + - name: LDAP_BASE_DN + {{- if .Values.googleSync.ldap.baseDN }} + value: {{ .Values.googleSync.ldap.baseDN | quote }} + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.googleSync.ldap.existingSecret }} + key: {{ .Values.googleSync.ldap.secretKeys.baseDN | default "base-dn" }} + optional: true + {{- end }} + {{- else }} + # Using internal OpenLDAP + - name: LDAP_HOST + {{- if .Values.googleSync.ldap.host }} + value: {{ .Values.googleSync.ldap.host | quote }} + {{- else }} + value: {{ include "ldap-stack.openldap.fullname" . }} + {{- end }} + - name: LDAP_BIND_DN + {{- if .Values.googleSync.ldap.bindDN }} + value: {{ .Values.googleSync.ldap.bindDN | quote }} + {{- else }} + value: {{ include "ldap-stack.openldap.adminDN" . | quote }} + {{- end }} + - name: LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "ldap-stack.openldap.secretName" . }} + key: {{ .Values.openldap.secretKeys.adminPassword | default "admin-password" }} + - name: LDAP_BASE_DN + {{- if .Values.googleSync.ldap.baseDN }} + value: {{ .Values.googleSync.ldap.baseDN | quote }} + {{- else }} + value: {{ include "ldap-stack.openldap.baseDN" . | quote }} + {{- end }} + {{- end }} + - name: LDAP_PORT + value: {{ .Values.googleSync.ldap.port | quote }} + - name: LDAP_USE_TLS + value: {{ .Values.googleSync.ldap.useTLS | quote }} + {{- if .Values.googleSync.ldap.groupBaseDN }} + - name: LDAP_GROUP_BASE_DN + value: {{ .Values.googleSync.ldap.groupBaseDN | quote }} + {{- end }} + - name: LDAP_USER_FILTER + value: {{ .Values.googleSync.ldap.userFilter | quote }} + - name: LDAP_GROUP_FILTER + value: {{ .Values.googleSync.ldap.groupFilter | quote }} + # LDAP Attributes + - name: LDAP_ATTR_UID + value: {{ .Values.googleSync.ldapAttributes.uid | quote }} + - name: LDAP_ATTR_EMAIL + value: {{ .Values.googleSync.ldapAttributes.email | quote }} + - name: LDAP_ATTR_FIRSTNAME + value: {{ .Values.googleSync.ldapAttributes.firstName | quote }} + - name: LDAP_ATTR_LASTNAME + value: {{ .Values.googleSync.ldapAttributes.lastName | quote }} + - name: LDAP_ATTR_PHONE + value: {{ .Values.googleSync.ldapAttributes.phone | quote }} + - name: LDAP_ATTR_DEPARTMENT + value: {{ .Values.googleSync.ldapAttributes.department | quote }} + - name: LDAP_ATTR_TITLE + value: {{ .Values.googleSync.ldapAttributes.title | quote }} + - name: LDAP_ATTR_ORG_UNIT + value: {{ .Values.googleSync.ldapAttributes.orgUnit | quote }} + - name: LDAP_ATTR_GROUP_NAME + value: {{ .Values.googleSync.ldapAttributes.groupName | quote }} + - name: LDAP_ATTR_GROUP_EMAIL + value: {{ .Values.googleSync.ldapAttributes.groupEmail | quote }} + - name: LDAP_ATTR_GROUP_DESC + value: {{ .Values.googleSync.ldapAttributes.groupDescription | quote }} + - name: LDAP_ATTR_GROUP_MEMBER + value: {{ .Values.googleSync.ldapAttributes.groupMember | quote }} + # Google Configuration + - name: GOOGLE_CREDENTIALS_FILE + value: "/secrets/google/credentials.json" + - name: GOOGLE_ADMIN_EMAIL + value: {{ required "googleSync.google.adminEmail is required" .Values.googleSync.google.adminEmail | quote }} + - name: GOOGLE_DOMAIN + value: {{ required "googleSync.google.domain is required" .Values.googleSync.google.domain | quote }} + # Sync Options + - name: SYNC_DRY_RUN + value: {{ .Values.googleSync.sync.dryRun | quote }} + # User Sync Options + - name: SYNC_USERS + value: {{ .Values.googleSync.sync.users.enabled | quote }} + - name: SYNC_CREATE_USERS + value: {{ .Values.googleSync.sync.users.create | quote }} + - name: SYNC_UPDATE_USERS + value: {{ .Values.googleSync.sync.users.update | quote }} + - name: SYNC_SUSPEND_MISSING_USERS + value: {{ .Values.googleSync.sync.users.suspendMissing | quote }} + - name: SYNC_DELETE_INSTEAD_OF_SUSPEND + value: {{ .Values.googleSync.sync.users.deleteInsteadOfSuspend | quote }} + - name: SYNC_DEFAULT_ORG_UNIT + value: {{ .Values.googleSync.sync.users.defaultOrgUnit | quote }} + # Group Sync Options + - name: SYNC_GROUPS + value: {{ .Values.googleSync.sync.groups.enabled | quote }} + - name: SYNC_CREATE_GROUPS + value: {{ .Values.googleSync.sync.groups.create | quote }} + - name: SYNC_UPDATE_GROUPS + value: {{ .Values.googleSync.sync.groups.update | quote }} + - name: SYNC_DELETE_MISSING_GROUPS + value: {{ .Values.googleSync.sync.groups.deleteMissing | quote }} + - name: SYNC_GROUP_MEMBERS + value: {{ .Values.googleSync.sync.groups.syncMembers | quote }} + {{- if .Values.googleSync.sync.groups.emailSuffix }} + - name: SYNC_GROUP_EMAIL_SUFFIX + value: {{ .Values.googleSync.sync.groups.emailSuffix | quote }} + {{- end }} + # OU Sync Options + - name: SYNC_ORG_UNITS + value: {{ .Values.googleSync.sync.orgUnits.enabled | quote }} + - name: SYNC_CREATE_ORG_UNITS + value: {{ .Values.googleSync.sync.orgUnits.create | quote }} + volumeMounts: + - name: google-credentials + mountPath: /secrets/google + readOnly: true + resources: + {{- toYaml .Values.googleSync.resources | nindent 12 }} + volumes: + - name: google-credentials + secret: + secretName: {{ required "googleSync.google.existingSecret is required" .Values.googleSync.google.existingSecret }} + items: + - key: {{ .Values.googleSync.google.secretKey | default "credentials.json" }} + path: credentials.json + {{- with .Values.googleSync.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.googleSync.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.googleSync.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/values.schema.json b/values.schema.json index 370b75f..1313925 100644 --- a/values.schema.json +++ b/values.schema.json @@ -811,6 +811,232 @@ } } } + }, + "googleSync": { + "type": "object", + "description": "LDAP to Google Workspace Sync", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable LDAP to Google Workspace synchronization", + "default": false + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "default": "startcodex/ldap-sync-google" + }, + "tag": { + "type": "string", + "default": "latest" + }, + "pullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent" + } + } + }, + "syncInterval": { + "type": "string", + "description": "Sync interval (e.g., 1h, 30m). Set to 0 for single run", + "default": "1h" + }, + "cronJob": { + "type": "object", + "description": "Run as CronJob instead of Deployment", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "schedule": { + "type": "string", + "description": "Cron schedule", + "default": "0 * * * *" + }, + "concurrencyPolicy": { + "type": "string", + "enum": ["Allow", "Forbid", "Replace"], + "default": "Forbid" + }, + "successfulJobsHistoryLimit": { + "type": "integer", + "default": 3 + }, + "failedJobsHistoryLimit": { + "type": "integer", + "default": 3 + } + } + }, + "google": { + "type": "object", + "description": "Google Workspace configuration", + "properties": { + "domain": { + "type": "string", + "description": "Google Workspace domain" + }, + "adminEmail": { + "type": "string", + "description": "Admin email for impersonation" + }, + "existingSecret": { + "type": "string", + "description": "Secret containing Google service account credentials" + }, + "secretKey": { + "type": "string", + "description": "Key in secret containing credentials JSON", + "default": "credentials.json" + } + } + }, + "ldap": { + "type": "object", + "description": "LDAP connection settings", + "properties": { + "host": { + "type": "string", + "description": "LDAP host (default: uses openldap service)" + }, + "port": { + "type": "integer", + "default": 389, + "minimum": 1, + "maximum": 65535 + }, + "useTLS": { + "type": "boolean", + "default": false + }, + "bindDN": { + "type": "string", + "description": "Bind DN for authentication" + }, + "bindPassword": { + "type": "string", + "description": "Bind password" + }, + "baseDN": { + "type": "string", + "description": "Base DN for user searches" + }, + "groupBaseDN": { + "type": "string", + "description": "Base DN for group searches" + }, + "userFilter": { + "type": "string", + "default": "(objectClass=inetOrgPerson)" + }, + "groupFilter": { + "type": "string", + "default": "(objectClass=posixGroup)" + }, + "existingSecret": { + "type": "string", + "description": "Secret containing LDAP credentials for external LDAP" + }, + "secretKeys": { + "type": "object", + "properties": { + "host": { + "type": "string", + "default": "host" + }, + "bindDN": { + "type": "string", + "default": "bind-dn" + }, + "bindPassword": { + "type": "string", + "default": "bind-password" + }, + "baseDN": { + "type": "string", + "default": "base-dn" + } + } + } + } + }, + "ldapAttributes": { + "type": "object", + "description": "LDAP attribute mappings", + "properties": { + "uid": {"type": "string", "default": "uid"}, + "email": {"type": "string", "default": "mail"}, + "firstName": {"type": "string", "default": "givenName"}, + "lastName": {"type": "string", "default": "sn"}, + "phone": {"type": "string", "default": "telephoneNumber"}, + "department": {"type": "string", "default": "departmentNumber"}, + "title": {"type": "string", "default": "title"}, + "orgUnit": {"type": "string", "default": "ou"}, + "groupName": {"type": "string", "default": "cn"}, + "groupEmail": {"type": "string", "default": "mail"}, + "groupDescription": {"type": "string", "default": "description"}, + "groupMember": {"type": "string", "default": "memberUid"} + } + }, + "sync": { + "type": "object", + "description": "Sync options", + "properties": { + "dryRun": { + "type": "boolean", + "description": "Simulate changes without applying", + "default": true + }, + "users": { + "type": "object", + "properties": { + "enabled": {"type": "boolean", "default": true}, + "create": {"type": "boolean", "default": true}, + "update": {"type": "boolean", "default": true}, + "suspendMissing": {"type": "boolean", "default": false}, + "deleteInsteadOfSuspend": {"type": "boolean", "default": false}, + "defaultOrgUnit": {"type": "string", "default": "/"} + } + }, + "groups": { + "type": "object", + "properties": { + "enabled": {"type": "boolean", "default": false}, + "create": {"type": "boolean", "default": true}, + "update": {"type": "boolean", "default": true}, + "deleteMissing": {"type": "boolean", "default": false}, + "syncMembers": {"type": "boolean", "default": true}, + "emailSuffix": {"type": "string"} + } + }, + "orgUnits": { + "type": "object", + "properties": { + "enabled": {"type": "boolean", "default": false}, + "create": {"type": "boolean", "default": true} + } + } + } + }, + "resources": { + "$ref": "#/definitions/resources" + }, + "nodeSelector": { + "type": "object", + "additionalProperties": {"type": "string"} + }, + "tolerations": { + "type": "array", + "items": {"$ref": "#/definitions/toleration"} + }, + "affinity": { + "type": "object" + } + } } }, "definitions": { diff --git a/values.yaml b/values.yaml index 57fb9b4..f429a2c 100644 --- a/values.yaml +++ b/values.yaml @@ -360,3 +360,118 @@ metrics: repository: tomcz/openldap_exporter tag: "v2.1" port: 9330 + +# ----------------------------------------------------------------------------- +# LDAP to Google Workspace Sync +# ----------------------------------------------------------------------------- +googleSync: + # Enable LDAP to Google Workspace synchronization + enabled: false + + image: + repository: startcodex/ldap-sync-google + tag: "latest" + pullPolicy: IfNotPresent + + # Sync interval (e.g., 1h, 30m, 2h30m). Set to "0" for single run (use with CronJob) + syncInterval: "1h" + + # Run as CronJob instead of Deployment (recommended for production) + cronJob: + enabled: false + schedule: "0 * * * *" # Every hour + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + + # Google Workspace configuration + google: + # Google Workspace domain (REQUIRED) + domain: "" + # Admin email for impersonation (REQUIRED) + adminEmail: "" + # Existing secret containing Google service account credentials JSON + # Secret must contain key: credentials.json + existingSecret: "" + secretKey: "credentials.json" + + # LDAP connection (auto-configured from openldap if enabled) + ldap: + # Override LDAP host (default: uses openldap service) + host: "" + port: 389 + useTLS: false + # Bind DN for authentication (auto-configured from openldap if enabled) + bindDN: "" + # Bind password (auto-configured from openldap secret if enabled) + bindPassword: "" + # Base DN for user searches (auto-configured from openldap.config.domain) + baseDN: "" + # Base DN for group searches (defaults to baseDN) + groupBaseDN: "" + # LDAP filters + userFilter: "(objectClass=inetOrgPerson)" + groupFilter: "(objectClass=posixGroup)" + # Use existing secret for LDAP credentials (for external LDAP servers) + # Secret must contain keys defined in secretKeys + existingSecret: "" + secretKeys: + host: "host" # optional + bindDN: "bind-dn" + bindPassword: "bind-password" + baseDN: "base-dn" # optional + + # LDAP attribute mappings + ldapAttributes: + uid: "uid" + email: "mail" + firstName: "givenName" + lastName: "sn" + phone: "telephoneNumber" + department: "departmentNumber" + title: "title" + orgUnit: "ou" + # Group attributes + groupName: "cn" + groupEmail: "mail" + groupDescription: "description" + groupMember: "memberUid" + + # Sync options + sync: + # Dry run mode (simulate changes without applying) + dryRun: true + # User sync options + users: + enabled: true + create: true + update: true + suspendMissing: false + deleteInsteadOfSuspend: false + defaultOrgUnit: "/" + # Group sync options + groups: + enabled: false + create: true + update: true + deleteMissing: false + syncMembers: true + emailSuffix: "" # Defaults to @GOOGLE_DOMAIN + # Organizational Unit sync options + orgUnits: + enabled: false + create: true + + # Resources + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "100m" + + # Node selector, tolerations, affinity + nodeSelector: {} + tolerations: [] + affinity: {}