diff --git a/charts/repo-guard/templates/githuborganization.yaml b/charts/repo-guard/templates/githuborganization.yaml index cc8cc15e..aa4d6751 100644 --- a/charts/repo-guard/templates/githuborganization.yaml +++ b/charts/repo-guard/templates/githuborganization.yaml @@ -20,6 +20,47 @@ metadata: {{- if not (kindIs "map" $ttl) }}{{- $ttl = dict -}}{{- end }} repo-guard.cloudoperators.dev/failedTTL: "{{ ((get $ttl "failed") | default $.Values.ttl.organization.failed) }}" repo-guard.cloudoperators.dev/completedTTL: "{{ ((get $ttl "completed") | default $.Values.ttl.organization.completed) }}" + {{- $githubInstance := $org.githubInstanceHostname | default "" -}} + {{- if not $githubInstance -}} + {{- range $.Values.githubs -}} + {{- if eq (.name | lower) ($org.github | lower) -}} + {{- $webURL := .webURL | default "" -}} + {{- $host := ($webURL | trimPrefix "https://" | trimPrefix "http://") -}} + {{- $githubInstance = (splitList ":" $host | first | splitList "/" | first) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- if gt (len $githubInstance) 63 -}} + {{- fail (printf "github-instance label value exceeds 63 characters (got %d): %q — set githubInstanceHostname to a shorter value" (len $githubInstance) $githubInstance) -}} + {{- end -}} + {{- if and $githubInstance (not (regexMatch "^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$" $githubInstance)) -}} + {{- fail (printf "github-instance label value is not a valid Kubernetes label value: %q — must start and end with alphanumeric, set githubInstanceHostname to a valid value" $githubInstance) -}} + {{- end }} + repo-guard.cloudoperators.dev/github-instance: "{{ $githubInstance }}" + {{- $githubInstanceKey := $org.githubInstanceKey | default $org.github -}} + {{- if gt (len $githubInstanceKey) 63 -}} + {{- fail (printf "github-instance-key label value exceeds 63 characters (got %d): %q — set githubInstanceKey to a shorter value" (len $githubInstanceKey) $githubInstanceKey) -}} + {{- end -}} + {{- if and $githubInstanceKey (not (regexMatch "^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$" $githubInstanceKey)) -}} + {{- fail (printf "github-instance-key label value is not a valid Kubernetes label value: %q — must start and end with alphanumeric, set githubInstanceKey to a valid value" $githubInstanceKey) -}} + {{- end }} + repo-guard.cloudoperators.dev/github-instance-key: "{{ $githubInstanceKey }}" + {{- $defaultLdapProvider := $org.defaultLdapProvider | default "" -}} + {{- if gt (len $defaultLdapProvider) 63 -}} + {{- fail (printf "default-ldap-provider label value exceeds 63 characters (got %d): %q — set defaultLdapProvider to a shorter value" (len $defaultLdapProvider) $defaultLdapProvider) -}} + {{- end -}} + {{- if and $defaultLdapProvider (not (regexMatch "^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$" $defaultLdapProvider)) -}} + {{- fail (printf "default-ldap-provider label value is not a valid Kubernetes label value: %q — must start and end with alphanumeric, set defaultLdapProvider to a valid value" $defaultLdapProvider) -}} + {{- end }} + repo-guard.cloudoperators.dev/default-ldap-provider: "{{ $defaultLdapProvider }}" + {{- if and (hasKey $org "adminPermission") (not (kindIs "string" $org.adminPermission)) -}} + {{- fail (printf "githubOrganizations[].adminPermission must be a string (\"admin\" or \"admin-ondemand\"), got %v" $org.adminPermission) -}} + {{- end -}} + {{- if and (hasKey $org "adminPermission") (kindIs "string" $org.adminPermission) (not (or (eq $org.adminPermission "admin") (eq $org.adminPermission "admin-ondemand"))) -}} + {{- fail (printf "githubOrganizations[].adminPermission must be \"admin\" or \"admin-ondemand\", got %q" $org.adminPermission) -}} + {{- end -}} + {{- $adminPermission := $org.adminPermission | default "admin" }} + repo-guard.cloudoperators.dev/admin-permission: "{{ $adminPermission }}" {{- $skipTeams := join "," $org.skipDefaultRepositoryTeams }} {{- if $skipTeams }} annotations: diff --git a/charts/repo-guard/values.yaml b/charts/repo-guard/values.yaml index 3ba253cb..bcd3e12a 100644 --- a/charts/repo-guard/values.yaml +++ b/charts/repo-guard/values.yaml @@ -132,6 +132,20 @@ perses: # # removeRepositoryDirectCollaborator. Typically includes bot accounts and the GitHub App user. # protectedMembers: [] # disableInternalUsernames: +# # Operational labels consumed by Permission Manager for org lookup and team creation. +# # githubInstanceHostname: GitHub hostname PM uses as a label selector to find this org CR from a CCRN instance segment. +# # Defaults to the webURL of the matching githubs[] entry. Override only if the webURL is not set or a different value is needed. +# githubInstanceHostname: +# # githubInstanceKey: short key PM uses as the prefix in CR names (----). +# # Defaults to the 'github' field value (the Github CR name), which matches how Helm names GithubOrganization CRs. +# # WARNING: overriding this value causes the label to advertise a prefix that differs from the one Helm uses when +# # naming GithubOrganization, GithubTeam, and GithubTeamRepository CRs (all of which are prefixed with $org.github). +# # Only override if you are also renaming those CRs to match. +# githubInstanceKey: +# # defaultLdapProvider: written by PM into spec.externalMemberProvider.ldap.provider on GithubTeams it creates for this org +# defaultLdapProvider: +# # adminPermission: "admin" or "admin-ondemand"; PM maps ADMIN role to this value (default: admin) +# adminPermission: admin # # GithubAccountLink email verification settings applied to all GALs # # associated with this GitHub (organization-level policy). # # When set, the Helm chart will populate a JSON annotation on each diff --git a/docs/operations/labels.md b/docs/operations/labels.md index 8be5bc70..b57da24d 100644 --- a/docs/operations/labels.md +++ b/docs/operations/labels.md @@ -21,6 +21,17 @@ Labels control the behavior of Repo Guard controllers. All labels live under `me | `repo-guard.cloudoperators.dev/failedTTL` | Go duration (e.g. `1h`, `30m`) | Clears failed operations and failed status after the duration since last status timestamp. | Not set | | `repo-guard.cloudoperators.dev/completedTTL` | Go duration (e.g. `24h`) | Clears completed operations after the duration since last status timestamp. | Not set | +**Operational labels (read by Permission Manager):** + +These labels are set automatically by the Helm chart and are not intended to control reconciler behaviour. They allow Permission Manager to locate a `GithubOrganization` CR via label selectors and read org-level config without parsing `spec` fields. + +| Key | Description | Default (Helm) | +|---|---|---| +| `repo-guard.cloudoperators.dev/github-instance` | GitHub hostname (e.g. `github.com`, `github.wdf.sap.corp`). PM uses this as a label selector to find the org CR from a CCRN instance segment (the `` path component, which is the full hostname). Derived from `githubs[].webURL` of the matching entry (scheme, port, and path stripped — e.g. `https://host:8080/base/` → `host`); override via `githubInstanceHostname` in Helm values. Must be a valid Kubernetes label value (≤ 63 chars, starts and ends with alphanumeric). | `githubs[].webURL` (scheme, port, and path stripped) for the matching `github` key | +| `repo-guard.cloudoperators.dev/github-instance-key` | Short key PM uses as the naming prefix in repo-guard's `----` CR convention. Defaults to `spec.github` (the `Github` CR name), which is the same prefix the Helm chart uses when naming `GithubOrganization` CRs. Override via `githubInstanceKey` in Helm values. | `spec.github` value (the `Github` CR name) | +| `repo-guard.cloudoperators.dev/default-ldap-provider` | LDAP provider name PM writes into `spec.externalMemberProvider.ldap.provider` on each `GithubTeam` it creates for this org. Empty string when not set. | `""` | +| `repo-guard.cloudoperators.dev/admin-permission` | Permission string PM uses when mapping the `ADMIN` role for this org. Either `"admin"` or `"admin-ondemand"`. | `"admin"` | + **Annotation:** | Key | Description |