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/healthcheck/healthcheck.go | 157 ++++++++++++++++++++++ src/k8splugin/internal/healthcheck/kubeclient.go | 59 ++++++++ 2 files changed, 216 insertions(+) create mode 100644 src/k8splugin/internal/healthcheck/healthcheck.go create mode 100644 src/k8splugin/internal/healthcheck/kubeclient.go (limited to 'src/k8splugin/internal/healthcheck') diff --git a/src/k8splugin/internal/healthcheck/healthcheck.go b/src/k8splugin/internal/healthcheck/healthcheck.go new file mode 100644 index 00000000..341b1dba --- /dev/null +++ b/src/k8splugin/internal/healthcheck/healthcheck.go @@ -0,0 +1,157 @@ +/* +Copyright © 2021 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 + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package healthcheck + +import ( + "encoding/json" + + protorelease "k8s.io/helm/pkg/proto/hapi/release" + "k8s.io/helm/pkg/releasetesting" + + "github.com/onap/multicloud-k8s/src/k8splugin/internal/app" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" + log "github.com/onap/multicloud-k8s/src/k8splugin/internal/logutils" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/namegenerator" + + pkgerrors "github.com/pkg/errors" +) + +// HealthcheckState holds possible states of Healthcheck instance +type HealthcheckState string + +const ( + HcS_UNKNOWN HealthcheckState = "UNKNOWN" + HcS_STARTED HealthcheckState = "STARTED" + HcS_RUNNING HealthcheckState = "RUNNING" + HcS_SUCCESS HealthcheckState = "SUCCESS" + HcS_FAILURE HealthcheckState = "FAILURE" +) + +// InstanceHCManager interface exposes instance Healthcheck fuctionalities +type InstanceHCManager interface { + Create(instanceId string) (InstanceHCStatus, error) + Get(instanceId, healthcheckId string) (InstanceHCStatus, error) + List(instanceId string) ([]InstanceHCStatus, error) + Delete(instanceId, healthcheckId string) error +} + +// HealthcheckKey is used as the primary key in the db +type HealthcheckKey struct { + InstanceId string `json:"instance-id"` + HealthcheckId string `json:"healthcheck-id"` +} + +// We will use json marshalling to convert to string to +// preserve the underlying structure. +func (dk HealthcheckKey) String() string { + out, err := json.Marshal(dk) + if err != nil { + return "" + } + + return string(out) +} + +// InstanceHCClient implements InstanceHCManager +type InstanceHCClient struct { + storeName string + tagInst string +} + +// InstanceHCStatus holds healthcheck status +type InstanceHCStatus struct { + releasetesting.TestSuite + Id string + Status HealthcheckState +} + +func NewHCClient() *InstanceHCClient { + return &InstanceHCClient{ + storeName: "rbdef", + tagInst: "instanceHC", + } +} + +func (ihc InstanceHCClient) Create(instanceId string) (InstanceHCStatus, error) { + //Generate ID + id := namegenerator.Generate() + + //Determine Cloud Region and namespace + v := app.NewInstanceClient() + instance, err := v.Get(instanceId) + if err != nil { + return InstanceHCStatus{}, pkgerrors.Wrap(err, "Getting instance") + } + + //Prepare Environment, Request and Release structs + //TODO In future could derive params from request + client, err := NewKubeClient(instanceId, instance.Request.CloudRegion) + if err != nil { + return InstanceHCStatus{}, pkgerrors.Wrap(err, "Preparing KubeClient") + } + env := &releasetesting.Environment{ + Namespace: instance.Namespace, + KubeClient: client, + Parallel: false, + } + release := protorelease.Release{ + Name: instance.ReleaseName, + Hooks: instance.Hooks, + } + + //Run HC + testSuite, err := releasetesting.NewTestSuite(&release) + if err != nil { + log.Error("Error creating TestSuite", log.Fields{ + "Release": release, + }) + return InstanceHCStatus{}, pkgerrors.Wrap(err, "Creating TestSuite") + } + if err = testSuite.Run(env); err != nil { + log.Error("Error running TestSuite", log.Fields{ + "TestSuite": testSuite, + "Environment": env, + }) + return InstanceHCStatus{}, pkgerrors.Wrap(err, "Running TestSuite") + } + + //Save state + ihcs := InstanceHCStatus{ + TestSuite: *testSuite, + Id: id, + Status: HcS_STARTED, + } + key := HealthcheckKey{ + InstanceId: instance.ID, + HealthcheckId: id, + } + err = db.DBconn.Create(ihc.storeName, key, ihc.tagInst, ihcs) + if err != nil { + return ihcs, pkgerrors.Wrap(err, "Creating Instance DB Entry") + } + + return ihcs, nil +} + +func (ihc InstanceHCClient) Get(instanceId, healthcheckId string) (InstanceHCStatus, error) { + return InstanceHCStatus{}, nil +} + +func (ihc InstanceHCClient) Delete(instanceId, healthcheckId string) error { + return nil +} + +func (ihc InstanceHCClient) List(instanceId string) ([]InstanceHCStatus, error) { + return make([]InstanceHCStatus, 0), nil +} diff --git a/src/k8splugin/internal/healthcheck/kubeclient.go b/src/k8splugin/internal/healthcheck/kubeclient.go new file mode 100644 index 00000000..be4c6fcc --- /dev/null +++ b/src/k8splugin/internal/healthcheck/kubeclient.go @@ -0,0 +1,59 @@ +/* +Copyright © 2021 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 + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package healthcheck + +import ( + "k8s.io/helm/pkg/kube" + "k8s.io/helm/pkg/tiller/environment" + + "github.com/onap/multicloud-k8s/src/k8splugin/internal/app" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/config" + + pkgerrors "github.com/pkg/errors" +) + +//implements environment.KubeClient but overrides it so that +//custom labels can be injected into created resources +// using internal k8sClient +type KubeClientImpl struct { + environment.KubeClient + labels map[string]string + k app.KubernetesClient +} + +func NewKubeClient(instanceId, cloudRegion string) (*KubeClientImpl, error) { + k8sClient := app.KubernetesClient{} + err := k8sClient.Init(cloudRegion, instanceId) + if err != nil { + return nil, pkgerrors.Wrap(err, "Initializing k8sClient") + } + return &KubeClientImpl{ + labels: map[string]string{ + config.GetConfiguration().KubernetesLabelName: instanceId, + }, + KubeClient: kube.New(&k8sClient), + k: k8sClient, + }, nil +} + +/* FIXME +// Need to correct this later and provide override of Create method to use our k8sClient +// So that healthcheck hook resources would be labeled with vf-module data just like currently +// every k8splugin-managed resource is + +//Create function is overrided to label test resources with custom labels +func (kci *KubeClientImpl) Create(namespace string, reader io.Reader, timeout int64, shouldWait bool) error { + return nil +} +*/ -- cgit 1.2.3-korg