aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvamshi.nemalikonda <vn00480215@techmahindra.com>2020-07-24 12:05:51 +0000
committerRitu Sood <Ritu.Sood@intel.com>2020-08-26 15:59:47 +0000
commit9c942a11c14836630ba528b75bdcb2790045b91f (patch)
tree55404d7b7d8a4189c0eed99de39cb42e3a630341
parent16ca82713faf6678d4b7055130768541f86ea20c (diff)
Improve configure API to support k8s resource updations
Code fore review. Issue-ID: MULTICLOUD-1124 Change-Id: I6bb9786660f6760c15008132f1c254e7f9b39561 Signed-off-by: vamshi.nemalikonda <vn00480215@techmahindra.com> Improve configure API to support k8s resource updations create resource enabled. Issue-ID: MULTICLOUD-1124 Change-Id: I6bb9786660f6760c15008132f1c254e7f9b39561 Signed-off-by: vamshi.nemalikonda <vn00480215@techmahindra.com> Improve configure API to support k8s resource updations code improvements. Issue-ID: MULTICLOUD-1124 Change-Id: I6bb9786660f6760c15008132f1c254e7f9b39561 Signed-off-by: vamshi.nemalikonda <vn00480215@techmahindra.com> Improve configure API to support k8s resource updations fixing unit test failures. Issue-ID: MULTICLOUD-1124 Change-Id: I6bb9786660f6760c15008132f1c254e7f9b39561 Signed-off-by: vamshi.nemalikonda <vn00480215@techmahindra.com>
-rw-r--r--src/k8splugin/go.mod2
-rw-r--r--src/k8splugin/internal/app/client.go57
-rw-r--r--src/k8splugin/internal/app/config_backend.go11
-rw-r--r--src/k8splugin/internal/plugin/helpers.go3
-rw-r--r--src/k8splugin/mock_files/mock_plugins/mockplugin.go7
-rw-r--r--src/k8splugin/plugins/generic/plugin.go56
-rw-r--r--src/k8splugin/plugins/namespace/plugin.go5
-rw-r--r--src/k8splugin/plugins/service/plugin.go6
8 files changed, 145 insertions, 2 deletions
diff --git a/src/k8splugin/go.mod b/src/k8splugin/go.mod
index f924828d..d26de6ef 100644
--- a/src/k8splugin/go.mod
+++ b/src/k8splugin/go.mod
@@ -108,3 +108,5 @@ replace (
k8s.io/client-go => k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
k8s.io/cloud-provider => k8s.io/cloud-provider v0.0.0-20190409023720-1bc0c81fa51d
)
+
+go 1.13
diff --git a/src/k8splugin/internal/app/client.go b/src/k8splugin/internal/app/client.go
index d3e5081a..ed606444 100644
--- a/src/k8splugin/internal/app/client.go
+++ b/src/k8splugin/internal/app/client.go
@@ -181,6 +181,43 @@ func (k *KubernetesClient) createKind(resTempl helm.KubernetesResourceTemplate,
}, nil
}
+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
+}
+
func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesResourceTemplate,
namespace string) ([]helm.KubernetesResource, error) {
@@ -201,6 +238,26 @@ func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesReso
return createdResources, nil
}
+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
+}
+
func (k *KubernetesClient) deleteKind(resource helm.KubernetesResource, namespace string) error {
log.Warn("Deleting Resource", log.Fields{
"gvk": resource.GVK,
diff --git a/src/k8splugin/internal/app/config_backend.go b/src/k8splugin/internal/app/config_backend.go
index 6bc145ee..4cbe1da3 100644
--- a/src/k8splugin/internal/app/config_backend.go
+++ b/src/k8splugin/internal/app/config_backend.go
@@ -360,10 +360,17 @@ func scheduleResources(c chan configResourceList) {
//Move onto the next cloud region
continue
}
+ //assuming - the resource is not exist already
data.createdResources, err = k8sClient.createResources(data.resourceTemplates, inst.Namespace)
+ errCreate := err
if err != nil {
- log.Printf("Error Creating resources: %s", err.Error())
- continue
+ // assuming - the err represent the resource is already exist, so going for update
+ data.createdResources, err = k8sClient.updateResources(data.resourceTemplates, inst.Namespace)
+ if err != nil {
+ log.Printf("Error Creating resources: %s", errCreate.Error())
+ log.Printf("Error Updating resources: %s", err.Error())
+ continue
+ }
}
}
//TODO: Needs to add code to call Kubectl create
diff --git a/src/k8splugin/internal/plugin/helpers.go b/src/k8splugin/internal/plugin/helpers.go
index ad785ab7..19ff03ab 100644
--- a/src/k8splugin/internal/plugin/helpers.go
+++ b/src/k8splugin/internal/plugin/helpers.go
@@ -68,6 +68,9 @@ type Reference interface {
//Delete a kubernetes resource described in the provided namespace
Delete(resource helm.KubernetesResource, namespace string, client KubernetesConnector) error
+
+ //Update kubernetes resource based on the groupVersionKind and resourceName provided in resource
+ Update(yamlFilePath string, namespace string, client KubernetesConnector) (string, error)
}
// GetPluginByKind returns a plugin by the kind name
diff --git a/src/k8splugin/mock_files/mock_plugins/mockplugin.go b/src/k8splugin/mock_files/mock_plugins/mockplugin.go
index 0b5b851e..48133c3e 100644
--- a/src/k8splugin/mock_files/mock_plugins/mockplugin.go
+++ b/src/k8splugin/mock_files/mock_plugins/mockplugin.go
@@ -54,3 +54,10 @@ func (p mockPlugin) Delete(resource helm.KubernetesResource, namespace string, c
func (p mockPlugin) Get(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) (string, error) {
return resource.Name, nil
}
+
+// Update existing resources
+func (p mockPlugin) Update(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
+
+ return "", nil
+}
+
diff --git a/src/k8splugin/plugins/generic/plugin.go b/src/k8splugin/plugins/generic/plugin.go
index 0711466f..aa503097 100644
--- a/src/k8splugin/plugins/generic/plugin.go
+++ b/src/k8splugin/plugins/generic/plugin.go
@@ -91,6 +91,62 @@ func (g genericPlugin) Create(yamlFilePath string, namespace string, client plug
return createdObj.GetName(), nil
}
+// Update deployment object in a specific Kubernetes cluster
+func (g genericPlugin) Update(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
+ if namespace == "" {
+ namespace = "default"
+ }
+
+ //Decode the yaml file to create a runtime.Object
+ unstruct := &unstructured.Unstructured{}
+ //Ignore the returned obj as we expect the data in unstruct
+ _, err := utils.DecodeYAML(yamlFilePath, unstruct)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Decode deployment object error")
+ }
+
+ dynClient := client.GetDynamicClient()
+ mapper := client.GetMapper()
+
+ gvk := unstruct.GroupVersionKind()
+ mapping, err := mapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Mapping kind to resource error")
+ }
+
+ //Add the tracking label to all resources created here
+ labels := unstruct.GetLabels()
+ //Check if labels exist for this object
+ if labels == nil {
+ labels = map[string]string{}
+ }
+ labels[config.GetConfiguration().KubernetesLabelName] = client.GetInstanceID()
+ unstruct.SetLabels(labels)
+
+ // This checks if the resource we are creating has a podSpec in it
+ // Eg: Deployment, StatefulSet, Job etc..
+ // If a PodSpec is found, the label will be added to it too.
+ plugin.TagPodsIfPresent(unstruct, client.GetInstanceID())
+
+ gvr := mapping.Resource
+ var updatedObj *unstructured.Unstructured
+
+ switch mapping.Scope.Name() {
+ case meta.RESTScopeNameNamespace:
+ updatedObj, err = dynClient.Resource(gvr).Namespace(namespace).Update(unstruct, metav1.UpdateOptions{})
+ case meta.RESTScopeNameRoot:
+ updatedObj, err = dynClient.Resource(gvr).Update(unstruct, metav1.UpdateOptions{})
+ default:
+ return "", pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + gvk.String())
+ }
+
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Update object error")
+ }
+
+ return updatedObj.GetName(), nil
+}
+
// Get an existing resource hosted in a specific Kubernetes cluster
func (g genericPlugin) Get(resource helm.KubernetesResource,
namespace string, client plugin.KubernetesConnector) (string, error) {
diff --git a/src/k8splugin/plugins/namespace/plugin.go b/src/k8splugin/plugins/namespace/plugin.go
index feb2aa61..cfc395bb 100644
--- a/src/k8splugin/plugins/namespace/plugin.go
+++ b/src/k8splugin/plugins/namespace/plugin.go
@@ -107,3 +107,8 @@ func (p namespacePlugin) List(gvk schema.GroupVersionKind, namespace string, cli
return result, nil
}
+
+func (p namespacePlugin) Update(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
+
+ return "", nil
+}
diff --git a/src/k8splugin/plugins/service/plugin.go b/src/k8splugin/plugins/service/plugin.go
index 4c1f37be..28191767 100644
--- a/src/k8splugin/plugins/service/plugin.go
+++ b/src/k8splugin/plugins/service/plugin.go
@@ -137,3 +137,9 @@ func (p servicePlugin) Get(resource helm.KubernetesResource, namespace string, c
return service.Name, nil
}
+
+func (p servicePlugin) Update(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
+
+ return "", nil
+
+}