2 Copyright 2018 Intel Corporation.
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 http://www.apache.org/licenses/LICENSE-2.0
7 Unless required by applicable law or agreed to in writing, software
8 distributed under the License is distributed on an "AS IS" BASIS,
9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 See the License for the specific language governing permissions and
11 limitations under the License.
18 pkgerrors "github.com/pkg/errors"
19 "k8s.io/apimachinery/pkg/api/meta"
20 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22 "k8s.io/apimachinery/pkg/runtime/schema"
24 utils "github.com/onap/multicloud-k8s/src/k8splugin/internal"
25 "github.com/onap/multicloud-k8s/src/k8splugin/internal/config"
26 "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
27 "github.com/onap/multicloud-k8s/src/k8splugin/internal/plugin"
30 // Compile time check to see if genericPlugin implements the correct interface
31 var _ plugin.Reference = genericPlugin{}
33 // ExportedVariable is what we will look for when calling the generic plugin
34 var ExportedVariable genericPlugin
36 type genericPlugin struct {
39 // Create generic object in a specific Kubernetes cluster
40 func (g genericPlugin) Create(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
45 //Decode the yaml file to create a runtime.Object
46 unstruct := &unstructured.Unstructured{}
47 //Ignore the returned obj as we expect the data in unstruct
48 _, err := utils.DecodeYAML(yamlFilePath, unstruct)
50 return "", pkgerrors.Wrap(err, "Decode deployment object error")
53 dynClient := client.GetDynamicClient()
54 mapper := client.GetMapper()
56 gvk := unstruct.GroupVersionKind()
57 mapping, err := mapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version)
59 return "", pkgerrors.Wrap(err, "Mapping kind to resource error")
62 //Add the tracking label to all resources created here
63 labels := unstruct.GetLabels()
64 //Check if labels exist for this object
66 labels = map[string]string{}
68 labels[config.GetConfiguration().KubernetesLabelName] = client.GetInstanceID()
69 unstruct.SetLabels(labels)
71 // This checks if the resource we are creating has a podSpec in it
72 // Eg: Deployment, StatefulSet, Job etc..
73 // If a PodSpec is found, the label will be added to it too.
74 plugin.TagPodsIfPresent(unstruct, client.GetInstanceID())
76 gvr := mapping.Resource
77 var createdObj *unstructured.Unstructured
79 switch mapping.Scope.Name() {
80 case meta.RESTScopeNameNamespace:
81 createdObj, err = dynClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), unstruct, metav1.CreateOptions{})
82 case meta.RESTScopeNameRoot:
83 createdObj, err = dynClient.Resource(gvr).Create(context.TODO(), unstruct, metav1.CreateOptions{})
85 return "", pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + gvk.String())
89 return "", pkgerrors.Wrap(err, "Create object error")
92 return createdObj.GetName(), nil
95 // Update deployment object in a specific Kubernetes cluster
96 func (g genericPlugin) Update(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
101 //Decode the yaml file to create a runtime.Object
102 unstruct := &unstructured.Unstructured{}
103 //Ignore the returned obj as we expect the data in unstruct
104 _, err := utils.DecodeYAML(yamlFilePath, unstruct)
106 return "", pkgerrors.Wrap(err, "Decode deployment object error")
109 dynClient := client.GetDynamicClient()
110 mapper := client.GetMapper()
112 gvk := unstruct.GroupVersionKind()
113 mapping, err := mapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version)
115 return "", pkgerrors.Wrap(err, "Mapping kind to resource error")
118 //Add the tracking label to all resources created here
119 labels := unstruct.GetLabels()
120 //Check if labels exist for this object
122 labels = map[string]string{}
124 labels[config.GetConfiguration().KubernetesLabelName] = client.GetInstanceID()
125 unstruct.SetLabels(labels)
127 // This checks if the resource we are creating has a podSpec in it
128 // Eg: Deployment, StatefulSet, Job etc..
129 // If a PodSpec is found, the label will be added to it too.
130 plugin.TagPodsIfPresent(unstruct, client.GetInstanceID())
132 gvr := mapping.Resource
133 var updatedObj *unstructured.Unstructured
135 switch mapping.Scope.Name() {
136 case meta.RESTScopeNameNamespace:
137 updatedObj, err = dynClient.Resource(gvr).Namespace(namespace).Update(context.TODO(), unstruct, metav1.UpdateOptions{})
138 case meta.RESTScopeNameRoot:
139 updatedObj, err = dynClient.Resource(gvr).Update(context.TODO(), unstruct, metav1.UpdateOptions{})
141 return "", pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + gvk.String())
145 return "", pkgerrors.Wrap(err, "Update object error")
148 return updatedObj.GetName(), nil
151 // Get an existing resource hosted in a specific Kubernetes cluster
152 func (g genericPlugin) Get(resource helm.KubernetesResource,
153 namespace string, client plugin.KubernetesConnector) (string, error) {
155 namespace = "default"
158 dynClient := client.GetDynamicClient()
159 mapper := client.GetMapper()
161 mapping, err := mapper.RESTMapping(schema.GroupKind{
162 Group: resource.GVK.Group,
163 Kind: resource.GVK.Kind,
164 }, resource.GVK.Version)
166 return "", pkgerrors.Wrap(err, "Mapping kind to resource error")
169 gvr := mapping.Resource
170 opts := metav1.GetOptions{}
171 var unstruct *unstructured.Unstructured
172 switch mapping.Scope.Name() {
173 case meta.RESTScopeNameNamespace:
174 unstruct, err = dynClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), resource.Name, opts)
175 case meta.RESTScopeNameRoot:
176 unstruct, err = dynClient.Resource(gvr).Get(context.TODO(), resource.Name, opts)
178 return "", pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + resource.GVK.String())
182 return "", pkgerrors.Wrap(err, "Delete object error")
185 return unstruct.GetName(), nil
188 // List all existing resources of the GroupVersionKind
189 // TODO: Implement in seperate patch
190 func (g genericPlugin) List(gvk schema.GroupVersionKind, namespace string,
191 client plugin.KubernetesConnector) ([]helm.KubernetesResource, error) {
193 var returnData []helm.KubernetesResource
194 return returnData, nil
197 // Delete an existing resource hosted in a specific Kubernetes cluster
198 func (g genericPlugin) Delete(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) error {
200 namespace = "default"
203 dynClient := client.GetDynamicClient()
204 mapper := client.GetMapper()
206 mapping, err := mapper.RESTMapping(schema.GroupKind{
207 Group: resource.GVK.Group,
208 Kind: resource.GVK.Kind,
209 }, resource.GVK.Version)
211 return pkgerrors.Wrap(err, "Mapping kind to resource error")
214 gvr := mapping.Resource
215 deletePolicy := metav1.DeletePropagationBackground
216 opts := metav1.DeleteOptions{
217 PropagationPolicy: &deletePolicy,
220 switch mapping.Scope.Name() {
221 case meta.RESTScopeNameNamespace:
222 err = dynClient.Resource(gvr).Namespace(namespace).Delete(context.TODO(), resource.Name, opts)
223 case meta.RESTScopeNameRoot:
224 err = dynClient.Resource(gvr).Delete(context.TODO(), resource.Name, opts)
226 return pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + resource.GVK.String())
230 return pkgerrors.Wrap(err, "Delete object error")