🌱 Add CertRotationController support for PlacementDebugServer TLS (#1494)

* Add service-CA certificate support for PlacementDebugServer

When the PlacementDebugServer feature gate is enabled, inject a
serving-cert annotation into the placement service and mount the
resulting TLS secret into the debug-server container. On OpenShift,
the service-serving-cert controller creates a CA-signed certificate
automatically. On non-OpenShift, optional: true allows the pod to
start and library-go falls back to self-signed certificates.

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Rename fields to PlacementAnnotations and PlacementServingCertSecret

Scope field names to Placement per review feedback, since these
are only used for the placement service and extending to other
services would require separate fields.

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Replace OCP annotation with CertRotationController for PlacementDebugServer TLS

Replaces the OpenShift-specific serving-cert-secret-name annotation with the
OCM-native CertRotationController to provision the PlacementDebugServer's TLS
serving certificate. Follows the existing GRPC conditional target pattern:
the placement-debug-serving-cert target is added/removed based on the
PlacementDebugServer feature gate.

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix misleading error messages and import ordering

Correct error messages in feature-disabled cleanup paths to accurately
state the operation (secret deletion with feature disabled) instead of
implying a deleted ClusterManager. Also move ocmfeature import into the
open-cluster-management.io group where it belongs.

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix RBAC and gofmt for PlacementDebugServer cert rotation

Add placement-debug-serving-cert to the cluster-manager ClusterRole
resourceNames allowlist and fix gofmt alignment in two files.

Root cause of E2E failures: the certRotationController attempts to
delete the placement-debug-serving-cert secret when the feature gate
is disabled (the default). The operator ClusterRole restricts secret
delete/get/update/patch to an explicit resourceNames list. Because
placement-debug-serving-cert was not in that list, the delete call
returned 403 Forbidden — not 404 NotFound. The error handler in
syncOne() only ignores IsNotFound, so 403 caused an early return
before the signing CA and ca-bundle-configmap were ever created.
The clusterManagerController.sync() blocks at line 312 waiting for
ca-bundle-configmap to appear, so ObservedGeneration was never set,
and all four E2E suites timed out in BeforeSuite after 150 seconds.

The gofmt failures were cosmetic: extra alignment spaces in the
PlacementDebugServingCertSecret/PlacementDebugService const block
and the PlacementDebugServerEnabled/PlacementServingCertSecret
struct fields.

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* retrigger CI

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>

* retrigger CI

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>

---------

Signed-off-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-authored-by: Randy Bruno Piverger <21374229+Randy424@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Randy Bruno Piverger
2026-05-14 18:53:10 -07:00
committed by GitHub
parent 82543fbdf2
commit a5c22a2bfd
10 changed files with 252 additions and 22 deletions

View File

@@ -36,6 +36,7 @@ rules:
- "work-driver-config"
- "open-cluster-management-image-pull-credentials"
- "grpc-server-serving-cert"
- "placement-debug-serving-cert"
- "cluster-import-config"
- apiGroups: [""]
resources: ["secrets"]

View File

@@ -38,6 +38,7 @@ rules:
- "work-driver-config"
- "open-cluster-management-image-pull-credentials"
- "grpc-server-serving-cert"
- "placement-debug-serving-cert"
- "cluster-import-config"
- apiGroups: [""]
resources: ["secrets"]

View File

@@ -171,10 +171,22 @@ spec:
volumeMounts:
- name: tmpdir
mountPath: /tmp
{{- if .PlacementServingCertSecret }}
- name: serving-cert
mountPath: /var/run/secrets/serving-cert
readOnly: true
{{- end }}
{{ end }}
volumes:
- name: tmpdir
emptyDir: { }
{{- if .PlacementServingCertSecret }}
- name: serving-cert
secret:
secretName: {{ .PlacementServingCertSecret }}
defaultMode: 420
optional: true
{{- end }}
{{ if .HostedMode }}
- name: kubeconfig
secret:

View File

@@ -14,6 +14,7 @@ type HubConfig struct {
WorkAPIServiceCABundle string
PlacementImage string
PlacementDebugServerEnabled bool
PlacementServingCertSecret string
AddonAPIServiceCABundle string
Replica int32
HostedMode bool

View File

@@ -39,6 +39,7 @@ import (
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
apiregistrationclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1"
ocmfeature "open-cluster-management.io/api/feature"
operatorapiv1 "open-cluster-management.io/api/operator/v1"
"open-cluster-management.io/sdk-go/pkg/basecontroller/events"
@@ -915,6 +916,17 @@ func AddLabelsToYaml(objData []byte, cmLabels map[string]string) ([]byte, error)
return modifiedYAML, nil
}
func PlacementDebugServerEnabled(cm *operatorapiv1.ClusterManager) bool {
if cm.Spec.PlacementConfiguration == nil {
return false
}
return FeatureGateEnabled(
cm.Spec.PlacementConfiguration.FeatureGates,
ocmfeature.DefaultHubPlacementFeatureGates,
ocmfeature.PlacementDebugServer,
)
}
func GRPCAuthEnabled(cm *operatorapiv1.ClusterManager) bool {
if cm.Spec.RegistrationConfiguration == nil {
return false

View File

@@ -48,6 +48,9 @@ const (
CaBundleConfigmap = "ca-bundle-configmap"
GRPCServerSecret = "grpc-server-serving-cert" //#nosec G101
PlacementDebugServingCertSecret = "placement-debug-serving-cert" //#nosec G101
PlacementDebugService = "cluster-manager-placement"
)
func ClusterManagerNamespace(clustermanagername string, mode operatorapiv1.InstallMode) string {

View File

@@ -82,7 +82,8 @@ func NewCertRotationController(
secretInformers[helpers.RegistrationWebhookSecret].Informer(),
secretInformers[helpers.WorkWebhookSecret].Informer(),
secretInformers[helpers.AddonWebhookSecret].Informer(),
secretInformers[helpers.GRPCServerSecret].Informer()).
secretInformers[helpers.GRPCServerSecret].Informer(),
secretInformers[helpers.PlacementDebugServingCertSecret].Informer()).
ToController("CertRotationController")
}
@@ -178,6 +179,12 @@ func (c certRotationController) syncOne(ctx context.Context, clustermanager *ope
return fmt.Errorf("clean up deleted cluster-manager, deleting grpc server secret failed, err:%s", err.Error())
}
// delete placement debug serving secret
err = c.kubeClient.CoreV1().Secrets(clustermanagerNamespace).Delete(ctx, helpers.PlacementDebugServingCertSecret, metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("clean up deleted cluster-manager, deleting placement debug serving secret failed, err:%s", err.Error())
}
delete(c.rotationMap, clustermanagerName)
}
return nil
@@ -191,6 +198,18 @@ func (c certRotationController) syncOne(ctx context.Context, clustermanager *ope
return err
}
// delete the placement debug serving secret if the feature is disabled
if !helpers.PlacementDebugServerEnabled(clustermanager) {
if _, ok := c.rotationMap[clustermanager.Name]; ok {
delete(c.rotationMap[clustermanager.Name].targetRotations, helpers.PlacementDebugServingCertSecret)
}
err = c.kubeClient.CoreV1().Secrets(clustermanagerNamespace).Delete(ctx, helpers.PlacementDebugServingCertSecret, metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("failed to delete secret %q for cluster-manager %q: PlacementDebugServer feature disabled, err: %v", helpers.PlacementDebugServingCertSecret, clustermanager.Name, err)
}
}
// delete the grpc serving secret if the grpc auth is disabled
if !helpers.GRPCAuthEnabled(clustermanager) {
if _, ok := c.rotationMap[clustermanager.Name]; ok {
@@ -199,7 +218,7 @@ func (c certRotationController) syncOne(ctx context.Context, clustermanager *ope
err = c.kubeClient.CoreV1().Secrets(clustermanagerNamespace).Delete(ctx, helpers.GRPCServerSecret, metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("clean up deleted cluster-manager, deleting grpc server secret failed, err:%s", err.Error())
return fmt.Errorf("failed to delete secret %q for cluster-manager %q: GRPCAuth feature disabled, err: %v", helpers.GRPCServerSecret, clustermanager.Name, err)
}
}
@@ -282,6 +301,22 @@ func (c certRotationController) syncOne(ctx context.Context, clustermanager *ope
}
}
if helpers.PlacementDebugServerEnabled(clustermanager) {
placementServiceName := fmt.Sprintf("%s-placement", clustermanager.Name)
hostNames := []string{fmt.Sprintf("%s.%s.svc", placementServiceName, clustermanagerNamespace)}
if _, ok := cmRotations.targetRotations[helpers.PlacementDebugServingCertSecret]; !ok {
c.rotationMap[clustermanagerName].targetRotations[helpers.PlacementDebugServingCertSecret] = certrotation.TargetRotation{
Namespace: clustermanagerNamespace,
Name: helpers.PlacementDebugServingCertSecret,
Validity: TargetCertValidity,
HostNames: hostNames,
Lister: c.secretInformers[helpers.PlacementDebugServingCertSecret].Lister(),
Client: c.kubeClient.CoreV1(),
}
}
}
// reconcile cert/key pair for signer
signingCertKeyPair, err := cmRotations.signingRotation.EnsureSigningCertKeyPair()
if err != nil {

View File

@@ -172,11 +172,12 @@ func TestCertRotation(t *testing.T) {
}
secretInformers := map[string]corev1informers.SecretInformer{
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.PlacementDebugServingCertSecret: newOnTermInformer(helpers.PlacementDebugServingCertSecret).Core().V1().Secrets(),
}
configmapInformer := newOnTermInformer(helpers.CaBundleConfigmap).Core().V1().ConfigMaps()
@@ -316,11 +317,12 @@ func TestCertRotationGRPCAuth(t *testing.T) {
}
secretInformers := map[string]corev1informers.SecretInformer{
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.PlacementDebugServingCertSecret: newOnTermInformer(helpers.PlacementDebugServingCertSecret).Core().V1().Secrets(),
}
configmapInformer := newOnTermInformer(helpers.CaBundleConfigmap).Core().V1().ConfigMaps()
@@ -672,11 +674,12 @@ func TestCertRotationGRPCServerHostNames(t *testing.T) {
}
secretInformers := map[string]corev1informers.SecretInformer{
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.PlacementDebugServingCertSecret: newOnTermInformer(helpers.PlacementDebugServingCertSecret).Core().V1().Secrets(),
}
configmapInformer := newOnTermInformer(helpers.CaBundleConfigmap).Core().V1().ConfigMaps()
@@ -716,6 +719,162 @@ func TestCertRotationGRPCServerHostNames(t *testing.T) {
}
}
func TestCertRotationPlacementDebug(t *testing.T) {
namespace := helpers.ClusterManagerNamespace(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
cases := []struct {
name string
clusterManager *operatorapiv1.ClusterManager
updatedClusterManager *operatorapiv1.ClusterManager
existingObjects []runtime.Object
validate func(t *testing.T, kubeClient kubernetes.Interface, controller *certRotationController)
}{
{
name: "Enable PlacementDebugServer",
clusterManager: func() *operatorapiv1.ClusterManager {
cm := newClusterManager(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
cm.Spec.PlacementConfiguration = nil
return cm
}(),
updatedClusterManager: func() *operatorapiv1.ClusterManager {
cm := newClusterManager(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
cm.Spec.PlacementConfiguration = &operatorapiv1.PlacementConfiguration{
FeatureGates: []operatorapiv1.FeatureGate{
{
Feature: "PlacementDebugServer",
Mode: operatorapiv1.FeatureGateModeTypeEnable,
},
},
}
return cm
}(),
existingObjects: []runtime.Object{
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
},
},
validate: func(t *testing.T, kubeClient kubernetes.Interface, controller *certRotationController) {
secret, err := kubeClient.CoreV1().Secrets(namespace).Get(context.Background(), helpers.PlacementDebugServingCertSecret, metav1.GetOptions{})
if err != nil {
t.Fatalf("expected placement debug serving cert secret to be created after update, but got error: %v", err)
}
if _, ok := secret.Data["tls.crt"]; !ok {
t.Fatalf("expected tls.crt in secret data")
}
if _, ok := secret.Data["tls.key"]; !ok {
t.Fatalf("expected tls.key in secret data")
}
cmRotations, ok := controller.rotationMap[testClusterManagerNameDefault]
if !ok {
t.Fatalf("expected rotations to exist in map")
}
if _, ok := cmRotations.targetRotations[helpers.PlacementDebugServingCertSecret]; !ok {
t.Fatalf("expected placement debug serving cert rotation to be added after update, %v", cmRotations)
}
},
},
{
name: "Disable PlacementDebugServer",
clusterManager: func() *operatorapiv1.ClusterManager {
cm := newClusterManager(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
cm.Spec.PlacementConfiguration = &operatorapiv1.PlacementConfiguration{
FeatureGates: []operatorapiv1.FeatureGate{
{
Feature: "PlacementDebugServer",
Mode: operatorapiv1.FeatureGateModeTypeEnable,
},
},
}
return cm
}(),
updatedClusterManager: func() *operatorapiv1.ClusterManager {
cm := newClusterManager(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
cm.Spec.PlacementConfiguration = nil
return cm
}(),
existingObjects: []runtime.Object{
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
},
},
validate: func(t *testing.T, kubeClient kubernetes.Interface, controller *certRotationController) {
_, err := kubeClient.CoreV1().Secrets(namespace).Get(context.Background(), helpers.PlacementDebugServingCertSecret, metav1.GetOptions{})
if !errors.IsNotFound(err) {
t.Fatalf("expected placement debug serving cert secret to be deleted after update, but got error: %v", err)
}
cmRotations, ok := controller.rotationMap[testClusterManagerNameDefault]
if !ok {
t.Fatalf("expected rotations to exist in map")
}
if _, ok := cmRotations.targetRotations[helpers.PlacementDebugServingCertSecret]; ok {
t.Fatalf("expected placement debug serving cert rotation to be removed after update, %v", cmRotations)
}
},
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
kubeClient := fakekube.NewSimpleClientset(c.existingObjects...)
newOnTermInformer := func(name string) kubeinformers.SharedInformerFactory {
return kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 5*time.Minute,
kubeinformers.WithTweakListOptions(func(options *metav1.ListOptions) {
options.FieldSelector = fields.OneTermEqualSelector("metadata.name", name).String()
}))
}
secretInformers := map[string]corev1informers.SecretInformer{
helpers.SignerSecret: newOnTermInformer(helpers.SignerSecret).Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: newOnTermInformer(helpers.RegistrationWebhookSecret).Core().V1().Secrets(),
helpers.WorkWebhookSecret: newOnTermInformer(helpers.WorkWebhookSecret).Core().V1().Secrets(),
helpers.AddonWebhookSecret: newOnTermInformer(helpers.AddonWebhookSecret).Core().V1().Secrets(),
helpers.GRPCServerSecret: newOnTermInformer(helpers.GRPCServerSecret).Core().V1().Secrets(),
helpers.PlacementDebugServingCertSecret: newOnTermInformer(helpers.PlacementDebugServingCertSecret).Core().V1().Secrets(),
}
configmapInformer := newOnTermInformer(helpers.CaBundleConfigmap).Core().V1().ConfigMaps()
operatorClient := fakeoperatorclient.NewSimpleClientset(c.clusterManager)
operatorInformers := operatorinformers.NewSharedInformerFactory(operatorClient, 5*time.Minute)
clusterManagerStore := operatorInformers.Operator().V1().ClusterManagers().Informer().GetStore()
if err := clusterManagerStore.Add(c.clusterManager); err != nil {
t.Fatal(err)
}
syncContext := testingcommon.NewFakeSyncContext(t, testClusterManagerNameDefault)
controller := &certRotationController{
rotationMap: make(map[string]rotations),
kubeClient: kubeClient,
secretInformers: secretInformers,
configMapInformer: configmapInformer,
clusterManagerLister: operatorInformers.Operator().V1().ClusterManagers().Lister(),
}
if err := controller.sync(context.TODO(), syncContext, testClusterManagerNameDefault); err != nil {
t.Fatal(err)
}
if err := clusterManagerStore.Update(c.updatedClusterManager); err != nil {
t.Fatal(err)
}
if err := controller.sync(context.TODO(), syncContext, testClusterManagerNameDefault); err != nil {
t.Fatal(err)
}
c.validate(t, kubeClient, controller)
})
}
}
func assertResourcesExistAndValid(t *testing.T, kubeClient kubernetes.Interface, namespace string) {
configmap, err := kubeClient.CoreV1().ConfigMaps(namespace).Get(context.Background(), "ca-bundle-configmap", metav1.GetOptions{})
if err != nil {

View File

@@ -227,6 +227,9 @@ func (n *clusterManagerController) sync(ctx context.Context, controllerContext f
}
_, placementFeatureMsgs = helpers.ConvertToFeatureGateFlags("Placement", placementFeatureGates, ocmfeature.DefaultHubPlacementFeatureGates)
config.PlacementDebugServerEnabled = helpers.FeatureGateEnabled(placementFeatureGates, ocmfeature.DefaultHubPlacementFeatureGates, ocmfeature.PlacementDebugServer)
if config.PlacementDebugServerEnabled {
config.PlacementServingCertSecret = helpers.PlacementDebugServingCertSecret
}
featureGateCondition := helpers.BuildFeatureCondition(registrationFeatureMsgs, workFeatureMsgs, addonFeatureMsgs, placementFeatureMsgs)

View File

@@ -60,6 +60,7 @@ func (o *Options) RunClusterManagerOperator(ctx context.Context, controllerConte
workSecretInformer := newOneTermInformer(helpers.WorkWebhookSecret)
addonSecretInformer := newOneTermInformer(helpers.AddonWebhookSecret)
grpcServerSecretInformer := newOneTermInformer(helpers.GRPCServerSecret)
placementDebugSecretInformer := newOneTermInformer(helpers.PlacementDebugServingCertSecret)
configmapInformer := newOneTermInformer(helpers.CaBundleConfigmap)
deploymentInformer := informers.NewSharedInformerFactoryWithOptions(kubeClient, 5*time.Minute,
@@ -76,11 +77,12 @@ func (o *Options) RunClusterManagerOperator(ctx context.Context, controllerConte
}))
secretInformers := map[string]corev1informers.SecretInformer{
helpers.SignerSecret: signerSecretInformer.Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: registrationSecretInformer.Core().V1().Secrets(),
helpers.WorkWebhookSecret: workSecretInformer.Core().V1().Secrets(),
helpers.AddonWebhookSecret: addonSecretInformer.Core().V1().Secrets(),
helpers.GRPCServerSecret: grpcServerSecretInformer.Core().V1().Secrets(),
helpers.SignerSecret: signerSecretInformer.Core().V1().Secrets(),
helpers.RegistrationWebhookSecret: registrationSecretInformer.Core().V1().Secrets(),
helpers.WorkWebhookSecret: workSecretInformer.Core().V1().Secrets(),
helpers.AddonWebhookSecret: addonSecretInformer.Core().V1().Secrets(),
helpers.GRPCServerSecret: grpcServerSecretInformer.Core().V1().Secrets(),
helpers.PlacementDebugServingCertSecret: placementDebugSecretInformer.Core().V1().Secrets(),
}
// Build operator client and informer
@@ -153,6 +155,7 @@ func (o *Options) RunClusterManagerOperator(ctx context.Context, controllerConte
go workSecretInformer.Start(ctx.Done())
go addonSecretInformer.Start(ctx.Done())
go grpcServerSecretInformer.Start(ctx.Done())
go placementDebugSecretInformer.Start(ctx.Done())
go configmapInformer.Start(ctx.Done())
go clusterManagerController.Run(ctx, 1)
go statusController.Run(ctx, 1)