From 0c97502f0dd45a7b99f020ca2cb81d7345c4455c Mon Sep 17 00:00:00 2001 From: day0hero Date: Tue, 14 Apr 2026 12:01:57 +0100 Subject: [PATCH] GroupSync/oAuth configuration --- charts/all/groupsync/Chart.yaml | 9 +++++ .../templates/eso-github-groupsync.yaml | 40 +++++++++++++++++++ charts/all/groupsync/templates/groupsync.yaml | 29 ++++++++++++++ charts/all/groupsync/values.yaml | 21 ++++++++++ .../rbac/hcp-admin-crolebinding.yaml | 5 +++ charts/all/hypershift/values.yaml | 3 +- charts/all/oauth/templates/oauth.yaml | 19 ++++++++- charts/all/oauth/values.yaml | 8 +++- values-hypershift.yaml | 32 +++++++++++---- values-prod.yaml | 18 ++++++++- 10 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 charts/all/groupsync/Chart.yaml create mode 100644 charts/all/groupsync/templates/eso-github-groupsync.yaml create mode 100644 charts/all/groupsync/templates/groupsync.yaml create mode 100644 charts/all/groupsync/values.yaml diff --git a/charts/all/groupsync/Chart.yaml b/charts/all/groupsync/Chart.yaml new file mode 100644 index 00000000..03d6f1a1 --- /dev/null +++ b/charts/all/groupsync/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: groupsync +description: A Helm chart for configuring the Group Sync Operator with GitHub + +type: application + +version: 0.1.0 + +appVersion: "0.1.0" diff --git a/charts/all/groupsync/templates/eso-github-groupsync.yaml b/charts/all/groupsync/templates/eso-github-groupsync.yaml new file mode 100644 index 00000000..efc8267b --- /dev/null +++ b/charts/all/groupsync/templates/eso-github-groupsync.yaml @@ -0,0 +1,40 @@ +{{- $cg := .Values.clusterGroup | default dict }} +{{- $apps := $cg.applications | default dict }} +{{- $gs := index $apps "groupsync" | default dict }} +{{- if not ($gs.disabled | default false) }} +{{- $vaultKey := .Values.global.groupsync.githubAppKeyPath | default .Values.githubAppKeyPath | default "secret/data/hub/githubGroupSync" }} +--- +apiVersion: "external-secrets.io/v1beta1" +kind: ExternalSecret +metadata: + name: {{ .Values.global.groupsync.secretName }} + namespace: group-sync-operator + annotations: + argocd.argoproj.io/sync-wave: '10' +spec: + refreshInterval: 15s + secretStoreRef: + name: {{ .Values.secretStore.name }} + kind: {{ .Values.secretStore.kind }} + target: + name: {{ .Values.global.groupsync.github.credentialsSecretName }} + creationPolicy: Owner + # group-sync-operator GitHub provider: keys must be `appId` (GitHub *App* numeric ID from + # the app's settings page, not org installation ID) and PEM `privateKey`. Installation is resolved via API. + template: + type: Opaque + data: + appId: |- + {{ "{{ .appId | trim }}" }} + privateKey: |- + {{ "{{ .privateKey }}" }} + data: + - secretKey: appId + remoteRef: + key: {{ $vaultKey }} + property: appId + - secretKey: privateKey + remoteRef: + key: {{ $vaultKey }} + property: privateKey +{{- end }} diff --git a/charts/all/groupsync/templates/groupsync.yaml b/charts/all/groupsync/templates/groupsync.yaml new file mode 100644 index 00000000..803bd1ff --- /dev/null +++ b/charts/all/groupsync/templates/groupsync.yaml @@ -0,0 +1,29 @@ +{{- $cg := .Values.clusterGroup | default dict }} +{{- $apps := $cg.applications | default dict }} +{{- $gs := index $apps "groupsync" | default dict }} +{{- if not ($gs.disabled | default false) }} +apiVersion: redhatcop.redhat.io/v1alpha1 +kind: GroupSync +metadata: + name: github-groupsync + annotations: + argocd.argoproj.io/sync-wave: '15' +spec: + schedule: "*/30 * * * *" + providers: +{{- range .Values.global.github.orgs }} + - name: {{ .name }} + github: + credentialsSecret: + name: {{ $.Values.global.groupsync.github.credentialsSecretName }} + namespace: group-sync-operator + url: {{ $.Values.global.groupsync.github.url }} + organization: {{ .name }} +{{- if .teams }} + teams: +{{- range .teams }} + - {{ . }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/all/groupsync/values.yaml b/charts/all/groupsync/values.yaml new file mode 100644 index 00000000..5b1aa083 --- /dev/null +++ b/charts/all/groupsync/values.yaml @@ -0,0 +1,21 @@ +secretStore: + name: vault-backend + kind: ClusterSecretStore + +# Templates render when clusterGroup.applications.groupsync.disabled is false (or unset). +clusterGroup: + applications: + groupsync: + disabled: false + +global: + github: + orgs: + - name: # GitHub organization to sync groups from + groupsync: + secretName: github-group-sync + # Vault KV path for GitHub App creds (vault_utils secret name githubGroupSync → default below). + githubAppKeyPath: "" + github: + credentialsSecretName: github-group-sync + url: https://api.github.com diff --git a/charts/all/hypershift/templates/rbac/hcp-admin-crolebinding.yaml b/charts/all/hypershift/templates/rbac/hcp-admin-crolebinding.yaml index 730070c9..8e92aa34 100644 --- a/charts/all/hypershift/templates/rbac/hcp-admin-crolebinding.yaml +++ b/charts/all/hypershift/templates/rbac/hcp-admin-crolebinding.yaml @@ -14,4 +14,9 @@ subjects: kind: User name: {{ . }} {{- end }} +{{- range .Values.rbac.groups }} +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: {{ . }} +{{- end }} {{- end }} diff --git a/charts/all/hypershift/values.yaml b/charts/all/hypershift/values.yaml index 554263d1..360c901a 100644 --- a/charts/all/hypershift/values.yaml +++ b/charts/all/hypershift/values.yaml @@ -57,7 +57,7 @@ autoscaling: # Role Based Access Controls # -# Provide a list of users to add to the clusterrolebinding +# Provide a list of users and/or groups to add to the clusterrolebinding rbac: create: true role: @@ -65,6 +65,7 @@ rbac: roleBinding: name: hcp-admins-crb users: [] + groups: [] clusterGroup: isHubCluster: true diff --git a/charts/all/oauth/templates/oauth.yaml b/charts/all/oauth/templates/oauth.yaml index 951c7677..f950f238 100644 --- a/charts/all/oauth/templates/oauth.yaml +++ b/charts/all/oauth/templates/oauth.yaml @@ -8,9 +8,26 @@ spec: clientID: {{ .Values.global.oauth.github.clientID }} clientSecret: name: {{ .Values.global.oauth.secretName }} +{{- $teams := list }} +{{- range .Values.global.github.orgs }} +{{- $orgName := .name }} +{{- range .teams }} +{{- if . }} +{{- $teams = append $teams (printf "%s/%s" $orgName .) }} +{{- end }} +{{- end }} +{{- end }} +{{- /* OpenShift allows organizations or teams on GitHub IdP, never both */}} +{{- if $teams }} + teams: +{{- range $teams }} + - {{ . }} +{{- end }} +{{- else }} organizations: -{{- range .Values.global.oauth.github.orgs }} +{{- range .Values.global.github.orgs }} - {{ .name }} +{{- end }} {{- end }} mappingMethod: claim name: github diff --git a/charts/all/oauth/values.yaml b/charts/all/oauth/values.yaml index a6a8d095..fd7239ba 100644 --- a/charts/all/oauth/values.yaml +++ b/charts/all/oauth/values.yaml @@ -12,6 +12,12 @@ secretStore: # Then update the GitHub accessKey, populate the vault with the secret, and update the list of org names # global: + github: + orgs: + - name: #list of organization names that are authorized with oauth + # If non-empty, OAuth restricts login to these org/team pairs (OpenShift forbids + # setting both organizations and teams). If empty, OAuth uses organizations only. + teams: [] # e.g. [my-team] becomes org/my-team for GitHub IdP teams oauth: enabled: #True to enable the customization of oauth, false to use cluster deployed secretName: #Name of the secret to be generated with appropriate credentials @@ -19,5 +25,3 @@ global: # if GitHub provide the following values github: clientID: #retrieve from github oauth application - orgs: - - name: #list of organization names that are authorized with oauth diff --git a/values-hypershift.yaml b/values-hypershift.yaml index 24d9dfdf..0d7cf2ce 100644 --- a/values-hypershift.yaml +++ b/values-hypershift.yaml @@ -5,8 +5,17 @@ global: createBucket: true oidc: # OIDC bucket information: provide region and bucketName - region: "" - bucketName: "" + region: '' + bucketName: '' + +# GitHub organization(s) — shared by oauth and group-sync + github: + orgs: + - name: 'github-org-name' + # Teams: Group Sync uses them for OpenShift groups. OAuth uses org/team slugs + # for login when this list is non-empty; otherwise OAuth allows the whole org. + # Team names are case-sensitive and must match GitHub exactly, including hyphens. For example: Engineering, not engineering + teams: [] # register a GitHub oAuth application: https://github.com/settings/applications/new # configure oauth provider: https://docs.openshift.com/container-platform/4.15/authentication/understanding-identity-provider.html @@ -16,9 +25,16 @@ global: type: GitHub secretName: ocp-github-oauth github: - clientID: #clientID of the registered GitHub oAuth Application - orgs: - - name: #list of github authorized organizations + clientID: 'github-app-client-id' + +# Group Sync Operator — syncs GitHub teams to OpenShift groups. +# Vault secret githubGroupSync: `appId` = GitHub App ID (settings/apps → About), not installation ID; +# `privateKey` = app PEM. The operator resolves org installation from `global.github.orgs[].name`. + groupsync: + secretName: github-group-sync + github: + credentialsSecretName: github-group-sync + url: https://api.github.com/ # Cluster Autoscaling Configuration # Enable autoscaling to automatically adjust cluster size based on workload demands @@ -54,10 +70,12 @@ autoscaling: # enabled: true # machineSetName: -worker- # minReplicas: 0 - # maxReplicas: 6 + # maxReplicas: 6 # Set rbac.create to false if you want to skip creation of role/rolebinding. rbac: create: false -# Provide a list of users to add to the clusterrolebinding +# Provide a list of users and/or groups to add to the clusterrolebinding +# Group and user names must match GitHub exactly, including hyphens. For example: Engineering, not engineering users: [] + groups: [] diff --git a/values-prod.yaml b/values-prod.yaml index cbbe652a..6bba367a 100644 --- a/values-prod.yaml +++ b/values-prod.yaml @@ -8,13 +8,20 @@ clusterGroup: - vault - golang-external-secrets - multicluster-engine + - group-sync-operator subscriptions: mce: name: multicluster-engine namespace: multicluster-engine - channel: stable-2.10 - + channel: stable-2.11 + + groupsync: + name: group-sync-operator + namespace: group-sync-operator + source: community-operators + channel: alpha + projects: - hub - hypershift @@ -48,6 +55,13 @@ clusterGroup: project: hub path: charts/all/oauth + groupsync: + disabled: false + name: groupsync + namespace: group-sync-operator + project: hub + path: charts/all/groupsync + imperative: # NOTE: We *must* use lists and not hashes. As hashes lose ordering once parsed by helm # The default schedule is every 10 minutes: imperative.schedule