Skip to content

Commit d5d5d88

Browse files
lmicciniclaude
andcommitted
Fix webhook config merge to match by name instead of index
MergeWebhookConfigurationForUpdate was copying the entire clientConfig from current to updated webhooks by array index. When the webhook arrays have different ordering (e.g. Kubernetes sorts alphabetically by name, but the template YAML has a different order), each webhook gets the clientConfig from the wrong entry. This scrambles the service paths, causing admission requests to be routed to the wrong handler. For example, mrabbitmq-v1beta1.kb.io would get the path for /mutate-network-openstack-org-v1beta1-reservation instead of /mutate-rabbitmq-openstack-org-v1beta1-rabbitmq, resulting in: "unable to decode rabbitmq.openstack.org/v1beta1, Kind=RabbitMq into *v1beta1.Reservation" Fix by matching webhooks by name and only copying the caBundle field (injected by cert-manager) rather than the entire clientConfig. This preserves the correct service path from the updated template. Jira: https://redhat.atlassian.net/browse/OSPRH-29026 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6fd66d8 commit d5d5d88

1 file changed

Lines changed: 38 additions & 8 deletions

File tree

internal/operator/bindata/merge.go

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ func MergeObjectForUpdate(current, updated *uns.Unstructured) error {
5555
return nil
5656
}
5757

58-
// MergeWebhookConfigurationForUpdate merges certs and clientConfig from the current object
58+
// MergeWebhookConfigurationForUpdate merges the caBundle from the current
59+
// webhook configuration into the updated one, matching webhooks by name.
60+
// This preserves the CA certificate injected by cert-manager while keeping
61+
// the service path and other clientConfig fields from the updated template.
5962
func MergeWebhookConfigurationForUpdate(current, updated *uns.Unstructured) error {
6063
gvk := updated.GroupVersionKind()
6164

@@ -65,17 +68,44 @@ func MergeWebhookConfigurationForUpdate(current, updated *uns.Unstructured) erro
6568
return nil
6669
}
6770

68-
for i, webhook := range updated.Object["webhooks"].([]interface{}) {
69-
// Check if the index exists in the current webhooks list
70-
if i >= len(currentWebhooks) {
71+
// Build a lookup of current caBundle values keyed by webhook name
72+
caBundleByName := make(map[string]interface{})
73+
for _, cw := range currentWebhooks {
74+
cwMap, ok := cw.(map[string]interface{})
75+
if !ok {
7176
continue
7277
}
73-
74-
currentClientConfig := currentWebhooks[i].(map[string]interface{})["clientConfig"].(map[string]interface{})
75-
if currentClientConfig != nil {
76-
webhook.(map[string]interface{})["clientConfig"] = currentClientConfig
78+
name, _ := cwMap["name"].(string)
79+
if name == "" {
80+
continue
81+
}
82+
cc, ok := cwMap["clientConfig"].(map[string]interface{})
83+
if !ok {
84+
continue
7785
}
86+
if caBundle, exists := cc["caBundle"]; exists {
87+
caBundleByName[name] = caBundle
88+
}
89+
}
7890

91+
for _, webhook := range updated.Object["webhooks"].([]interface{}) {
92+
whMap, ok := webhook.(map[string]interface{})
93+
if !ok {
94+
continue
95+
}
96+
name, _ := whMap["name"].(string)
97+
if name == "" {
98+
continue
99+
}
100+
caBundle, found := caBundleByName[name]
101+
if !found {
102+
continue
103+
}
104+
cc, ok := whMap["clientConfig"].(map[string]interface{})
105+
if !ok {
106+
continue
107+
}
108+
cc["caBundle"] = caBundle
79109
}
80110
}
81111
return nil

0 commit comments

Comments
 (0)