Skip to content

Commit ee282a6

Browse files
Merge pull request #197 from datum-cloud/fix/replicator-downstream-version-fallback
fix(replicator): fall back to storage version for downstream watch
2 parents 1bab5bc + 3e7cc0d commit ee282a6

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

internal/controller/gateway_resource_replicator_controller.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
corev1 "k8s.io/api/core/v1"
1212
apiequality "k8s.io/apimachinery/pkg/api/equality"
1313
apierrors "k8s.io/apimachinery/pkg/api/errors"
14+
apimeta "k8s.io/apimachinery/pkg/api/meta"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1617
"k8s.io/apimachinery/pkg/labels"
@@ -86,6 +87,7 @@ type replicationResourceConfig struct {
8687

8788
type replicationResource struct {
8889
gvk schema.GroupVersionKind
90+
downstreamGVK schema.GroupVersionKind
8991
replicationResourceConfig replicationResourceConfig
9092
controllerName string
9193
}
@@ -221,7 +223,7 @@ func (r *GatewayResourceReplicatorReconciler) Reconcile(ctx context.Context, req
221223
downstreamStrategy := downstreamclient.NewMappedNamespaceResourceStrategy(string(req.ClusterName), upstreamClient, r.DownstreamCluster.GetClient())
222224

223225
if !upstreamObj.GetDeletionTimestamp().IsZero() {
224-
return r.finalizeResource(ctx, upstreamClient, upstreamObj, downstreamStrategy)
226+
return r.finalizeResource(ctx, resourceCfg, upstreamClient, upstreamObj, downstreamStrategy)
225227
}
226228

227229
if !controllerutil.ContainsFinalizer(upstreamObj, gatewayResourceReplicatorFinalizer) {
@@ -245,12 +247,13 @@ func (r *GatewayResourceReplicatorReconciler) Reconcile(ctx context.Context, req
245247
// nolint:unparam
246248
func (r *GatewayResourceReplicatorReconciler) finalizeResource(
247249
ctx context.Context,
250+
resource replicationResource,
248251
upstreamClient client.Client,
249252
upstreamObj *unstructured.Unstructured,
250253
downstreamStrategy downstreamclient.ResourceStrategy,
251254
) (ctrl.Result, error) {
252255
if controllerutil.ContainsFinalizer(upstreamObj, gatewayResourceReplicatorFinalizer) {
253-
if err := r.finalize(ctx, upstreamObj, downstreamStrategy); err != nil {
256+
if err := r.finalize(ctx, resource, upstreamObj, downstreamStrategy); err != nil {
254257
return ctrl.Result{}, err
255258
}
256259

@@ -292,7 +295,7 @@ func (r *GatewayResourceReplicatorReconciler) ensureDownstreamResource(
292295
}
293296

294297
downstreamObj := &unstructured.Unstructured{}
295-
downstreamObj.SetGroupVersionKind(upstreamObj.GroupVersionKind())
298+
downstreamObj.SetGroupVersionKind(resource.downstreamGVK)
296299
downstreamObj.SetName(downstreamObjectMeta.Name)
297300
downstreamObj.SetNamespace(downstreamObjectMeta.Namespace)
298301

@@ -434,7 +437,7 @@ func (r *GatewayResourceReplicatorReconciler) syncUpstreamStatus(
434437
) error {
435438
logger := log.FromContext(ctx)
436439
downstreamObj := &unstructured.Unstructured{}
437-
downstreamObj.SetGroupVersionKind(upstreamObj.GroupVersionKind())
440+
downstreamObj.SetGroupVersionKind(resource.downstreamGVK)
438441

439442
if err := downstreamStrategy.GetClient().Get(ctx, client.ObjectKey{Name: downstreamMeta.Name, Namespace: downstreamMeta.Namespace}, downstreamObj); err != nil {
440443
if apierrors.IsNotFound(err) {
@@ -671,6 +674,7 @@ func defaultGatewayEnvoyReasonHandlers() conditionReasonHandlers {
671674

672675
func (r *GatewayResourceReplicatorReconciler) finalize(
673676
ctx context.Context,
677+
resource replicationResource,
674678
upstreamObj *unstructured.Unstructured,
675679
downstreamStrategy downstreamclient.ResourceStrategy,
676680
) error {
@@ -681,7 +685,7 @@ func (r *GatewayResourceReplicatorReconciler) finalize(
681685
}
682686

683687
downstreamObj := &unstructured.Unstructured{}
684-
downstreamObj.SetGroupVersionKind(upstreamObj.GroupVersionKind())
688+
downstreamObj.SetGroupVersionKind(resource.downstreamGVK)
685689
downstreamObj.SetName(downstreamObjectMeta.Name)
686690
downstreamObj.SetNamespace(downstreamObjectMeta.Namespace)
687691

@@ -728,19 +732,32 @@ func (r *GatewayResourceReplicatorReconciler) SetupWithManager(mgr mcmanager.Man
728732

729733
resource := replicationResource{
730734
gvk: gvk,
735+
downstreamGVK: gvk,
731736
controllerName: string(r.Config.Gateway.ControllerName),
732737
}
733738
if cfg, ok := defaultReplicationResourceConfigs[gvkKey(gvk)]; ok {
734739
resource.replicationResourceConfig = cfg
735740
}
736741

742+
// If the downstream cluster no longer serves the upstream version (e.g.
743+
// v1alpha3 removed after a Gateway API graduation), fall back to the
744+
// storage version for both the watch and the create path. The discovery
745+
// check is done once at setup so reconciles pay no extra cost.
746+
if resource.replicationResourceConfig.statusGVK != nil {
747+
if _, err := r.DownstreamCluster.GetRESTMapper().RESTMapping(
748+
schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version,
749+
); err != nil && apimeta.IsNoMatchError(err) {
750+
resource.downstreamGVK = *resource.replicationResourceConfig.statusGVK
751+
}
752+
}
753+
737754
resources[gvkKey(gvk)] = resource
738755

739756
upstreamWatchObj := newUnstructuredForGVK(gvk)
740757

741758
builder = builder.Watches(upstreamWatchObj, typedEnqueueRequestForGVK(gvk, selector))
742759

743-
downstreamWatchObj := newUnstructuredForGVK(gvk)
760+
downstreamWatchObj := newUnstructuredForGVK(resource.downstreamGVK)
744761

745762
src := mcsource.TypedKind(
746763
downstreamWatchObj,

internal/controller/gateway_resource_replicator_controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ func newReplicatorForGVKTest(gvk schema.GroupVersionKind, upstream client.Client
625625
upstreamCluster := &replicatorFakeCluster{scheme: scheme, c: upstream}
626626
downstreamCluster := &replicatorFakeCluster{scheme: scheme, c: downstream}
627627

628-
resource := replicationResource{gvk: gvk, controllerName: testControllerName}
628+
resource := replicationResource{gvk: gvk, downstreamGVK: gvk, controllerName: testControllerName}
629629
if cfg, ok := defaultReplicationResourceConfigs[gvkKey(gvk)]; ok {
630630
resource.replicationResourceConfig = cfg
631631
}

0 commit comments

Comments
 (0)