crossplane / upjet

A code generation framework and runtime for Crossplane providers
Apache License 2.0
318 stars 89 forks source link

Fix empty TypeMeta while running API conversions #424

Closed ulucinar closed 4 days ago

ulucinar commented 3 months ago

Description of your changes

When running the API conversion functions for multi-version CRDs, there are cases, as discussed in https://github.com/kubernetes/client-go/issues/541, where the v1.TypeMeta information has been dropped. This breaks non-wildcard conversion function filtering performed by the conversion webhook.

I have:

How has this code been tested

Tested against crossplane-contrib/provider-upjet-aws resource Instance.rds with conversions between the versions v1beta1, v1beta2, and v1beta3. Here are the steps (Note that testing the fix requires building an image, because conversion functions won't work in a provider running outside of the cluster — unless you jump through the hoops):

  1. Install a provider image, built before the fix (this PR).
  2. Apply the v1beta1 MR manifest below.
  3. Run kubectl get instance.v1beta2.rds.aws.upbound.io/test-upjet-pr-424-db.
  4. Observe that name field in v1beta1 was lost when converted to storage version v1beta2 (field renaming conversion).
  5. Repeat for other versions.
  6. Delete the resource.
  7. Build and load a provider image with the fix (this PR).
  8. Apply the same manifest.
  9. Run kubectl get instance.v1beta2.rds.aws.upbound.io/test-upjet-pr-424-db.
  10. Observe that name field in v1beta1 was converted successfully to dbName in v1beta2.
  11. Repeat for other versions.

Resource manifest

Note that we supply an invalid providerConfigRef to prevent provisioning the external resource, because we don't need the resource to test conversion functions.

apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
metadata:
  annotations:
    meta.upbound.io/example-id: rds/v1beta1/instance
    uptest.upbound.io/timeout: "3600"
  labels:
    testing.upbound.io/example-name: example-dbinstance
  name: test-upjet-pr-424-db
spec:
  forProvider:
    name: example
    region: us-west-1
    allocatedStorage: 20
    autoMinorVersionUpgrade: true
    backupRetentionPeriod: 14
    instanceClass: db.t3.micro
    engine: postgres
    engineVersion: "16.1"
    username: adminuser
    autoGeneratePassword: true
    passwordSecretRef:
      key: password
      name: example-dbinstance
      namespace: upbound-system
    backupWindow: "09:46-10:16"
    maintenanceWindow: "Mon:00:00-Mon:03:00"
    publiclyAccessible: false
    skipFinalSnapshot: true
    storageEncrypted: true
    storageType: gp2
  providerConfigRef:
    name: nonexistingproviderconfig
  writeConnectionSecretToRef:
    name: example-dbinstance-out
    namespace: default
ulucinar commented 3 months ago

Hi @turkenf, @mergenci, Could you please take over this? Please ping me if help is needed.

mergenci commented 1 week ago

Thanks for the fix @ulucinar. It's working successfully. I've completed the PR description. Could you please review @sergenyalcin and @erhancagirici?