Skip to content

Finalization uses invalid cluster_type as OpenShift, hiding misconfigurations #109

Description

@sourcery-ai

Summary

Finalization logic for Kruize resources currently treats invalid cluster_type values as OpenShift by default, even though creation now rejects invalid cluster_type values. This asymmetry can hide misconfigurations and cause unexpected behavior during cleanup.

Problem Details

  • At creation time, invalid cluster_type values in Kruize.spec.cluster_type are rejected via validation.
  • At finalization time, the controller currently:
    • Reads kruize.Spec.Cluster_type.
    • If the value is not recognized, it defaults to OpenShift-specific cleanup instead of failing.

This leads to:

  • A resource with a misconfigured cluster_type potentially being rejected when created, but
  • The same misconfigured cluster_type being treated as OpenShift during deletion/finalization if it somehow exists in the cluster (e.g., via older versions, manual edits, or spec drift).

This behavior:

  • Masks configuration errors.
  • Can cause OpenShift-specific cleanup logic to run on non-OpenShift clusters.
  • Makes create and delete behavior inconsistent for the same invalid spec.

Expected Behavior

Finalization should:

  • Use the same validation rules for cluster_type as creation, and
  • Fail finalization (and log an error) if the stored cluster_type is invalid, or
  • Use a canonical, validated cluster type value that was persisted at creation time, and reuse that value during finalization instead of defaulting to OpenShift.

Proposed Solutions

Option A – Validate during finalization (simpler):

  1. In internal/controller/kruize_controller.go, when determining the cluster type during finalization, validate kruize.Spec.Cluster_type using the same validation helper as creation (e.g. constants.IsValidClusterType).
  2. If invalid, log an error and return without performing cleanup.

Suggested code snippet:

// Get the cluster type to determine which resources to clean up
clusterType := kruize.Spec.Cluster_type
if !constants.IsValidClusterType(clusterType) {
    err := fmt.Errorf("invalid cluster type %q in Kruize spec during finalization", clusterType)
    logger.Error(err, "Invalid cluster type during finalization; refusing to proceed")
    return err
}

// existing cleanup logic based on clusterType ...

To compile, ensure fmt is imported in internal/controller/kruize_controller.go:

import (
    "fmt"
    // other imports...
)

(If fmt is already imported, no changes are needed there.)

Option B – Persist canonical cluster type at creation (more robust, but larger change):

  1. During creation/reconciliation, after validating cluster_type, store a canonical/normalized cluster type in the Kruize status or another durable field.
  2. During finalization, only use this canonical field to determine which cleanup logic to run.
  3. If the canonical field is missing or invalid (e.g. from legacy objects), log an error and fail finalization instead of defaulting to OpenShift.

Action Items

  • Decide on approach (A: validate on finalization, or B: persist canonical cluster type and reuse).
  • Implement cluster type validation in finalization path (or switch to using the persisted canonical type).
  • Ensure logging clearly indicates when finalization is refused due to invalid cluster_type.
  • Add/extend tests to cover:
    • Valid cluster types for all supported platforms.
    • Invalid cluster_type in spec during finalization (should log and fail, not default to OpenShift).
    • Backward compatibility behavior for existing CRs.
  • Update documentation (if any) to reflect consistent validation on create and delete and clarify behavior when cluster_type is invalid.

Impact

Fixing this will:

  • Keep creation and finalization behavior consistent.
  • Prevent invalid specs from being silently treated as OpenShift.
  • Reduce risk of running OpenShift-specific cleanup on non-OpenShift clusters.

I created this issue for @shreyabiradar07 from #108 (comment).

Tips and commands

Getting Help

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions