mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-05-15 21:59:16 +00:00
🌱 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:
committed by
GitHub
parent
82543fbdf2
commit
a5c22a2bfd
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -14,6 +14,7 @@ type HubConfig struct {
|
||||
WorkAPIServiceCABundle string
|
||||
PlacementImage string
|
||||
PlacementDebugServerEnabled bool
|
||||
PlacementServingCertSecret string
|
||||
AddonAPIServiceCABundle string
|
||||
Replica int32
|
||||
HostedMode bool
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user