From 22a37f42a54c1acd2f095bc559ab03745e5ae7f9 Mon Sep 17 00:00:00 2001 From: Konrad Bańka Date: Thu, 25 Feb 2021 00:08:05 +0100 Subject: Provide Healthcheck API MVP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements basic functionality of running starting Healthcheck. Results can be inspected so-far without dedicated API, by using, for example, Query API. Issue-ID: MULTICLOUD-1233 Signed-off-by: Konrad Bańka Change-Id: Ia4d96d936d573173d7d8f41e6c39d059bf5f8b1f --- src/k8splugin/internal/app/client.go | 39 ++++++++++++++++++++++++++-- src/k8splugin/internal/app/client_test.go | 2 +- src/k8splugin/internal/app/config_backend.go | 6 ++--- src/k8splugin/internal/app/instance.go | 14 ++++++---- src/k8splugin/internal/app/instance_test.go | 2 +- 5 files changed, 51 insertions(+), 12 deletions(-) (limited to 'src/k8splugin/internal/app') diff --git a/src/k8splugin/internal/app/client.go b/src/k8splugin/internal/app/client.go index f0edf8c9..85fefe69 100644 --- a/src/k8splugin/internal/app/client.go +++ b/src/k8splugin/internal/app/client.go @@ -16,6 +16,7 @@ limitations under the License. package app import ( + "io/ioutil" "os" "strings" "time" @@ -32,9 +33,11 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" "k8s.io/client-go/discovery/cached/disk" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" "k8s.io/client-go/tools/clientcmd" ) @@ -42,6 +45,8 @@ import ( // KubernetesClient encapsulates the different clients' interfaces // we need when interacting with a Kubernetes cluster type KubernetesClient struct { + rawConfig clientcmd.ClientConfig + restConfig *rest.Config clientSet kubernetes.Interface dynamicClient dynamic.Interface discoverClient *disk.CachedDiscoveryClient @@ -168,8 +173,8 @@ func (k *KubernetesClient) getKubeConfig(cloudregion string) (string, error) { return kubeConfigPath, nil } -// init loads the Kubernetes configuation values stored into the local configuration file -func (k *KubernetesClient) init(cloudregion string, iid string) error { +// Init loads the Kubernetes configuation values stored into the local configuration file +func (k *KubernetesClient) Init(cloudregion string, iid string) error { if cloudregion == "" { return pkgerrors.New("Cloudregion is empty") } @@ -209,6 +214,21 @@ func (k *KubernetesClient) init(cloudregion string, iid string) error { } k.restMapper = restmapper.NewDeferredDiscoveryRESTMapper(k.discoverClient) + k.restConfig = config + + //Spawn ClientConfig + kubeFile, err := os.Open(configPath) + if err != nil { + return pkgerrors.Wrap(err, "Opening kubeConfig") + } + kubeData, err := ioutil.ReadAll(kubeFile) + if err != nil { + return pkgerrors.Wrap(err, "Reading kubeConfig") + } + k.rawConfig, err = clientcmd.NewClientConfigFromBytes(kubeData) + if err != nil { + return pkgerrors.Wrap(err, "Creating rawConfig") + } return nil } @@ -423,3 +443,18 @@ func (k *KubernetesClient) GetStandardClient() kubernetes.Interface { func (k *KubernetesClient) GetInstanceID() string { return k.instanceID } + +//Following set of methods are implemented so that KubernetesClient +//implements genericclioptions.RESTClientGetter interface +func (k *KubernetesClient) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { + return k.discoverClient, nil +} +func (k *KubernetesClient) ToRESTMapper() (meta.RESTMapper, error) { + return k.GetMapper(), nil +} +func (k *KubernetesClient) ToRawKubeConfigLoader() clientcmd.ClientConfig { + return k.rawConfig +} +func (k *KubernetesClient) ToRESTConfig() (*rest.Config, error) { + return k.restConfig, nil +} diff --git a/src/k8splugin/internal/app/client_test.go b/src/k8splugin/internal/app/client_test.go index 7001d9e2..6db541a4 100644 --- a/src/k8splugin/internal/app/client_test.go +++ b/src/k8splugin/internal/app/client_test.go @@ -72,7 +72,7 @@ func TestInit(t *testing.T) { kubeClient := KubernetesClient{} // Refer to the connection via its name - err = kubeClient.init("mock_connection", "abcdefg") + err = kubeClient.Init("mock_connection", "abcdefg") if err != nil { t.Fatalf("TestGetKubeClient returned an error (%s)", err) } diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go index 5771c83f..e2f802c7 100644 --- a/src/k8splugin/internal/app/config_backend.go +++ b/src/k8splugin/internal/app/config_backend.go @@ -391,7 +391,7 @@ func scheduleResources(c chan configResourceList) { log.Printf("[scheduleResources]: POST %v %v", data.profile, data.resourceTemplates) for _, inst := range resp { k8sClient := KubernetesClient{} - err = k8sClient.init(inst.Request.CloudRegion, inst.ID) + err = k8sClient.Init(inst.Request.CloudRegion, inst.ID) if err != nil { log.Printf("Getting CloudRegion Information: %s", err.Error()) //Move onto the next cloud region @@ -418,7 +418,7 @@ func scheduleResources(c chan configResourceList) { log.Printf("[scheduleResources]: DELETE %v %v", data.profile, data.resourceTemplates) for _, inst := range resp { k8sClient := KubernetesClient{} - err = k8sClient.init(inst.Request.CloudRegion, inst.ID) + err = k8sClient.Init(inst.Request.CloudRegion, inst.ID) if err != nil { log.Printf("Getting CloudRegion Information: %s", err.Error()) //Move onto the next cloud region @@ -488,7 +488,7 @@ var resolve = func(rbName, rbVersion, profileName string, p Config) (configResou profile.ReleaseName) chartPath := filepath.Join(chartBasePath, t.ChartName) - resTemplates, err = helmClient.GenerateKubernetesArtifacts(chartPath, + resTemplates, _, err = helmClient.GenerateKubernetesArtifacts(chartPath, []string{outputfile.Name()}, nil) if err != nil { diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index b11283e0..337ce687 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -22,6 +22,8 @@ import ( "log" "strings" + protorelease "k8s.io/helm/pkg/proto/hapi/release" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm" "github.com/onap/multicloud-k8s/src/k8splugin/internal/namegenerator" @@ -49,6 +51,7 @@ type InstanceResponse struct { Namespace string `json:"namespace"` ReleaseName string `json:"release-name"` Resources []helm.KubernetesResource `json:"resources"` + Hooks []*protorelease.Hook `json:"hooks"` } // InstanceMiniResponse contains the response from instantiation @@ -147,7 +150,7 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { } //Execute the kubernetes create command - sortedTemplates, releaseName, err := rb.NewProfileClient().Resolve(i.RBName, i.RBVersion, i.ProfileName, overrideValues, i.ReleaseName) + sortedTemplates, hookList, 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") } @@ -156,7 +159,7 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { id := namegenerator.Generate() k8sClient := KubernetesClient{} - err = k8sClient.init(i.CloudRegion, id) + err = k8sClient.Init(i.CloudRegion, id) if err != nil { return InstanceResponse{}, pkgerrors.Wrap(err, "Getting CloudRegion Information") } @@ -173,6 +176,7 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) { Namespace: profile.Namespace, ReleaseName: releaseName, Resources: createdResources, + Hooks: hookList, } key := InstanceKey{ @@ -230,7 +234,7 @@ func (v *InstanceClient) Query(id, apiVersion, kind, name, labels string) (Insta } k8sClient := KubernetesClient{} - err = k8sClient.init(resResp.Request.CloudRegion, id) + err = k8sClient.Init(resResp.Request.CloudRegion, id) if err != nil { return InstanceStatus{}, pkgerrors.Wrap(err, "Getting CloudRegion Information") } @@ -296,7 +300,7 @@ func (v *InstanceClient) Status(id string) (InstanceStatus, error) { } k8sClient := KubernetesClient{} - err = k8sClient.init(resResp.Request.CloudRegion, id) + err = k8sClient.Init(resResp.Request.CloudRegion, id) if err != nil { return InstanceStatus{}, pkgerrors.Wrap(err, "Getting CloudRegion Information") } @@ -432,7 +436,7 @@ func (v *InstanceClient) Delete(id string) error { } k8sClient := KubernetesClient{} - err = k8sClient.init(inst.Request.CloudRegion, inst.ID) + err = k8sClient.Init(inst.Request.CloudRegion, inst.ID) if err != nil { return pkgerrors.Wrap(err, "Getting CloudRegion Information") } diff --git a/src/k8splugin/internal/app/instance_test.go b/src/k8splugin/internal/app/instance_test.go index b79cf388..2711a52f 100644 --- a/src/k8splugin/internal/app/instance_test.go +++ b/src/k8splugin/internal/app/instance_test.go @@ -179,7 +179,7 @@ func TestInstanceCreate(t *testing.T) { log.Println(ir) if len(ir.Resources) == 0 { - t.Fatalf("TestInstanceCreate returned empty data (%s)", ir) + t.Fatalf("TestInstanceCreate returned empty data (%+v)", ir) } }) -- cgit 1.2.3-korg