diff options
Diffstat (limited to 'src/k8splugin/internal/app/instance.go')
-rw-r--r-- | src/k8splugin/internal/app/instance.go | 117 |
1 files changed, 76 insertions, 41 deletions
diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index d6eb91b4..a6e213c1 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -1,5 +1,6 @@ /* * Copyright 2018 Intel Corporation, Inc + * 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. @@ -19,6 +20,7 @@ package app import ( "encoding/json" "log" + "strings" "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm" @@ -26,7 +28,6 @@ import ( "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb" pkgerrors "github.com/pkg/errors" - corev1 "k8s.io/api/core/v1" ) // InstanceRequest contains the parameters needed for instantiation @@ -35,6 +36,7 @@ type InstanceRequest struct { RBName string `json:"rb-name"` RBVersion string `json:"rb-version"` ProfileName string `json:"profile-name"` + ReleaseName string `json:"release-name"` CloudRegion string `json:"cloud-region"` Labels map[string]string `json:"labels"` OverrideValues map[string]string `json:"override-values"` @@ -42,29 +44,21 @@ type InstanceRequest struct { // InstanceResponse contains the response from instantiation type InstanceResponse struct { - ID string `json:"id"` - Request InstanceRequest `json:"request"` - Namespace string `json:"namespace"` - Resources []helm.KubernetesResource `json:"resources"` - OverrideValues map[string]string `json:"override-values"` + ID string `json:"id"` + Request InstanceRequest `json:"request"` + Namespace string `json:"namespace"` + ReleaseName string `json:"release-name"` + Resources []helm.KubernetesResource `json:"resources"` } // InstanceMiniResponse contains the response from instantiation // It does NOT include the created resources. // Use the regular GET to get the created resources for a particular instance type InstanceMiniResponse struct { - ID string `json:"id"` - Request InstanceRequest `json:"request"` - Namespace string `json:"namespace"` -} - -// PodStatus defines the observed state of ResourceBundleState -type PodStatus struct { - Name string `json:"name"` - Namespace string `json:"namespace"` - Ready bool `json:"ready"` - Status corev1.PodStatus `json:"status,omitempty"` - IPAddresses []string `json:"ipaddresses"` + ID string `json:"id"` + Request InstanceRequest `json:"request"` + ReleaseName string `json:"release-name"` + Namespace string `json:"namespace"` } // InstanceStatus is what is returned when status is queried for an instance @@ -72,8 +66,7 @@ type InstanceStatus struct { Request InstanceRequest `json:"request"` Ready bool `json:"ready"` ResourceCount int32 `json:"resourceCount"` - PodStatuses []PodStatus `json:"podStatuses"` - ServiceStatuses []corev1.Service `json:"serviceStatuses"` + ResourcesStatus []ResourceStatus `json:"resourcesStatus"` } // InstanceManager is an interface exposes the instantiation functionality @@ -105,18 +98,16 @@ func (dk InstanceKey) String() string { // InstanceClient implements the InstanceManager interface // It will also be used to maintain some localized state type InstanceClient struct { - storeName string - tagInst string - tagInstStatus string + storeName string + tagInst string } // NewInstanceClient returns an instance of the InstanceClient // which implements the InstanceManager func NewInstanceClient() *InstanceClient { return &InstanceClient{ - storeName: "rbdef", - tagInst: "instance", - tagInstStatus: "instanceStatus", + storeName: "rbdef", + tagInst: "instance", } } @@ -145,7 +136,7 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { } //Execute the kubernetes create command - sortedTemplates, err := rb.NewProfileClient().Resolve(i.RBName, i.RBVersion, i.ProfileName, overrideValues) + sortedTemplates, releaseName, err := rb.NewProfileClient().Resolve(i.RBName, i.RBVersion, i.ProfileName, overrideValues, i.ReleaseName) if err != nil { return InstanceResponse{}, pkgerrors.Wrap(err, "Error resolving helm charts") } @@ -166,10 +157,11 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { //Compose the return response resp := InstanceResponse{ - ID: id, - Request: i, - Namespace: profile.Namespace, - Resources: createdResources, + ID: id, + Request: i, + Namespace: profile.Namespace, + ReleaseName: releaseName, + Resources: createdResources, } key := InstanceKey{ @@ -214,22 +206,64 @@ func (v *InstanceClient) Status(id string) (InstanceStatus, error) { ID: id, } - value, err := db.DBconn.Read(v.storeName, key, v.tagInstStatus) + value, err := db.DBconn.Read(v.storeName, key, v.tagInst) if err != nil { return InstanceStatus{}, pkgerrors.Wrap(err, "Get Instance") } //value is a byte array - if value != nil { - resp := InstanceStatus{} - err = db.DBconn.Unmarshal(value, &resp) + if value == nil { + return InstanceStatus{}, pkgerrors.New("Status is not available") + } + + resResp := InstanceResponse{} + err = db.DBconn.Unmarshal(value, &resResp) + if err != nil { + return InstanceStatus{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value") + } + + k8sClient := KubernetesClient{} + err = k8sClient.init(resResp.Request.CloudRegion, id) + if err != nil { + return InstanceStatus{}, pkgerrors.Wrap(err, "Getting CloudRegion Information") + } + + cumulatedErrorMsg := make([]string, 0) + podsStatus, err := k8sClient.getPodsByLabel(resResp.Namespace) + if err != nil { + cumulatedErrorMsg = append(cumulatedErrorMsg, err.Error()) + } + + generalStatus := make([]ResourceStatus, 0, len(resResp.Resources)) +Main: + for _, resource := range resResp.Resources { + for _, pod := range podsStatus { + if resource.GVK == pod.GVK && resource.Name == pod.Name { + continue Main //Don't double check pods if someone decided to define pod explicitly in helm chart + } + } + status, err := k8sClient.getResourceStatus(resource, resResp.Namespace) if err != nil { - return InstanceStatus{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value") + cumulatedErrorMsg = append(cumulatedErrorMsg, err.Error()) + } else { + generalStatus = append(generalStatus, status) } - return resp, nil + } + resp := InstanceStatus{ + Request: resResp.Request, + ResourceCount: int32(len(generalStatus) + len(podsStatus)), + Ready: false, //FIXME To determine readiness, some parsing of status fields is necessary + ResourcesStatus: append(generalStatus, podsStatus...), } - return InstanceStatus{}, pkgerrors.New("Status is not available") + if len(cumulatedErrorMsg) != 0 { + err = pkgerrors.New("Getting Resources Status:\n" + + strings.Join(cumulatedErrorMsg, "\n")) + return resp, err + } + //TODO Filter response content by requested verbosity (brief, ...)? + + return resp, nil } // List returns the instance for corresponding ID @@ -253,9 +287,10 @@ func (v *InstanceClient) List(rbname, rbversion, profilename string) ([]Instance } miniresp := InstanceMiniResponse{ - ID: resp.ID, - Request: resp.Request, - Namespace: resp.Namespace, + ID: resp.ID, + Request: resp.Request, + Namespace: resp.Namespace, + ReleaseName: resp.ReleaseName, } //Filter based on the accepted keys |