Repository: knative-sandbox/eventing-kafka-broker (go)

Issue:
metadata.finalizers: Invalid value: name part must be no more than 63 characters
**Describe the bug**
When I create a Knative eventing broker using a configmap with name `ob-46b35be1-0165-441b-9158-a7ec08ad7a97` and namespace `ob-1608dc1f-4139-49c5-ae22-afe73ed807d7` the Broker fails with 
```
 reason: >-
        failed to add finalizer to ConfigMap
        ob-1608dc1f-4139-49c5-ae22-afe73ed807d7/ob-46b35be1-0165-441b-9158-a7ec08ad7a97:
        ConfigMap "ob-46b35be1-0165-441b-9158-a7ec08ad7a97" is invalid:
        metadata.finalizers: Invalid value:
        "kafka.brokers.eventing.knative.dev/ob-1608dc1f-4139-49c5-ae22-afe73ed807d7-ob-46b35be1-0165-441b-9158-a7ec08ad7a97":
        name part must be no more than 63 characters
```

 **Expected behavior**
I think sometimes it is reasonable to use a uuid for a name and a namespace, so I would expect this to work. I think the prefix `kafka.brokers.eventing.knative.dev` is slightly longer than needed. 

 **To Reproduce**
```
kind: ConfigMap
apiVersion: v1
metadata:
  name: ob-468c0030-c45e-4ded-8c79-08cb1e455085
  namespace: ob-1608dc1f-4139-49c5-ae22-afe73ed807d7
data:
  auth.secret.ref.name: ob-468c0030-c45e-4ded-8c79-08cb1e455085
  bootstrap.servers: REDACTED
  default.topic.partitions: '10'
  default.topic.replication.factor: '3'
---
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  annotations:
    eventing.knative.dev/broker.class: Kafka
  name: ob-468c0030-c45e-4ded-8c79-08cb1e455085
  namespace: ob-1608dc1f-4139-49c5-ae22-afe73ed807d7
spec:
  config:
    apiVersion: v1
    kind: ConfigMap
    name: ob-468c0030-c45e-4ded-8c79-08cb1e455085
    namespace: ob-1608dc1f-4139-49c5-ae22-afe73ed807d7
```

 **Knative release version**
release-1.1
 **Additional context**
Add any other context about the problem here such as proposed priority


Pull request:
Use broker status annotations to stamp ConfigMap reference
Instead of adding a finalizer to the ConfigMap, we can record
the ConfigMap data in the Broker status so that we can re-build
the ConfigMap even when the ConfigMap is deleted first.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

Fixes #1970

**Release Note**

<!--
:page_facing_up: If this change has user-visible impact, write a release note in the block
below. Include the string "action required" if additional action is required of
users switching to the new release, for example in case of a breaking change.

Write as if you are speaking to users, not other Knative contributors. If this
change has no user-visible impact, no release-note is needed.
-->

```release-note
Support brokers with long namespace and name values.
```


Patch:
diff --git a/control-plane/pkg/reconciler/broker/broker.go b/control-plane/pkg/reconciler/broker/broker.go
index 3b9c20473..689f57e2c 100644
--- a/control-plane/pkg/reconciler/broker/broker.go
+++ b/control-plane/pkg/reconciler/broker/broker.go
@@ -90,7 +90,7 @@ func (r *Reconciler) reconcileKind(ctx context.Context, broker *eventing.Broker)
 	}
 	statusConditionManager.DataPlaneAvailable()
 
-	topicConfig, brokerConfig, err := r.topicConfig(ctx, logger, broker)
+	topicConfig, brokerConfig, err := r.topicConfig(logger, broker)
 	if err != nil {
 		return statusConditionManager.FailedToResolveConfig(err)
 	}
@@ -305,7 +305,7 @@ func (r *Reconciler) finalizeKind(ctx context.Context, broker *eventing.Broker)
 		return controller.NewRequeueAfter(5 * time.Second)
 	}
 
-	topicConfig, brokerConfig, err := r.topicConfig(ctx, logger, broker)
+	topicConfig, brokerConfig, err := r.topicConfig(logger, broker)
 	if err != nil {
 		return fmt.Errorf("failed to resolve broker config: %w", err)
 	}
@@ -348,6 +348,7 @@ func (r *Reconciler) finalizeKind(ctx context.Context, broker *eventing.Broker)
 
 	logger.Debug("Topic deleted", zap.String("topic", topic))
 
+	// TODO(pierDipi) remove after some releases (released in 1.4)
 	if err := r.removeFinalizerCM(ctx, finalizerCM(broker), brokerConfig); err != nil {
 		return err
 	}
@@ -355,7 +356,7 @@ func (r *Reconciler) finalizeKind(ctx context.Context, broker *eventing.Broker)
 	return nil
 }
 
-func (r *Reconciler) topicConfig(ctx context.Context, logger *zap.Logger, broker *eventing.Broker) (*kafka.TopicConfig, *corev1.ConfigMap, error) {
+func (r *Reconciler) topicConfig(logger *zap.Logger, broker *eventing.Broker) (*kafka.TopicConfig, *corev1.ConfigMap, error) {
 
 	logger.Debug("broker config", zap.Any("broker.spec.config", broker.Spec.Config))
 
@@ -368,23 +369,62 @@ func (r *Reconciler) topicConfig(ctx context.Context, logger *zap.Logger, broker
 		// Namespace not specified, use broker namespace.
 		namespace = broker.Namespace
 	}
-	cm, err := r.ConfigMapLister.ConfigMaps(namespace).Get(broker.Spec.Config.Name)
-	if err != nil {
-		return nil, nil, fmt.Errorf("failed to get configmap %s/%s: %w", namespace, broker.Spec.Config.Name, err)
-	}
 
-	if err := r.addFinalizerCM(ctx, finalizerCM(broker), cm); err != nil {
-		return nil, nil, err
+	// There might be cases where the ConfigMap is deleted before the Broker.
+	// In these cases, we rebuild the ConfigMap from broker status annotations.
+	//
+	// These annotations aren't guaranteed to be there or valid since there might
+	// be other actions messing with them, so when we try to rebuild the ConfigMap's
+	// data but the guess is wrong or data are invalid we return the
+	// `StatusReasonNotFound` error instead of the error generated from the fake
+	// "re-built" ConfigMap.
+
+	isRebuilt := false
+	cm, getCmError := r.ConfigMapLister.ConfigMaps(namespace).Get(broker.Spec.Config.Name)
+	if getCmError != nil && !apierrors.IsNotFound(getCmError) {
+		return nil, nil, fmt.Errorf("failed to get configmap %s/%s: %w", namespace, broker.Spec.Config.Name, getCmError)
+	}
+	if apierrors.IsNotFound(getCmError) {
+		cm = rebuildCMFromAnnotations(broker)
+		isRebuilt = true
 	}
 
 	topicConfig, err := kafka.TopicConfigFromConfigMap(logger, cm)
 	if err != nil {
+		if isRebuilt {
+			return nil, cm, fmt.Errorf("failed to get configmap %s/%s: %w", namespace, broker.Spec.Config.Name, getCmError)
+		}
 		return nil, cm, fmt.Errorf("unable to build topic config from configmap: %w - ConfigMap data: %v", err, cm.Data)
 	}
 
+	if broker.Status.Annotations == nil {
+		broker.Status.Annotations = make(map[string]string, len(cm.Data))
+	}
+
+	// Save ConfigMap's data into broker annotations
+	for k, v := range cm.Data {
+		broker.Status.Annotations[k] = v
+	}
+
 	return topicConfig, cm, nil
 }
 
+func rebuildCMFromAnnotations(br *eventing.Broker) *corev1.ConfigMap {
+	cm := &corev1.ConfigMap{
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: br.Spec.Config.Namespace,
+			Name:      br.Spec.Config.Name,
+		},
+	}
+	for k, v := range br.Status.Annotations {
+		if cm.Data == nil {
+			cm.Data = make(map[string]string, len(br.Status.Annotations))
+		}
+		cm.Data[k] = v
+	}
+	return cm
+}
+
 func (r *Reconciler) reconcilerBrokerResource(ctx context.Context, topic string, broker *eventing.Broker, secret *corev1.Secret, config *kafka.TopicConfig) (*contract.Resource, error) {
 	resource := &contract.Resource{
 		Uid:    string(broker.UID),
@@ -422,30 +462,6 @@ func (r *Reconciler) reconcilerBrokerResource(ctx context.Context, topic string,
 	return resource, nil
 }
 
-func (r *Reconciler) addFinalizerCM(ctx context.Context, finalizer string, cm *corev1.ConfigMap) error {
-	if !containsFinalizerCM(cm, finalizer) {
-		cm := cm.DeepCopy() // Do not modify informer copy.
-		cm.Finalizers = append(cm.Finalizers, finalizer)
-		_, err := r.KubeClient.CoreV1().ConfigMaps(cm.GetNamespace()).Update(ctx, cm, metav1.UpdateOptions{})
-		if err != nil && !apierrors.IsNotFound(err) {
-			return fmt.Errorf("failed to add finalizer to ConfigMap %s/%s: %w", cm.GetNamespace(), cm.GetName(), err)
-		}
-	}
-	return nil
-}
-
-func containsFinalizerCM(cm *corev1.ConfigMap, finalizer string) bool {
-	if cm == nil {
-		return false
-	}
-	for _, f := range cm.Finalizers {
-		if f == finalizer {
-			return true
-		}
-	}
-	return false
-}
-
 func (r *Reconciler) removeFinalizerCM(ctx context.Context, finalizer string, cm *corev1.ConfigMap) error {
 	newFinalizers := make([]string, 0, len(cm.Finalizers))
 	for _, f := range cm.Finalizers {
diff --git a/go.mod b/go.mod
index 5f6bed90c..9e5eb7c2a 100644
--- a/go.mod
+++ b/go.mod
@@ -23,7 +23,7 @@ require (
 	k8s.io/apiserver v0.22.5
 	k8s.io/client-go v0.22.5
 	k8s.io/utils v0.0.0-20211208161948-7d6a63dca704
-	knative.dev/eventing v0.29.1-0.20220303004706-b34944341f8c
+	knative.dev/eventing v0.29.1-0.20220307093036-6fabdd586db7
 	knative.dev/eventing-kafka v0.28.1-0.20220304062435-fb7769ca5216
 	knative.dev/hack v0.0.0-20220224013837-e1785985d364
 	knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77
diff --git a/go.sum b/go.sum
index b5fbc2a87..7f7c98d75 100644
--- a/go.sum
+++ b/go.sum
@@ -1360,8 +1360,8 @@ k8s.io/utils v0.0.0-20211208161948-7d6a63dca704 h1:ZKMMxTvduyf5WUtREOqg5LiXaN1KO
 k8s.io/utils v0.0.0-20211208161948-7d6a63dca704/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 knative.dev/control-protocol v0.0.0-20220201152531-79a0b1ad34b9/go.mod h1:OGZyr8rJQoDs8pE9gQ47koLdhJ+Vb0QubzntQbrwjdY=
 knative.dev/eventing v0.29.1-0.20220228193110-f2045b0d65b7/go.mod h1:1PF6Gr2r+y0PrJ/sgoN8jcAi599SLbKDuGulAsdGX/w=
-knative.dev/eventing v0.29.1-0.20220303004706-b34944341f8c h1:t62rMmDxde4qSNxSBo58vePigTeGetphQ0IVJSrxLnE=
-knative.dev/eventing v0.29.1-0.20220303004706-b34944341f8c/go.mod h1:Vw68reHKw2xRYIit+M4ZjcJXUP9dnzW5pR6H5LPnaic=
+knative.dev/eventing v0.29.1-0.20220307093036-6fabdd586db7 h1:lGhM4CYQjo0VLqmYYt2Julns4b2HvZxXoKswsFdRzxs=
+knative.dev/eventing v0.29.1-0.20220307093036-6fabdd586db7/go.mod h1:JCqC8evTls1WiBTmYhPEGME6OQD8HFnLQjFPImwOEOg=
 knative.dev/eventing-kafka v0.28.1-0.20220304062435-fb7769ca5216 h1:RMXWs9ycE9IYkjCb9MoNmKWWg4pHQ7PZwxBaMiT1RYA=
 knative.dev/eventing-kafka v0.28.1-0.20220304062435-fb7769ca5216/go.mod h1:f9NT3MrbeIORmRzUhzuDtVhrC8/MajxJukpEyQlplVw=
 knative.dev/hack v0.0.0-20220118141833-9b2ed8471e30/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
diff --git a/vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go b/vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go
index fb5da1c9c..6b66a0584 100644
--- a/vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go
+++ b/vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go
@@ -103,7 +103,6 @@ func (a *autoscaler) Start(ctx context.Context) {
 }
 
 func (a *autoscaler) Autoscale(ctx context.Context, attemptScaleDown bool, pending int32) {
-	a.trigger <- pending
 	a.syncAutoscale(ctx, attemptScaleDown, pending)
 }
 
diff --git a/vendor/modules.txt b/vendor/modules.txt
index b692906fd..e0cf4e3f9 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1124,7 +1124,7 @@ k8s.io/utils/buffer
 k8s.io/utils/integer
 k8s.io/utils/pointer
 k8s.io/utils/trace
-# knative.dev/eventing v0.29.1-0.20220303004706-b34944341f8c
+# knative.dev/eventing v0.29.1-0.20220307093036-6fabdd586db7
 ## explicit
 knative.dev/eventing/pkg/apis/config
 knative.dev/eventing/pkg/apis/duck


Test patch:
diff --git a/control-plane/pkg/reconciler/broker/broker_test.go b/control-plane/pkg/reconciler/broker/broker_test.go
index 43e3a4359..df31de9ad 100644
--- a/control-plane/pkg/reconciler/broker/broker_test.go
+++ b/control-plane/pkg/reconciler/broker/broker_test.go
@@ -136,7 +136,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -171,6 +170,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerTopicReady,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
+						BrokerConfigMapAnnotations(),
 					),
 				},
 			},
@@ -196,7 +196,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -230,6 +229,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
 						StatusBrokerProbeFailed(prober.StatusNotReady),
+						BrokerConfigMapAnnotations(),
 					),
 				},
 			},
@@ -258,7 +258,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -291,6 +290,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerProbeFailed(prober.StatusUnknown),
 					),
 				},
@@ -318,7 +318,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -350,6 +349,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerConfigParsed,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
@@ -377,7 +377,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -409,6 +408,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerConfigParsed,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
@@ -436,9 +436,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 					BrokerTopic(), createTopicError,
 				),
 			},
-			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
-			},
 			WantPatches: []clientgotesting.PatchActionImpl{
 				patchFinalizers(),
 			},
@@ -449,6 +446,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerConfigParsed,
 						StatusBrokerFailedToCreateTopic,
+						BrokerConfigMapAnnotations(),
 					),
 				},
 			},
@@ -482,7 +480,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				NewConfigMapWithBinaryData(&env, nil),
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -515,6 +512,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 						BrokerDLSResolved(ServiceURL),
@@ -539,7 +537,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -570,6 +567,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 					),
@@ -609,7 +607,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -651,6 +648,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 					),
@@ -701,7 +699,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -748,6 +745,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 						BrokerDLSResolved("http://www.my-sink.com/api"),
@@ -793,7 +791,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -833,6 +830,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 					),
@@ -873,7 +871,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -910,6 +907,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 					),
@@ -954,9 +952,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 			},
 			Key:     testKey,
 			WantErr: true,
-			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
-			},
 			WantEvents: []string{
 				finalizerUpdatedEvent,
 				Eventf(
@@ -981,6 +976,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerConfigNotParsed("failed to resolve Spec.Delivery.DeadLetterSink: destination missing Ref and URI, expected at least one"),
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 					),
 				},
 			},
@@ -999,11 +995,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 			},
 			Key:     testKey,
 			WantErr: true,
-			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName, func(cm *corev1.ConfigMap) {
-					cm.Data["bootstrap.servers"] = ""
-				}),
-			},
 			WantEvents: []string{
 				finalizerUpdatedEvent,
 				Eventf(
@@ -1050,7 +1041,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1086,6 +1076,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 					),
@@ -1122,7 +1113,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName, BrokerAuthConfig("secret-1")),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1166,6 +1156,8 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
+						BrokerConfigMapSecretAnnotation("secret-1"),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 					),
@@ -1318,7 +1310,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1374,6 +1365,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerConfigParsed,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 						BrokerDLSResolved(ServiceURL),
@@ -1429,7 +1421,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1467,6 +1458,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerConfigParsed,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
@@ -1495,7 +1487,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1533,6 +1524,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerConfigParsed,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
@@ -1561,7 +1553,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1596,6 +1587,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerConfigParsed,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
@@ -1624,7 +1616,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				ConfigMapUpdate(&env, &contract.Contract{
 					Resources: []*contract.Resource{
 						{
@@ -1662,6 +1653,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						StatusBrokerConfigMapUpdatedReady(&env),
 						StatusBrokerDataPlaneAvailable,
 						StatusBrokerTopicReady,
+						BrokerConfigMapAnnotations(),
 						StatusBrokerConfigParsed,
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
@@ -1675,6 +1667,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 			Objects: []runtime.Object{
 				NewBroker(
 					WithDelivery(),
+					BrokerConfigMapAnnotations(),
 				),
 				BrokerConfig(bootstrapServers, 20, 5),
 				NewConfigMapFromContract(&contract.Contract{
@@ -1698,9 +1691,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 			WantEvents: []string{
 				finalizerUpdatedEvent,
 			},
-			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
-			},
 			WantPatches: []clientgotesting.PatchActionImpl{
 				patchFinalizers(),
 			},
@@ -1716,6 +1706,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 						BrokerDLSResolved(ServiceURL),
+						BrokerConfigMapAnnotations(),
 					),
 				},
 			},
@@ -1749,7 +1740,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 				finalizerUpdatedEvent,
 			},
 			WantUpdates: []clientgotesting.UpdateActionImpl{
-				ConfigMapFinalizerUpdate(ConfigMapFinalizerName),
 				BrokerReceiverPodUpdate(env.SystemNamespace, map[string]string{base.VolumeGenerationAnnotationKey: "1"}),
 				BrokerDispatcherPodUpdate(env.SystemNamespace, map[string]string{base.VolumeGenerationAnnotationKey: "1"}),
 			},
@@ -1768,6 +1758,7 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 						BrokerAddressable(&env),
 						StatusBrokerProbeSucceeded,
 						BrokerDLSResolved(ServiceURL),
+						BrokerConfigMapAnnotations(),
 					),
 				},
 			},
@@ -1781,23 +1772,6 @@ func brokerReconciliation(t *testing.T, format string, env config.Env) {
 	useTable(t, table, &env)
 }
 
-func ConfigMapFinalizerUpdate(name string, opts ...CMOption) clientgotesting.UpdateActionImpl {
-	return clientgotesting.NewUpdateAction(
-		schema.GroupVersionResource{
-			Group:    "*",
-			Version:  "v1",
-			Resource: "ConfigMap",
-		},
-		ConfigMapNamespace,
-		BrokerConfig(bootstrapServers, 20, 5,
-			append(
-				[]CMOption{BrokerConfigFinalizer(name)},
-				opts...,
-			)...,
-		),
-	)
-}
-
 func ConfigMapFinalizerUpdateRemove(name string, opts ...CMOption) clientgotesting.UpdateActionImpl {
 	return clientgotesting.NewUpdateAction(
 		schema.GroupVersionResource{
@@ -1860,6 +1834,34 @@ func brokerFinalization(t *testing.T, format string, env config.Env) {
 				testProber: probertesting.MockProber(prober.StatusNotReady),
 			},
 		},
+		{
+			Name: "Reconciled normal - no ConfigMap, rebuild from annotations",
+			Objects: []runtime.Object{
+				NewDeletedBroker(
+					BrokerConfigMapAnnotations(),
+				),
+				NewConfigMapFromContract(&contract.Contract{
+					Resources: []*contract.Resource{
+						{
+							Uid:     BrokerUUID,
+							Topics:  []string{BrokerTopic()},
+							Ingress: &contract.Ingress{IngressType: &contract.Ingress_Path{Path: receiver.Path(BrokerNamespace, BrokerName)}},
+						},
+					},
+					Generation: 1,
+				}, &env),
+			},
+			Key: testKey,
+			WantUpdates: []clientgotesting.UpdateActionImpl{
+				ConfigMapUpdate(&env, &contract.Contract{
+					Resources:  []*contract.Resource{},
+					Generation: 2,
+				}),
+			},
+			OtherTestData: map[string]interface{}{
+				testProber: probertesting.MockProber(prober.StatusNotReady),
+			},
+		},
 		{
 			Name: "Reconciled failed - probe not ready",
 			Objects: []runtime.Object{
diff --git a/control-plane/pkg/reconciler/testing/objects_broker.go b/control-plane/pkg/reconciler/testing/objects_broker.go
index 7ab0e6936..de4788d39 100644
--- a/control-plane/pkg/reconciler/testing/objects_broker.go
+++ b/control-plane/pkg/reconciler/testing/objects_broker.go
@@ -18,6 +18,7 @@ package testing
 
 import (
 	"fmt"
+	"strings"
 
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -85,6 +86,7 @@ func NewDeletedBroker(options ...reconcilertesting.BrokerOption) runtime.Object
 			func(broker *eventing.Broker) {
 				WithDeletedTimeStamp(broker)
 			},
+			BrokerConfigMapAnnotations(),
 		)...,
 	)
 }
@@ -138,9 +140,8 @@ type CMOption func(cm *corev1.ConfigMap)
 func BrokerConfig(bootstrapServers string, numPartitions, replicationFactor int, options ...CMOption) *corev1.ConfigMap {
 	cm := &corev1.ConfigMap{
 		ObjectMeta: metav1.ObjectMeta{
-			Namespace:  ConfigMapNamespace,
-			Name:       ConfigMapName,
-			Finalizers: []string{"finalizer-that-we-should-not-drop"},
+			Namespace: ConfigMapNamespace,
+			Name:      ConfigMapName,
 		},
 		Data: map[string]string{
 			kafka.BootstrapServersConfigMapKey:              bootstrapServers,
@@ -336,3 +337,23 @@ func StatusBrokerProbeFailed(status prober.Status) reconcilertesting.BrokerOptio
 		StatusProbeFailed(status)(broker)
 	}
 }
+
+func BrokerConfigMapAnnotations() reconcilertesting.BrokerOption {
+	return func(broker *eventing.Broker) {
+		if broker.Status.Annotations == nil {
+			broker.Status.Annotations = make(map[string]string, 10)
+		}
+		broker.Status.Annotations[kafka.BootstrapServersConfigMapKey] = strings.Join(bootstrapServers, ",")
+		broker.Status.Annotations[kafka.DefaultTopicNumPartitionConfigMapKey] = fmt.Sprintf("%d", DefaultNumPartitions)
+		broker.Status.Annotations[kafka.DefaultTopicReplicationFactorConfigMapKey] = fmt.Sprintf("%d", DefaultReplicationFactor)
+	}
+}
+
+func BrokerConfigMapSecretAnnotation(name string) reconcilertesting.BrokerOption {
+	return func(broker *eventing.Broker) {
+		if broker.Status.Annotations == nil {
+			broker.Status.Annotations = make(map[string]string, 10)
+		}
+		broker.Status.Annotations[security.AuthSecretNameKey] = name
+	}
+}