Skip to content

Observe only resources fail to sync when server-side apply (SSA) is enabled #431

@gravufo

Description

@gravufo

What happened?

When provider-kubernetes with SSA enabled tries to reconcile an Object resource with only the Observe management policy and not all fields are provided, it fails with the following error:

cannot get desired state: cannot dry run SSA: PushSecret.external-secrets.io "test" is invalid: spec.secretStoreRefs: Invalid value: "null": spec.secretStoreRefs in body must be of type array: "null"

How can we reproduce it?

Have a setup with provider-kubernetes with SSA enabled.
Create the underlying resource, then watch it with an Object that only references its name, nothing from its spec. We don't want to match it 1-to-1 since the goal of an Observe-only resource is to get its remote state and bring it back into Crossplane (spec, status, etc.).

For example, for a PushSecret named test:

apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: test
  namespace: test
spec:
  data:
  - conversionStrategy: None
    match:
      remoteRef:
        remoteKey: test
      secretKey: test
  deletionPolicy: Delete
  refreshInterval: 1m0s
  secretStoreRefs:
  - kind: ClusterSecretStore
    name: test
  selector:
    secret:
      name: test
  updatePolicy: Replace
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
  name: test
spec:
  deletionPolicy: Delete
  forProvider:
    manifest:
      apiVersion: external-secrets.io/v1alpha1
      kind: PushSecret
      metadata:
        name: test
        namespace: test
      spec:
        secretStoreRefs: null
        selector: {}
      status:
        refreshTime: null
  managementPolicies:
  - Observe
  providerConfigRef:
    name: default
  readiness:
    policy: DeriveFromObject
  watch: false

What environment did it happen in?

Crossplane version: 2.1.4
Cloud: Azure
Kubernetes version: 1.33.6
Kubernetes distro: AKS
OS: Azure Linux

Investigation

I investigated this a little bit and it seems to be due to the dry-run Apply being done here:

if desiredState, err = c.syncer.GetDesiredState(ctx, obj, manifest); err != nil {

Since we don't really care about "drift" in an Observe-only resource (using it like a data source object in Terraform), maybe we could just wrap this in an if statement that skips the dry-run apply?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions