K8s-config-connector: Go client: incorrectly handling default values as empty/zero

Created on 11 Mar 2021  路  7Comments  路  Source: GoogleCloudPlatform/k8s-config-connector

Hi, I'm trying to use the Go client to create ComputeInstance resources but schema validation fails.
I'm not sure what I'm doing wrong, this is a small client I use to reproduce the error:

package main


import (
    "context"
    "fmt"
    "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1"
    "log"

    gcloud "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/compute/v1beta1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/runtime"
    _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
    ctrl "sigs.k8s.io/controller-runtime"
    "sigs.k8s.io/controller-runtime/pkg/client"
)

var kclient client.Client

func init() {
    kclient = GetClient()
}

func GetClient() client.Client {
    scheme := runtime.NewScheme()
    gcloud.AddToScheme(scheme)
    kubeconfig := ctrl.GetConfigOrDie()
    controllerClient, err := client.New(kubeconfig, client.Options{Scheme: scheme})
    if err != nil {
        log.Fatal(err)
        return nil
    }
    return controllerClient
}

func CreateComputeInstance(instance *gcloud.ComputeInstance) (err error) {
    err = kclient.Create(context.TODO(), instance)
    return err
}

func main() {
    testInstance := &gcloud.ComputeInstance{
        ObjectMeta: metav1.ObjectMeta{
            Name:        "test-instance",
            Namespace:   "config-connector",
            Labels:      make(map[string]string),
            Annotations: make(map[string]string),
        },
        Spec: gcloud.ComputeInstanceSpec{
            BootDisk: gcloud.BootDisk{
                AutoDelete: true,
                InitializeParams: gcloud.InitializeParams{
                    Size: 20,
                    SourceImageRef: v1alpha1.ResourceRef{
                        External: "debian-cloud/debian-9",
                    },
                    Type: "pd-ssd",
                },
            },
            MachineType: "n1-standard-1",
            NetworkInterface: []gcloud.NetworkInterface{
                {
                    NetworkRef: v1alpha1.ResourceRef{
                        Name: "default",
                    },
                    SubnetworkRef: v1alpha1.ResourceRef{
                        Name: "default",
                    },
                },
            },
            Zone: "europe-west1-b",
        },
    }

    err:= CreateComputeInstance(testInstance)
    fmt.Printf("Error %v", err)
}

result:

Error ComputeInstance.compute.cnrm.cloud.google.com "test-instance" is invalid: [: Invalid value: "": "spec.instanceTemplateRef" must validate one and only one schema (oneOf). Found none valid, spec.instanceTemplateRef.name: Required value, spec.confidentialInstanceConfig.enableConfidentialCompute: Required value, : Invalid value: "": "spec.serviceAccount.serviceAccountRef" must validate one and only one schema (oneOf). Found none valid, spec.serviceAccount.serviceAccountRef.name: Required value, spec.serviceAccount.scopes: Required value, : Invalid value: "": "spec.bootDisk.sourceDiskRef" must validate one and only one schema (oneOf). Found none valid, spec.bootDisk.sourceDiskRef.name: Required value, spec.bootDisk.diskEncryptionKeyRaw.valueFrom.secretKeyRef.name: Required value, spec.bootDisk.diskEncryptionKeyRaw.valueFrom.secretKeyRef.key: Required value, : Invalid value: "": "spec.bootDisk.kmsKeyRef" must validate one and only one schema (oneOf). Found none valid, spec.bootDisk.kmsKeyRef.name: Required value]

instead if I try to create the instance using kubectl and a yaml manifest i get no errors:

kubectl apply -f testinstance.yaml
computeinstance.compute.cnrm.cloud.google.com/test-instance created

testinstance.yaml file contents:

apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeInstance
metadata:
  name: test-instance
spec:
  machineType: n1-standard-1
  zone: europe-west1-b
  bootDisk:
    initializeParams:
      size: 24
      type: pd-ssd
      sourceImageRef:
        external: debian-cloud/debian-9
  networkInterface:
    - subnetworkRef:
        name: default

It seems like validation fails to interpret default values as empty/zero

PS. Go Client version: v1.41.0, config-connector-operator image: gcr.io/gke-release/cnrm/operator:f3b1091

bug

All 7 comments

Hi @averzicco, thanks for reporting this. It seems to be a bug on side. We will look into this and post an update when we have more information.

Hi @xiaobaitusi, do you have an estimation for when this bug will be resolved? Right now this is a blocker and I'm trying to understand if this tool can be used for a project or I should look for alternatives

Thanks

Hi @averzicco, we're currently working on a solution for this bug. I can't give you a precise ETA, but we'll have it fixed in the near future/few weeks. We're really sorry for this inconvenience, but appreciate that you are trying out our new go-clients!

Any update?

Hi, yes! @aw185176 and @averzicco, sorry we didn't update this thread when the feature was supported but as of release 1.46.0, the go-client uses a pointer type or build-in nil value so that unset fields are not defaulted incorrectly. Please try this out and let us know if it works for you.

Hi @caieo, yes, now works properly.

Thanks!

Awesome! I'm going to go ahead and close this issue, please feel free to open a new issue if you run into something else.

Was this page helpful?
0 / 5 - 0 ratings