Kerry Gunn
Kerry Gunn

Reputation: 177

Generic client.Get for custom Kubernetes GO operator

In a custom Kubernetes operator implemented with the operator-sdk in golang is it possible to call the custom API directly and retrieve the object as YAML?

For example. I have a custom resource

apiVersion: test.com/v1alpha1
kind: TEST
metadata::
  name: example-test
spec:
  replicas: 3
  randomname: value

I don't know ahead of time what the fields in the spec are going to be apart from replicas. So I am not able to create a go type that includes structs to hold the entries.

So rather than doing:

instance := &testv1alpha1.Test{}
err := r.client.Get(context.TODO(), nameSpaceName, instance)

I want to be able to do something like:

instanceYAML := genericContainer{}
err := r.client.GetGeneric(context.TODO(), nameSpaceName, instance)

and then parse the instanceYAML to check the entries.

Upvotes: 4

Views: 2503

Answers (3)

jmcgrath207
jmcgrath207

Reputation: 2037

Here is what I did in the Operator SDK to get a object from kubernetes.

Ref: https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/client/example_test.go#L57


func (r *ConfigDeploymentReconciler) findObjectsForConfigMap(configMap client.Object) []reconcile.Request {

    pod := &corev1.Pod{}

    _ = r.Client.Get(context.Background(), client.ObjectKey{
        Namespace: "prometheus",
        Name:      "prometheus-node-exporter-7vxqs",
    }, pod)

    fmt.Println("Got this pod", pod.String())

    return nil

}

Upvotes: 0

Aman Jain
Aman Jain

Reputation: 3045

Using the unstructured type client all the operation done on the CoreAPI resource can be done on the CustomResourceDefinition(CRD)

package util

import (
    "context"
    "encoding/json"
    "strconv"

    "github.com/go-logr/logr"
    "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    "k8s.io/apimachinery/pkg/runtime/schema"
    types "k8s.io/apimachinery/pkg/types"
    _ "k8s.io/client-go/plugin/pkg/client/auth"
    "sigs.k8s.io/controller-runtime/pkg/client"
)

var reqLogger logr.Logger

func CRUDonCRD(c client.Client) {
    u := createUnstructuredObject(c)
    GetCR(u, c)
    PatchCR(u, c, 1)
    DeleteCR(u, c)
}

func createUnstructuredObject(c client.Client) *unstructured.Unstructured {
    u := &unstructured.Unstructured{}

    u.SetGroupVersionKind(schema.GroupVersionKind{
        // Group:   "<crd group name>",
        // Kind:    "<crd kind>",
        // Version: "<crd version>",
        Group:   "com.cumulus.netq.operator.transport",
        Kind:    "TransportOperator",
        Version: "v1",
    })

    _ = c.Get(context.Background(), client.ObjectKey{
        // Namespace: "<namespace>",
        // Name:      "cr name",
        Namespace: "default",
        Name:      "transport-operator",
    }, u)

    return u
}

type patchStringValue struct {
    Op    string `json:"op"`
    Path  string `json:"path"`
    Value string `json:"value"`
}

func PatchCR(u *unstructured.Unstructured, c client.Client, replicaCount int) error {

    payload := []patchStringValue{{
        Op:    "replace",
        Path:  "/spec/replicas/replicasOpta",
        Value: strconv.Itoa(replicaCount),
    }}
    payloadBytes, _ := json.Marshal(payload)

    err := c.Patch(context.Background(), u, client.RawPatch(types.JSONPatchType, payloadBytes))
    if err != nil {
        reqLogger.Error(err, "error occured while patching")
    }

    reqLogger.Info("Patching is successful", "Patched Transport Operator Object", u)
    return err
}

func GetCR(u *unstructured.Unstructured, c client.Client) {

    // key := client.ObjectKey{Namespace: "default", Name: "<cr-name>"}
    key := client.ObjectKey{Namespace: "default", Name: "transport-operator"}
    err := c.Get(context.Background(), key, u)
    if err != nil {
        reqLogger.Error(err, "error occured while getting the resource")
    }

    reqLogger.Info("Got the resource", "Resource Object", u)
}

func DeleteCR(u *unstructured.Unstructured, c client.Client) {
    err := c.Delete(context.Background(), u)
    if err != nil {
        reqLogger.Error(err, "error occured while deleting the resource")
    }

    reqLogger.Info("Resource deleted", "Resource ", u)
}

Upvotes: 1

coderanger
coderanger

Reputation: 54191

This is called the "unstructured" client. The docs are pretty light so I recommend looking over the tests as examples https://github.com/kubernetes-sigs/controller-runtime/blob/ea32729106c995d9df310ac4731c2061490addfb/pkg/client/client_test.go#L1536-L1566

Upvotes: 4

Related Questions