summaryrefslogtreecommitdiffstats
path: root/src/k8splugin/internal/app/client.go
diff options
context:
space:
mode:
authorKonrad Bańka <k.banka@samsung.com>2020-09-25 16:35:02 +0200
committerKonrad Bańka <k.banka@samsung.com>2020-09-30 12:56:34 +0200
commitb5ccaabd6c3b06286cc845bfb910fc2bd1ab6419 (patch)
tree3d8922fc3e7fa444a27d2b0fb81c220819f8c637 /src/k8splugin/internal/app/client.go
parent603a68284970205fa95dec67d4f9b88ae99e8d2c (diff)
Fix Status API to actually provide instance status
Provide information about instance resources and Pods inside status response. Issue-ID: MULTICLOUD-1177 Signed-off-by: Konrad Bańka <k.banka@samsung.com> Change-Id: Iee6fd56120d091dddfa6b6d0e4aa7eb36d40e888
Diffstat (limited to 'src/k8splugin/internal/app/client.go')
-rw-r--r--src/k8splugin/internal/app/client.go181
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 {