Skip to content

Commit 485278a

Browse files
svorclaude
andcommitted
feat: Add user-provided secret support and rename credential keys
Rename secret keys to be more descriptive (e.g. user→db-user, userPAT→publisher-token). Add OpenVSXSecret field to allow users to provide their own credentials secret. Make JDBC database name configurable via PGDATABASE env var instead of hardcoded value. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c427c84 commit 485278a

16 files changed

Lines changed: 315 additions & 51 deletions

api/v2/checluster_types.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,19 @@ type OpenVSXServer struct {
481481
// Database configuration for OpenVSX.
482482
// +k8s:openapi-gen=true
483483
type OpenVSXDatabase struct {
484+
// The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
485+
// and registry users. When specified, the operator uses this secret instead of auto-generating one.
486+
// The secret must contain the following keys:
487+
// - `db-user`: PostgreSQL username.
488+
// - `db-password`: PostgreSQL password.
489+
// - `db-name`: PostgreSQL database name.
490+
// - `publisher-name`: OpenVSX publisher account login name used to publish extensions.
491+
// - `publisher-token`: Personal access token for the publisher account.
492+
// - `admin-name`: OpenVSX admin account login name.
493+
// - `admin-token`: Personal access token for the admin account.
494+
// If omitted, the operator creates a secret with auto-generated random values.
495+
// +optional
496+
OpenVSXSecret string `json:"openVSXSecret,omitempty"`
484497
// Deployment override options.
485498
// +optional
486499
Deployment *Deployment `json:"deployment,omitempty"`

bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ metadata:
8686
categories: Developer Tools
8787
certified: "false"
8888
containerImage: quay.io/eclipse/che-operator:next
89-
createdAt: "2026-06-12T17:18:53Z"
89+
createdAt: "2026-06-16T12:46:18Z"
9090
description: A Kube-native development solution that delivers portable and collaborative
9191
developer workspaces.
9292
features.operators.openshift.io/cnf: "false"
@@ -108,7 +108,7 @@ metadata:
108108
operatorframework.io/arch.amd64: supported
109109
operatorframework.io/arch.arm64: supported
110110
operatorframework.io/os.linux: supported
111-
name: eclipse-che.v7.119.0-1019.next
111+
name: eclipse-che.v7.119.0-1020.next
112112
namespace: placeholder
113113
spec:
114114
apiservicedefinitions: {}
@@ -1166,7 +1166,7 @@ spec:
11661166
name: openvsx
11671167
- image: quay.io/sclorg/postgresql-16-c9s:20260319
11681168
name: openvsx-postgres
1169-
version: 7.119.0-1019.next
1169+
version: 7.119.0-1020.next
11701170
webhookdefinitions:
11711171
- admissionReviewVersions:
11721172
- v1

bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14707,6 +14707,20 @@ spec:
1470714707
type: object
1470814708
type: array
1470914709
type: object
14710+
openVSXSecret:
14711+
description: |-
14712+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14713+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14714+
The secret must contain the following keys:
14715+
- `db-user`: PostgreSQL username.
14716+
- `db-password`: PostgreSQL password.
14717+
- `db-name`: PostgreSQL database name.
14718+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14719+
- `publisher-token`: Personal access token for the publisher account.
14720+
- `admin-name`: OpenVSX admin account login name.
14721+
- `admin-token`: Personal access token for the admin account.
14722+
If omitted, the operator creates a secret with auto-generated random values.
14723+
type: string
1471014724
pvc:
1471114725
description: PVC settings for PostgreSQL data.
1471214726
properties:

config/crd/bases/org.eclipse.che_checlusters.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14627,6 +14627,20 @@ spec:
1462714627
type: object
1462814628
type: array
1462914629
type: object
14630+
openVSXSecret:
14631+
description: |-
14632+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14633+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14634+
The secret must contain the following keys:
14635+
- `db-user`: PostgreSQL username.
14636+
- `db-password`: PostgreSQL password.
14637+
- `db-name`: PostgreSQL database name.
14638+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14639+
- `publisher-token`: Personal access token for the publisher account.
14640+
- `admin-name`: OpenVSX admin account login name.
14641+
- `admin-token`: Personal access token for the admin account.
14642+
If omitted, the operator creates a secret with auto-generated random values.
14643+
type: string
1463014644
pvc:
1463114645
description: PVC settings for PostgreSQL data.
1463214646
properties:

deploy/deployment/kubernetes/combined.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14648,6 +14648,20 @@ spec:
1464814648
type: object
1464914649
type: array
1465014650
type: object
14651+
openVSXSecret:
14652+
description: |-
14653+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14654+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14655+
The secret must contain the following keys:
14656+
- `db-user`: PostgreSQL username.
14657+
- `db-password`: PostgreSQL password.
14658+
- `db-name`: PostgreSQL database name.
14659+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14660+
- `publisher-token`: Personal access token for the publisher account.
14661+
- `admin-name`: OpenVSX admin account login name.
14662+
- `admin-token`: Personal access token for the admin account.
14663+
If omitted, the operator creates a secret with auto-generated random values.
14664+
type: string
1465114665
pvc:
1465214666
description: PVC settings for PostgreSQL data.
1465314667
properties:

deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14643,6 +14643,20 @@ spec:
1464314643
type: object
1464414644
type: array
1464514645
type: object
14646+
openVSXSecret:
14647+
description: |-
14648+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14649+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14650+
The secret must contain the following keys:
14651+
- `db-user`: PostgreSQL username.
14652+
- `db-password`: PostgreSQL password.
14653+
- `db-name`: PostgreSQL database name.
14654+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14655+
- `publisher-token`: Personal access token for the publisher account.
14656+
- `admin-name`: OpenVSX admin account login name.
14657+
- `admin-token`: Personal access token for the admin account.
14658+
If omitted, the operator creates a secret with auto-generated random values.
14659+
type: string
1464614660
pvc:
1464714661
description: PVC settings for PostgreSQL data.
1464814662
properties:

deploy/deployment/openshift/combined.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14648,6 +14648,20 @@ spec:
1464814648
type: object
1464914649
type: array
1465014650
type: object
14651+
openVSXSecret:
14652+
description: |-
14653+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14654+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14655+
The secret must contain the following keys:
14656+
- `db-user`: PostgreSQL username.
14657+
- `db-password`: PostgreSQL password.
14658+
- `db-name`: PostgreSQL database name.
14659+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14660+
- `publisher-token`: Personal access token for the publisher account.
14661+
- `admin-name`: OpenVSX admin account login name.
14662+
- `admin-token`: Personal access token for the admin account.
14663+
If omitted, the operator creates a secret with auto-generated random values.
14664+
type: string
1465114665
pvc:
1465214666
description: PVC settings for PostgreSQL data.
1465314667
properties:

deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14643,6 +14643,20 @@ spec:
1464314643
type: object
1464414644
type: array
1464514645
type: object
14646+
openVSXSecret:
14647+
description: |-
14648+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14649+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14650+
The secret must contain the following keys:
14651+
- `db-user`: PostgreSQL username.
14652+
- `db-password`: PostgreSQL password.
14653+
- `db-name`: PostgreSQL database name.
14654+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14655+
- `publisher-token`: Personal access token for the publisher account.
14656+
- `admin-name`: OpenVSX admin account login name.
14657+
- `admin-token`: Personal access token for the admin account.
14658+
If omitted, the operator creates a secret with auto-generated random values.
14659+
type: string
1464614660
pvc:
1464714661
description: PVC settings for PostgreSQL data.
1464814662
properties:

helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14643,6 +14643,20 @@ spec:
1464314643
type: object
1464414644
type: array
1464514645
type: object
14646+
openVSXSecret:
14647+
description: |-
14648+
The value can be the name of a Kubernetes Secret that contains credentials for the OpenVSX database
14649+
and registry users. When specified, the operator uses this secret instead of auto-generating one.
14650+
The secret must contain the following keys:
14651+
- `db-user`: PostgreSQL username.
14652+
- `db-password`: PostgreSQL password.
14653+
- `db-name`: PostgreSQL database name.
14654+
- `publisher-name`: OpenVSX publisher account login name used to publish extensions.
14655+
- `publisher-token`: Personal access token for the publisher account.
14656+
- `admin-name`: OpenVSX admin account login name.
14657+
- `admin-token`: Personal access token for the admin account.
14658+
If omitted, the operator creates a secret with auto-generated random values.
14659+
type: string
1464614660
pvc:
1464714661
description: PVC settings for PostgreSQL data.
1464814662
properties:

pkg/deploy/openvsx/database/openvsx_database.go

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ package database
1515
import (
1616
"context"
1717

18+
"fmt"
19+
1820
"github.com/eclipse-che/che-operator/pkg/common/chetypes"
1921
"github.com/eclipse-che/che-operator/pkg/common/constants"
2022
defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults"
@@ -23,6 +25,7 @@ import (
2325
"github.com/eclipse-che/che-operator/pkg/deploy"
2426
appsv1 "k8s.io/api/apps/v1"
2527
corev1 "k8s.io/api/core/v1"
28+
2629
"k8s.io/apimachinery/pkg/api/errors"
2730
"k8s.io/apimachinery/pkg/api/resource"
2831
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -51,7 +54,9 @@ func (p *OpenVSXDatabaseReconciler) Reconcile(ctx *chetypes.DeployContext) (reco
5154
_ = cw.DeleteByKeyIgnoreNotFound(context.TODO(), types.NamespacedName{Name: constants.OpenVSXDatabaseName, Namespace: ns}, &appsv1.Deployment{})
5255
_ = cw.DeleteByKeyIgnoreNotFound(context.TODO(), types.NamespacedName{Name: constants.OpenVSXDatabaseName, Namespace: ns}, &corev1.Service{})
5356
_ = cw.DeleteByKeyIgnoreNotFound(context.TODO(), types.NamespacedName{Name: pvcName, Namespace: ns}, &corev1.PersistentVolumeClaim{})
54-
_ = cw.DeleteByKeyIgnoreNotFound(context.TODO(), types.NamespacedName{Name: constants.OpenVSXDatabaseCredentialsSecret, Namespace: ns}, &corev1.Secret{})
57+
if !isUserProvidedSecret(ctx) {
58+
_ = cw.DeleteByKeyIgnoreNotFound(context.TODO(), types.NamespacedName{Name: constants.OpenVSXDatabaseCredentialsSecret, Namespace: ns}, &corev1.Secret{})
59+
}
5560
return reconcile.Result{}, true, nil
5661
}
5762

@@ -82,50 +87,90 @@ func (p *OpenVSXDatabaseReconciler) Finalize(ctx *chetypes.DeployContext) bool {
8287
return true
8388
}
8489

90+
var requiredSecretKeys = []string{
91+
"db-user", "db-password", "db-name",
92+
"publisher-name", "publisher-token",
93+
"admin-name", "admin-token",
94+
}
95+
8596
func (p *OpenVSXDatabaseReconciler) syncSecret(ctx *chetypes.DeployContext) (bool, error) {
97+
secretName := GetCredentialsSecretName(ctx)
98+
8699
secret := &corev1.Secret{}
87100
err := ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{
88-
Name: constants.OpenVSXDatabaseCredentialsSecret,
101+
Name: secretName,
89102
Namespace: ctx.CheCluster.Namespace,
90103
}, secret)
91104

92105
if err == nil {
106+
if isUserProvidedSecret(ctx) {
107+
return validateSecretKeys(secret)
108+
}
93109
return true, nil
94110
}
95111

96112
if !errors.IsNotFound(err) {
97113
return false, err
98114
}
99115

116+
if isUserProvidedSecret(ctx) {
117+
return false, fmt.Errorf("credentials secret '%s' not found", secretName)
118+
}
119+
100120
secret = &corev1.Secret{
101121
TypeMeta: metav1.TypeMeta{
102122
Kind: "Secret",
103123
APIVersion: "v1",
104124
},
105125
ObjectMeta: metav1.ObjectMeta{
106-
Name: constants.OpenVSXDatabaseCredentialsSecret,
126+
Name: secretName,
107127
Namespace: ctx.CheCluster.Namespace,
108128
Labels: deploy.GetLabels(defaults.GetCheFlavor()),
109129
},
110130
Type: corev1.SecretTypeOpaque,
111131
Data: map[string][]byte{
112-
"user": []byte("openvsx"),
113-
"password": []byte(utils.GeneratePassword(16)),
114-
"database": []byte("openvsx"),
115-
"userName": []byte("eclipse-che"),
116-
"userPAT": []byte(utils.GeneratePassword(32)),
117-
"adminName": []byte("openvsx-admin"),
118-
"adminPAT": []byte(utils.GeneratePassword(32)),
132+
"db-user": []byte("openvsx"),
133+
"db-password": []byte(utils.GeneratePassword(16)),
134+
"db-name": []byte("openvsx"),
135+
"publisher-name": []byte("eclipse-che"),
136+
"publisher-token": []byte(utils.GeneratePassword(32)),
137+
"admin-name": []byte("openvsx-admin"),
138+
"admin-token": []byte(utils.GeneratePassword(32)),
119139
},
120140
}
121141

122142
if err := controllerutil.SetControllerReference(ctx.CheCluster, secret, ctx.ClusterAPI.Scheme); err != nil {
123143
return false, err
124144
}
125-
err = ctx.ClusterAPI.ClientWrapper.Sync(context.TODO(), secret)
145+
err = ctx.ClusterAPI.ClientWrapper.Sync(context.TODO(), secret)
126146
return err == nil, err
127147
}
128148

149+
func validateSecretKeys(secret *corev1.Secret) (bool, error) {
150+
var missing []string
151+
for _, key := range requiredSecretKeys {
152+
if _, ok := secret.Data[key]; !ok {
153+
missing = append(missing, key)
154+
}
155+
}
156+
if len(missing) > 0 {
157+
return false, fmt.Errorf("credentials secret '%s' is missing required keys: %v", secret.Name, missing)
158+
}
159+
return true, nil
160+
}
161+
162+
func isUserProvidedSecret(ctx *chetypes.DeployContext) bool {
163+
return ctx.CheCluster.Spec.Components.OpenVSX.OpenVSXDatabase != nil &&
164+
ctx.CheCluster.Spec.Components.OpenVSX.OpenVSXDatabase.OpenVSXSecret != ""
165+
}
166+
167+
func GetCredentialsSecretName(ctx *chetypes.DeployContext) string {
168+
if isUserProvidedSecret(ctx) {
169+
return ctx.CheCluster.Spec.Components.OpenVSX.OpenVSXDatabase.OpenVSXSecret
170+
}
171+
return constants.OpenVSXDatabaseCredentialsSecret
172+
}
173+
129174
func (p *OpenVSXDatabaseReconciler) syncService(ctx *chetypes.DeployContext) (bool, error) {
130175
return deploy.SyncServiceToCluster(
131176
ctx,

0 commit comments

Comments
 (0)