2 * Copyright 2019 Intel Corporation, Inc
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 utils "github.com/onap/multicloud-k8s/src/k8splugin/internal"
24 "github.com/onap/multicloud-k8s/src/k8splugin/internal/config"
25 "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
27 pkgerrors "github.com/pkg/errors"
28 corev1 "k8s.io/api/core/v1"
29 "k8s.io/apimachinery/pkg/api/meta"
30 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
31 "k8s.io/apimachinery/pkg/runtime"
32 "k8s.io/apimachinery/pkg/runtime/schema"
33 "k8s.io/client-go/dynamic"
34 "k8s.io/client-go/kubernetes"
37 // KubernetesConnector is an interface that is expected to be implemented
38 // by any code that calls the plugin framework functions.
39 // It implements methods that are needed by the plugins to get Kubernetes
40 // clients and other information needed to interface with Kubernetes
41 type KubernetesConnector interface {
42 //GetMapper returns the RESTMapper that was created for this client
43 GetMapper() meta.RESTMapper
45 //GetDynamicClient returns the dynamic client that is needed for
46 //unstructured REST calls to the apiserver
47 GetDynamicClient() dynamic.Interface
49 // GetStandardClient returns the standard client that can be used to handle
50 // standard kubernetes kinds
51 GetStandardClient() kubernetes.Interface
53 //GetInstanceID returns the InstanceID for tracking during creation
54 GetInstanceID() string
57 // Reference is the interface that is implemented
58 type Reference interface {
59 //Create a kubernetes resource described by the yaml in yamlFilePath
60 Create(yamlFilePath string, namespace string, client KubernetesConnector) (string, error)
62 //Get a kubernetes resource based on the groupVersionKind and resourceName provided in resource
63 Get(resource helm.KubernetesResource, namespace string, client KubernetesConnector) (string, error)
65 //List all resources of the specified GroupVersionKind in the given namespace
66 //If gvk is empty, the plugin will return all supported objects in the namespace
67 List(gvk schema.GroupVersionKind, namespace string, client KubernetesConnector) ([]helm.KubernetesResource, error)
69 //Delete a kubernetes resource described in the provided namespace
70 Delete(resource helm.KubernetesResource, namespace string, client KubernetesConnector) error
72 //Update kubernetes resource based on the groupVersionKind and resourceName provided in resource
73 Update(yamlFilePath string, namespace string, client KubernetesConnector) (string, error)
76 // GetPluginByKind returns a plugin by the kind name
77 // If plugin does not exist, it will return the generic plugin
78 // TODO: Change this once we have a plugin registration mechanism
79 func GetPluginByKind(kind string) (Reference, error) {
81 typePlugin, ok := utils.LoadedPlugins[strings.ToLower(kind)]
83 log.Println("No plugin for kind " + kind + " found. Using generic Plugin")
84 typePlugin, ok = utils.LoadedPlugins["generic"]
86 return nil, pkgerrors.New("No generic plugin found")
90 symbol, err := typePlugin.Lookup("ExportedVariable")
92 return nil, pkgerrors.Wrap(err, "No ExportedVariable symbol found")
95 //Assert if it implements the PluginReference interface
96 pluginImpl, ok := symbol.(Reference)
98 return nil, pkgerrors.New("ExportedVariable does not implement plugins.Reference interface type")
101 return pluginImpl, nil
104 // TagPodsIfPresent finds the PodTemplateSpec from any workload
105 // object that contains it and changes the spec to include the tag label
106 func TagPodsIfPresent(unstruct *unstructured.Unstructured, tag string) {
108 spec, ok := unstruct.Object["spec"].(map[string]interface{})
110 log.Println("Error converting spec to map")
114 template, ok := spec["template"].(map[string]interface{})
116 log.Println("Error converting template to map")
120 //Attempt to convert the template to a podtemplatespec.
121 //This is to check if we have any pods being created.
122 podTemplateSpec := &corev1.PodTemplateSpec{}
123 err := runtime.DefaultUnstructuredConverter.FromUnstructured(template, podTemplateSpec)
125 log.Println("Did not find a podTemplateSpec: " + err.Error())
129 labels := podTemplateSpec.GetLabels()
131 labels = map[string]string{}
133 labels[config.GetConfiguration().KubernetesLabelName] = tag
134 podTemplateSpec.SetLabels(labels)
136 updatedTemplate, err := runtime.DefaultUnstructuredConverter.ToUnstructured(podTemplateSpec)
139 spec["template"] = updatedTemplate