diff options
Diffstat (limited to 'src/k8splugin/internal/app/client.go')
-rw-r--r-- | src/k8splugin/internal/app/client.go | 181 |
1 files changed, 130 insertions, 51 deletions
diff --git a/src/k8splugin/internal/app/client.go b/src/k8splugin/internal/app/client.go index ed606444..6762d1bc 100644 --- a/src/k8splugin/internal/app/client.go +++ b/src/k8splugin/internal/app/client.go @@ -1,5 +1,7 @@ /* Copyright 2018 Intel Corporation. +Copyright © 2020 Samsung Electronics + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -18,6 +20,7 @@ import ( "strings" "time" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/config" "github.com/onap/multicloud-k8s/src/k8splugin/internal/connection" "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm" log "github.com/onap/multicloud-k8s/src/k8splugin/internal/logutils" @@ -25,6 +28,9 @@ import ( pkgerrors "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery/cached/disk" "k8s.io/client-go/dynamic" @@ -43,6 +49,79 @@ type KubernetesClient struct { instanceID string } +// ResourceStatus holds Resource Runtime Data +type ResourceStatus struct { + Name string `json:"name"` + GVK schema.GroupVersionKind `json:"GVK"` + Status unstructured.Unstructured `json:"status"` +} + +// getPodsByLabel yields status of all pods under given instance ID +func (k *KubernetesClient) getPodsByLabel(namespace string) ([]ResourceStatus, error) { + client := k.GetStandardClient().CoreV1().Pods(namespace) + listOpts := metav1.ListOptions{ + LabelSelector: config.GetConfiguration().KubernetesLabelName + "=" + k.instanceID, + } + podList, err := client.List(listOpts) + if err != nil { + return nil, pkgerrors.Wrap(err, "Retrieving PodList from cluster") + } + resp := make([]ResourceStatus, 0, len(podList.Items)) + cumulatedErrorMsg := make([]string, 0) + for _, pod := range podList.Items { + podContent, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&pod) + if err != nil { + cumulatedErrorMsg = append(cumulatedErrorMsg, err.Error()) + continue + } + var unstrPod unstructured.Unstructured + unstrPod.SetUnstructuredContent(podContent) + podStatus := ResourceStatus{ + Name: unstrPod.GetName(), + GVK: schema.FromAPIVersionAndKind("v1", "Pod"), + Status: unstrPod, + } + resp = append(resp, podStatus) + } + if len(cumulatedErrorMsg) != 0 { + return resp, pkgerrors.New("Converting podContent to unstruct error:\n" + + strings.Join(cumulatedErrorMsg, "\n")) + } + return resp, nil +} + +// getResourcesStatus yields status of given generic resource +func (k *KubernetesClient) getResourceStatus(res helm.KubernetesResource, namespace string) (ResourceStatus, error) { + dynClient := k.GetDynamicClient() + mapper := k.GetMapper() + mapping, err := mapper.RESTMapping(schema.GroupKind{ + Group: res.GVK.Group, + Kind: res.GVK.Kind, + }, res.GVK.Version) + if err != nil { + return ResourceStatus{}, + pkgerrors.Wrap(err, "Preparing mapper based on GVK") + } + + gvr := mapping.Resource + opts := metav1.GetOptions{} + var unstruct *unstructured.Unstructured + switch mapping.Scope.Name() { + case meta.RESTScopeNameNamespace: + unstruct, err = dynClient.Resource(gvr).Namespace(namespace).Get(res.Name, opts) + case meta.RESTScopeNameRoot: + unstruct, err = dynClient.Resource(gvr).Get(res.Name, opts) + default: + return ResourceStatus{}, pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + res.GVK.String()) + } + + if err != nil { + return ResourceStatus{}, pkgerrors.Wrap(err, "Getting object status") + } + + return ResourceStatus{unstruct.GetName(), res.GVK, *unstruct}, nil +} + // getKubeConfig uses the connectivity client to get the kubeconfig based on the name // of the cloudregion. This is written out to a file. func (k *KubernetesClient) getKubeConfig(cloudregion string) (string, error) { @@ -182,40 +261,40 @@ func (k *KubernetesClient) createKind(resTempl helm.KubernetesResourceTemplate, } func (k *KubernetesClient) updateKind(resTempl helm.KubernetesResourceTemplate, - namespace string) (helm.KubernetesResource, error) { - - if _, err := os.Stat(resTempl.FilePath); os.IsNotExist(err) { - return helm.KubernetesResource{}, pkgerrors.New("File " + resTempl.FilePath + "does not exists") - } - - log.Info("Processing Kubernetes Resource", log.Fields{ - "filepath": resTempl.FilePath, - }) - - pluginImpl, err := plugin.GetPluginByKind(resTempl.GVK.Kind) - if err != nil { - return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error loading plugin") - } - - updatedResourceName, err := pluginImpl.Update(resTempl.FilePath, namespace, k) - if err != nil { - log.Error("Error Updating Resource", log.Fields{ - "error": err, - "gvk": resTempl.GVK, - "filepath": resTempl.FilePath, - }) - return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error in plugin "+resTempl.GVK.Kind+" plugin") - } - - log.Info("Updated Kubernetes Resource", log.Fields{ - "resource": updatedResourceName, - "gvk": resTempl.GVK, - }) - - return helm.KubernetesResource{ - GVK: resTempl.GVK, - Name: updatedResourceName, - }, nil + namespace string) (helm.KubernetesResource, error) { + + if _, err := os.Stat(resTempl.FilePath); os.IsNotExist(err) { + return helm.KubernetesResource{}, pkgerrors.New("File " + resTempl.FilePath + "does not exists") + } + + log.Info("Processing Kubernetes Resource", log.Fields{ + "filepath": resTempl.FilePath, + }) + + pluginImpl, err := plugin.GetPluginByKind(resTempl.GVK.Kind) + if err != nil { + return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error loading plugin") + } + + updatedResourceName, err := pluginImpl.Update(resTempl.FilePath, namespace, k) + if err != nil { + log.Error("Error Updating Resource", log.Fields{ + "error": err, + "gvk": resTempl.GVK, + "filepath": resTempl.FilePath, + }) + return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error in plugin "+resTempl.GVK.Kind+" plugin") + } + + log.Info("Updated Kubernetes Resource", log.Fields{ + "resource": updatedResourceName, + "gvk": resTempl.GVK, + }) + + return helm.KubernetesResource{ + GVK: resTempl.GVK, + Name: updatedResourceName, + }, nil } func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesResourceTemplate, @@ -239,23 +318,23 @@ func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesReso } func (k *KubernetesClient) updateResources(sortedTemplates []helm.KubernetesResourceTemplate, - namespace string) ([]helm.KubernetesResource, error) { - - err := k.ensureNamespace(namespace) - if err != nil { - return nil, pkgerrors.Wrap(err, "Creating Namespace") - } - - var updatedResources []helm.KubernetesResource - for _, resTempl := range sortedTemplates { - resUpdated, err := k.updateKind(resTempl, namespace) - if err != nil { - return nil, pkgerrors.Wrapf(err, "Error updating kind: %+v", resTempl.GVK) - } - updatedResources = append(updatedResources, resUpdated) - } - - return updatedResources, nil + namespace string) ([]helm.KubernetesResource, error) { + + err := k.ensureNamespace(namespace) + if err != nil { + return nil, pkgerrors.Wrap(err, "Creating Namespace") + } + + var updatedResources []helm.KubernetesResource + for _, resTempl := range sortedTemplates { + resUpdated, err := k.updateKind(resTempl, namespace) + if err != nil { + return nil, pkgerrors.Wrapf(err, "Error updating kind: %+v", resTempl.GVK) + } + updatedResources = append(updatedResources, resUpdated) + } + + return updatedResources, nil } func (k *KubernetesClient) deleteKind(resource helm.KubernetesResource, namespace string) error { |