From 4d8146a896bce46fcc41a5248d572b702c6d1268 Mon Sep 17 00:00:00 2001 From: fanmin shi Date: Mon, 26 Mar 2018 11:07:18 -0700 Subject: [PATCH] *: implement List and add necessary peices for it --- pkg/sdk/query/op.go | 6 ++++++ pkg/sdk/query/query.go | 25 +++++++++++++++++++++++++ pkg/util/k8sutil/k8sutil.go | 15 +++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/pkg/sdk/query/op.go b/pkg/sdk/query/op.go index 7c5890332bb..cd4b7163f6a 100644 --- a/pkg/sdk/query/op.go +++ b/pkg/sdk/query/op.go @@ -56,6 +56,12 @@ type ListOp struct { metaListOptions *metav1.ListOptions } +func NewListOp() *ListOp { + op := &ListOp{} + op.setDefaults() + return op +} + // ListOption configures ListOp. type ListOption func(*ListOp) diff --git a/pkg/sdk/query/query.go b/pkg/sdk/query/query.go index c7acaeef612..cbe3a68dd06 100644 --- a/pkg/sdk/query/query.go +++ b/pkg/sdk/query/query.go @@ -50,3 +50,28 @@ func Get(into sdkTypes.Object, opts ...GetOption) error { } return nil } + +// List retrieves the specified object list and unmarshals the retrieved data into the "into" object. +// "namespace" indicates which kubernetes namespace to look for the list of kubernetes objects. +// "into" is a sdkType.Object that must have +// "Kind" and "APIVersion" specified in its "TypeMeta" field +// Those are used to construct the underlying resource client. +// "opts" configures the List operation. +func List(namespace string, into sdkTypes.Object, opts ...ListOption) error { + gvk := into.GetObjectKind().GroupVersionKind() + apiVersion, kind := gvk.ToAPIVersionAndKind() + resourceClient, _, err := k8sclient.GetResourceClient(apiVersion, kind, namespace) + if err != nil { + return fmt.Errorf("failed to get resource client for (apiVersion:%s, kind:%s, ns:%s): %v", apiVersion, kind, namespace, err) + } + o := NewListOp() + o.applyOpts(opts) + l, err := resourceClient.List(*o.metaListOptions) + if err != nil { + return err + } + if err := k8sutil.RuntimeObjectIntoRuntimeObject(l, into); err != nil { + return fmt.Errorf("failed to unmarshal the retrieved data: %v", err) + } + return nil +} diff --git a/pkg/util/k8sutil/k8sutil.go b/pkg/util/k8sutil/k8sutil.go index fb6fd9cfaa3..b7d630fbd85 100644 --- a/pkg/util/k8sutil/k8sutil.go +++ b/pkg/util/k8sutil/k8sutil.go @@ -101,6 +101,21 @@ func UnstructuredIntoRuntimeObject(u *unstructured.Unstructured, into runtime.Ob return nil } +// RuntimeObjectIntoRuntimeObject unmarshalls an runtime.Object into a given runtime object +func RuntimeObjectIntoRuntimeObject(from runtime.Object, into runtime.Object) error { + b, err := json.Marshal(from) + if err != nil { + return err + } + gvk := from.GetObjectKind().GroupVersionKind() + decoder := decoder(gvk.GroupVersion()) + _, _, err = decoder.Decode(b, &gvk, into) + if err != nil { + return fmt.Errorf("failed to decode json data with gvk(%v): %v", gvk.String(), err) + } + return nil +} + // GetNameAndNamespace extracts the name and namespace from the given runtime.Object // and returns a error if any of those is missing. func GetNameAndNamespace(object runtime.Object) (string, string, error) {