aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/k8splugin/plugins')
-rw-r--r--src/k8splugin/plugins/generic/plugin.go68
-rw-r--r--src/k8splugin/plugins/namespace/plugin.go60
-rw-r--r--src/k8splugin/plugins/namespace/plugin_test.go106
-rw-r--r--src/k8splugin/plugins/network/plugin.go39
-rw-r--r--src/k8splugin/plugins/network/plugin_test.go33
-rw-r--r--src/k8splugin/plugins/service/plugin.go58
-rw-r--r--src/k8splugin/plugins/service/plugin_test.go141
7 files changed, 321 insertions, 184 deletions
diff --git a/src/k8splugin/plugins/generic/plugin.go b/src/k8splugin/plugins/generic/plugin.go
index 9ecaf68c..31c65d05 100644
--- a/src/k8splugin/plugins/generic/plugin.go
+++ b/src/k8splugin/plugins/generic/plugin.go
@@ -23,15 +23,18 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
utils "k8splugin/internal"
- "k8splugin/internal/app"
+ "k8splugin/internal/plugin"
"k8splugin/internal/helm"
)
+// ExportedVariable is what we will look for when calling the generic plugin
+var ExportedVariable genericPlugin
+
type genericPlugin struct {
}
// Create deployment object in a specific Kubernetes cluster
-func (g genericPlugin) Create(yamlFilePath string, namespace string, client *app.KubernetesClient) (string, error) {
+func (g genericPlugin) Create(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
if namespace == "" {
namespace = "default"
}
@@ -72,15 +75,58 @@ func (g genericPlugin) Create(yamlFilePath string, namespace string, client *app
return createdObj.GetName(), nil
}
-// Delete an existing deployment hosted in a specific Kubernetes cluster
-func (g genericPlugin) Delete(resource helm.KubernetesResource, namespace string, client *app.KubernetesClient) error {
+// Get an existing resource hosted in a specific Kubernetes cluster
+func (g genericPlugin) Get(resource helm.KubernetesResource,
+ namespace string, client plugin.KubernetesConnector) (string, error) {
if namespace == "" {
namespace = "default"
}
- deletePolicy := metav1.DeletePropagationForeground
- opts := &metav1.DeleteOptions{
- PropagationPolicy: &deletePolicy,
+ dynClient := client.GetDynamicClient()
+ mapper := client.GetMapper()
+
+ mapping, err := mapper.RESTMapping(schema.GroupKind{
+ Group: resource.GVK.Group,
+ Kind: resource.GVK.Kind,
+ }, resource.GVK.Version)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Mapping kind to resource error")
+ }
+
+ gvr := mapping.Resource
+ log.Printf("Using gvr: %s, %s, %s", gvr.Group, gvr.Version, gvr.Resource)
+
+ opts := metav1.GetOptions{}
+ var unstruct *unstructured.Unstructured
+ switch mapping.Scope.Name() {
+ case meta.RESTScopeNameNamespace:
+ unstruct, err = dynClient.Resource(gvr).Namespace(namespace).Get(resource.Name, opts)
+ case meta.RESTScopeNameRoot:
+ unstruct, err = dynClient.Resource(gvr).Get(resource.Name, opts)
+ default:
+ return "", pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + resource.GVK.String())
+ }
+
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Delete object error")
+ }
+
+ return unstruct.GetName(), nil
+}
+
+// List all existing resources of the GroupVersionKind
+// TODO: Implement in seperate patch
+func (g genericPlugin) List(gvk schema.GroupVersionKind, namespace string,
+ client plugin.KubernetesConnector) ([]helm.KubernetesResource, error) {
+
+ var returnData []helm.KubernetesResource
+ return returnData, nil
+}
+
+// Delete an existing resource hosted in a specific Kubernetes cluster
+func (g genericPlugin) Delete(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) error {
+ if namespace == "" {
+ namespace = "default"
}
dynClient := client.GetDynamicClient()
@@ -97,6 +143,11 @@ func (g genericPlugin) Delete(resource helm.KubernetesResource, namespace string
gvr := mapping.Resource
log.Printf("Using gvr: %s, %s, %s", gvr.Group, gvr.Version, gvr.Resource)
+ deletePolicy := metav1.DeletePropagationForeground
+ opts := &metav1.DeleteOptions{
+ PropagationPolicy: &deletePolicy,
+ }
+
switch mapping.Scope.Name() {
case meta.RESTScopeNameNamespace:
err = dynClient.Resource(gvr).Namespace(namespace).Delete(resource.Name, opts)
@@ -111,6 +162,3 @@ func (g genericPlugin) Delete(resource helm.KubernetesResource, namespace string
}
return nil
}
-
-// ExportedVariable is what we will look for when calling the generic plugin
-var ExportedVariable genericPlugin
diff --git a/src/k8splugin/plugins/namespace/plugin.go b/src/k8splugin/plugins/namespace/plugin.go
index 6f823918..2d5d2ab8 100644
--- a/src/k8splugin/plugins/namespace/plugin.go
+++ b/src/k8splugin/plugins/namespace/plugin.go
@@ -16,39 +16,42 @@ package main
import (
"log"
- "k8s.io/client-go/kubernetes"
-
pkgerrors "github.com/pkg/errors"
-
coreV1 "k8s.io/api/core/v1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
utils "k8splugin/internal"
+ "k8splugin/internal/helm"
+ "k8splugin/internal/plugin"
)
+// ExportedVariable is what we will look for when calling the plugin
+var ExportedVariable namespacePlugin
+
+type namespacePlugin struct {
+}
+
// Create a namespace object in a specific Kubernetes cluster
-func Create(data *utils.ResourceData, client kubernetes.Interface) (string, error) {
- namespace := &coreV1.Namespace{
+func (p namespacePlugin) Create(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
+ namespaceObj := &coreV1.Namespace{
ObjectMeta: metaV1.ObjectMeta{
- Name: data.Namespace,
+ Name: namespace,
},
}
- _, err := client.CoreV1().Namespaces().Create(namespace)
+ _, err := client.GetStandardClient().CoreV1().Namespaces().Create(namespaceObj)
if err != nil {
return "", pkgerrors.Wrap(err, "Create Namespace error")
}
- log.Printf("Namespace (%s) created", data.Namespace)
+ log.Printf("Namespace (%s) created", namespace)
- return data.Namespace, nil
+ return namespace, nil
}
// Get an existing namespace hosted in a specific Kubernetes cluster
-func Get(name string, namespace string, client kubernetes.Interface) (string, error) {
+func (p namespacePlugin) Get(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) (string, error) {
opts := metaV1.GetOptions{}
- opts.APIVersion = "apps/v1"
- opts.Kind = "Deployment"
-
- ns, err := client.CoreV1().Namespaces().Get(name, opts)
+ ns, err := client.GetStandardClient().CoreV1().Namespaces().Get(resource.Name, opts)
if err != nil {
return "", pkgerrors.Wrap(err, "Get Namespace error")
}
@@ -57,14 +60,14 @@ func Get(name string, namespace string, client kubernetes.Interface) (string, er
}
// Delete an existing namespace hosted in a specific Kubernetes cluster
-func Delete(name string, namespace string, client kubernetes.Interface) error {
+func (p namespacePlugin) Delete(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) error {
deletePolicy := metaV1.DeletePropagationForeground
opts := &metaV1.DeleteOptions{
PropagationPolicy: &deletePolicy,
}
- log.Println("Deleting namespace: " + name)
- if err := client.CoreV1().Namespaces().Delete(name, opts); err != nil {
+ log.Println("Deleting namespace: " + resource.Name)
+ if err := client.GetStandardClient().CoreV1().Namespaces().Delete(resource.Name, opts); err != nil {
return pkgerrors.Wrap(err, "Delete namespace error")
}
@@ -72,23 +75,30 @@ func Delete(name string, namespace string, client kubernetes.Interface) error {
}
// List of existing namespaces hosted in a specific Kubernetes cluster
-func List(namespace string, client kubernetes.Interface) ([]string, error) {
+// This plugin ignores both gvk and namespace arguments
+func (p namespacePlugin) List(gvk schema.GroupVersionKind, namespace string, client plugin.KubernetesConnector) ([]helm.KubernetesResource, error) {
opts := metaV1.ListOptions{
Limit: utils.ResourcesListLimit,
}
- opts.APIVersion = "apps/v1"
- opts.Kind = "Namespace"
- list, err := client.CoreV1().Namespaces().List(opts)
+ list, err := client.GetStandardClient().CoreV1().Namespaces().List(opts)
if err != nil {
return nil, pkgerrors.Wrap(err, "Get Namespace list error")
}
- result := make([]string, 0, utils.ResourcesListLimit)
+ result := make([]helm.KubernetesResource, 0, utils.ResourcesListLimit)
if list != nil {
- for _, deployment := range list.Items {
- log.Printf("%v", deployment.Name)
- result = append(result, deployment.Name)
+ for _, ns := range list.Items {
+ log.Printf("%v", ns.Name)
+ result = append(result,
+ helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Namespace",
+ },
+ Name: ns.Name,
+ })
}
}
diff --git a/src/k8splugin/plugins/namespace/plugin_test.go b/src/k8splugin/plugins/namespace/plugin_test.go
index 0019df1c..9e57b971 100644
--- a/src/k8splugin/plugins/namespace/plugin_test.go
+++ b/src/k8splugin/plugins/namespace/plugin_test.go
@@ -18,36 +18,54 @@ import (
"strings"
"testing"
- utils "k8splugin/internal"
+ "k8splugin/internal/helm"
coreV1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/meta"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- testclient "k8s.io/client-go/kubernetes/fake"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/client-go/dynamic"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/kubernetes/fake"
)
+type TestKubernetesConnector struct {
+ object runtime.Object
+}
+
+func (t TestKubernetesConnector) GetMapper() meta.RESTMapper {
+ return nil
+}
+
+func (t TestKubernetesConnector) GetDynamicClient() dynamic.Interface {
+ return nil
+}
+
+func (t TestKubernetesConnector) GetStandardClient() kubernetes.Interface {
+ return fake.NewSimpleClientset(t.object)
+}
+
func TestCreateNamespace(t *testing.T) {
- namespace := "test1"
testCases := []struct {
label string
- input *utils.ResourceData
- clientOutput *coreV1.Namespace
+ input string
+ object *coreV1.Namespace
expectedResult string
expectedError string
}{
{
- label: "Successfully create a namespace",
- input: &utils.ResourceData{
- Namespace: namespace,
- },
- clientOutput: &coreV1.Namespace{},
- expectedResult: namespace,
+ label: "Successfully create a namespace",
+ input: "test1",
+ object: &coreV1.Namespace{},
+ expectedResult: "test1",
},
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- result, err := Create(testCase.input, client)
+ result, err := namespacePlugin{}.Create("", testCase.input, client)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Create method return an un-expected (%s)", err)
@@ -72,39 +90,47 @@ func TestCreateNamespace(t *testing.T) {
}
func TestListNamespace(t *testing.T) {
- namespace := "test1"
testCases := []struct {
label string
input string
- clientOutput *coreV1.NamespaceList
- expectedResult []string
+ object *coreV1.NamespaceList
+ expectedResult []helm.KubernetesResource
}{
{
label: "Sucessfully to display an empty namespace list",
- input: namespace,
- clientOutput: &coreV1.NamespaceList{},
- expectedResult: []string{},
+ input: "",
+ object: &coreV1.NamespaceList{},
+ expectedResult: []helm.KubernetesResource{},
},
{
label: "Sucessfully to display a list of existing namespaces",
- input: namespace,
- clientOutput: &coreV1.NamespaceList{
+ input: "test1",
+ object: &coreV1.NamespaceList{
Items: []coreV1.Namespace{
coreV1.Namespace{
ObjectMeta: metaV1.ObjectMeta{
- Name: namespace,
+ Name: "test1",
},
},
},
},
- expectedResult: []string{namespace},
+ expectedResult: []helm.KubernetesResource{
+ {
+ Name: "test1",
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"},
+ },
+ },
},
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- result, err := List(testCase.input, client)
+ result, err := namespacePlugin{}.List(schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Namespace",
+ }, testCase.input, client)
if err != nil {
t.Fatalf("List method returned an error (%s)", err)
} else {
@@ -113,7 +139,7 @@ func TestListNamespace(t *testing.T) {
}
if !reflect.DeepEqual(testCase.expectedResult, result) {
- t.Fatalf("List method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult)
+ t.Fatalf("List method returned: \n%+v\n and it was expected: \n%+v", result, testCase.expectedResult)
}
}
})
@@ -122,14 +148,14 @@ func TestListNamespace(t *testing.T) {
func TestDeleteNamespace(t *testing.T) {
testCases := []struct {
- label string
- input map[string]string
- clientOutput *coreV1.Namespace
+ label string
+ input map[string]string
+ object *coreV1.Namespace
}{
{
label: "Sucessfully to delete an existing namespace",
input: map[string]string{"name": "test-name", "namespace": "test-namespace"},
- clientOutput: &coreV1.Namespace{
+ object: &coreV1.Namespace{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-name",
},
@@ -138,9 +164,12 @@ func TestDeleteNamespace(t *testing.T) {
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- err := Delete(testCase.input["name"], testCase.input["namespace"], client)
+ err := namespacePlugin{}.Delete(helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"},
+ Name: testCase.input["name"],
+ }, testCase.input["namespace"], client)
if err != nil {
t.Fatalf("Delete method returned an error (%s)", err)
}
@@ -152,14 +181,14 @@ func TestGetNamespace(t *testing.T) {
testCases := []struct {
label string
input map[string]string
- clientOutput *coreV1.Namespace
+ object *coreV1.Namespace
expectedResult string
expectedError string
}{
{
label: "Sucessfully to get an existing namespace",
input: map[string]string{"name": "test-name", "namespace": "test-namespace"},
- clientOutput: &coreV1.Namespace{
+ object: &coreV1.Namespace{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-name",
},
@@ -169,7 +198,7 @@ func TestGetNamespace(t *testing.T) {
{
label: "Fail to get an non-existing namespace",
input: map[string]string{"name": "test-name", "namespace": "test-namespace"},
- clientOutput: &coreV1.Namespace{
+ object: &coreV1.Namespace{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-name2",
},
@@ -179,9 +208,12 @@ func TestGetNamespace(t *testing.T) {
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- result, err := Get(testCase.input["name"], testCase.input["namespace"], client)
+ result, err := namespacePlugin{}.Get(helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"},
+ Name: testCase.input["name"],
+ }, testCase.input["namespace"], client)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Get method return an un-expected (%s)", err)
diff --git a/src/k8splugin/plugins/network/plugin.go b/src/k8splugin/plugins/network/plugin.go
index 74ac3473..5cc57e87 100644
--- a/src/k8splugin/plugins/network/plugin.go
+++ b/src/k8splugin/plugins/network/plugin.go
@@ -14,31 +14,38 @@ limitations under the License.
package main
import (
- "k8splugin/plugins/network/v1"
+ v1 "k8splugin/plugins/network/v1"
"regexp"
utils "k8splugin/internal"
+ "k8splugin/internal/app"
+ "k8splugin/internal/helm"
pkgerrors "github.com/pkg/errors"
- "k8s.io/client-go/kubernetes"
+ "k8s.io/apimachinery/pkg/runtime/schema"
)
-func extractData(data string) (vnfID, cniType, networkName string) {
+// ExportedVariable is what we will look for when calling the plugin
+var ExportedVariable networkPlugin
+
+type networkPlugin struct {
+}
+
+func extractData(data string) (cniType, networkName string) {
re := regexp.MustCompile("_")
split := re.Split(data, -1)
if len(split) != 3 {
return
}
- vnfID = split[0]
cniType = split[1]
networkName = split[2]
return
}
// Create an ONAP Network object
-func Create(data *utils.ResourceData, client kubernetes.Interface) (string, error) {
+func (p networkPlugin) Create(yamlFilePath string, namespace string, client *app.KubernetesClient) (string, error) {
network := &v1.OnapNetwork{}
- if _, err := utils.DecodeYAML(data.YamlFilePath, network); err != nil {
+ if _, err := utils.DecodeYAML(yamlFilePath, network); err != nil {
return "", pkgerrors.Wrap(err, "Decode network object error")
}
@@ -58,17 +65,24 @@ func Create(data *utils.ResourceData, client kubernetes.Interface) (string, erro
return "", pkgerrors.Wrap(err, "Error during the creation for "+cniType+" plugin")
}
- return data.VnfId + "_" + cniType + "_" + name, nil
+ return cniType + "_" + name, nil
+}
+
+// Get a Network
+func (p networkPlugin) Get(resource helm.KubernetesResource, namespace string, client *app.KubernetesClient) (string, error) {
+ return "", nil
}
// List of Networks
-func List(namespace string, kubeclient kubernetes.Interface) ([]string, error) {
+func (p networkPlugin) List(gvk schema.GroupVersionKind, namespace string,
+ client *app.KubernetesClient) ([]helm.KubernetesResource, error) {
+
return nil, nil
}
// Delete an existing Network
-func Delete(name string, namespace string, kubeclient kubernetes.Interface) error {
- _, cniType, networkName := extractData(name)
+func (p networkPlugin) Delete(resource helm.KubernetesResource, namespace string, client *app.KubernetesClient) error {
+ cniType, networkName := extractData(resource.Name)
typePlugin, ok := utils.LoadedPlugins[cniType+"-network"]
if !ok {
return pkgerrors.New("No plugin for resource " + cniType + " found")
@@ -85,8 +99,3 @@ func Delete(name string, namespace string, kubeclient kubernetes.Interface) erro
return nil
}
-
-// Get an existing Network
-func Get(name string, namespace string, kubeclient kubernetes.Interface) (string, error) {
- return "", nil
-}
diff --git a/src/k8splugin/plugins/network/plugin_test.go b/src/k8splugin/plugins/network/plugin_test.go
index e8e113b2..5a8ce4db 100644
--- a/src/k8splugin/plugins/network/plugin_test.go
+++ b/src/k8splugin/plugins/network/plugin_test.go
@@ -15,6 +15,7 @@ package main
import (
utils "k8splugin/internal"
+ "k8splugin/internal/helm"
"os"
"plugin"
"reflect"
@@ -22,6 +23,7 @@ import (
"testing"
pkgerrors "github.com/pkg/errors"
+ "k8s.io/apimachinery/pkg/runtime/schema"
)
func LoadMockNetworkPlugins(krdLoadedPlugins *map[string]*plugin.Plugin, networkName, errMsg string) error {
@@ -51,7 +53,6 @@ func LoadMockNetworkPlugins(krdLoadedPlugins *map[string]*plugin.Plugin, network
}
func TestCreateNetwork(t *testing.T) {
- internalVNFID := "1"
oldkrdPluginData := utils.LoadedPlugins
defer func() {
@@ -60,34 +61,27 @@ func TestCreateNetwork(t *testing.T) {
testCases := []struct {
label string
- input *utils.ResourceData
+ input string
mockError string
mockOutput string
expectedResult string
expectedError string
}{
{
- label: "Fail to decode a network object",
- input: &utils.ResourceData{
- YamlFilePath: "../../mock_files/mock_yamls/service.yaml",
- },
+ label: "Fail to decode a network object",
+ input: "../../mock_files/mock_yamls/service.yaml",
expectedError: "No plugin for resource",
},
{
- label: "Fail to create a network",
- input: &utils.ResourceData{
- YamlFilePath: "../../mock_files/mock_yamls/ovn4nfvk8s.yaml",
- },
+ label: "Fail to create a network",
+ input: "../../mock_files/mock_yamls/ovn4nfvk8s.yaml",
mockError: "Internal error",
expectedError: "Error during the creation for ovn4nfvk8s plugin: Internal error",
},
{
- label: "Successfully create a ovn4nfv network",
- input: &utils.ResourceData{
- VnfId: internalVNFID,
- YamlFilePath: "../../mock_files/mock_yamls/ovn4nfvk8s.yaml",
- },
- expectedResult: internalVNFID + "_ovn4nfvk8s_myNetwork",
+ label: "Successfully create a ovn4nfv network",
+ input: "../../mock_files/mock_yamls/ovn4nfvk8s.yaml",
+ expectedResult: "ovn4nfvk8s_myNetwork",
mockOutput: "myNetwork",
},
}
@@ -98,7 +92,7 @@ func TestCreateNetwork(t *testing.T) {
if err != nil {
t.Fatalf("TestCreateNetwork returned an error (%s)", err)
}
- result, err := Create(testCase.input, nil)
+ result, err := networkPlugin{}.Create(testCase.input, "", nil)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Create method return an un-expected (%s)", err)
@@ -157,7 +151,10 @@ func TestDeleteNetwork(t *testing.T) {
if err != nil {
t.Fatalf("TestDeleteNetwork returned an error (%s)", err)
}
- err = Delete(testCase.input, "", nil)
+ err = networkPlugin{}.Delete(helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{Group: "", Version: "", Kind: "Network"},
+ Name: testCase.input,
+ }, "", nil)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Create method return an un-expected (%s)", err)
diff --git a/src/k8splugin/plugins/service/plugin.go b/src/k8splugin/plugins/service/plugin.go
index ea5aecad..2957c441 100644
--- a/src/k8splugin/plugins/service/plugin.go
+++ b/src/k8splugin/plugins/service/plugin.go
@@ -16,23 +16,29 @@ package main
import (
"log"
- "k8s.io/client-go/kubernetes"
-
pkgerrors "github.com/pkg/errors"
-
coreV1 "k8s.io/api/core/v1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
utils "k8splugin/internal"
+ "k8splugin/internal/helm"
+ "k8splugin/internal/plugin"
)
+// ExportedVariable is what we will look for when calling the plugin
+var ExportedVariable servicePlugin
+
+type servicePlugin struct {
+}
+
// Create a service object in a specific Kubernetes cluster
-func Create(data *utils.ResourceData, client kubernetes.Interface) (string, error) {
- namespace := data.Namespace
+func (p servicePlugin) Create(yamlFilePath string, namespace string, client plugin.KubernetesConnector) (string, error) {
if namespace == "" {
namespace = "default"
}
- obj, err := utils.DecodeYAML(data.YamlFilePath, nil)
+
+ obj, err := utils.DecodeYAML(yamlFilePath, nil)
if err != nil {
return "", pkgerrors.Wrap(err, "Decode service object error")
}
@@ -43,7 +49,7 @@ func Create(data *utils.ResourceData, client kubernetes.Interface) (string, erro
}
service.Namespace = namespace
- result, err := client.CoreV1().Services(namespace).Create(service)
+ result, err := client.GetStandardClient().CoreV1().Services(namespace).Create(service)
if err != nil {
return "", pkgerrors.Wrap(err, "Create Service error")
}
@@ -52,7 +58,8 @@ func Create(data *utils.ResourceData, client kubernetes.Interface) (string, erro
}
// List of existing services hosted in a specific Kubernetes cluster
-func List(namespace string, kubeclient kubernetes.Interface) ([]string, error) {
+// gvk parameter is not used as this plugin is specific to services only
+func (p servicePlugin) List(gvk schema.GroupVersionKind, namespace string, client plugin.KubernetesConnector) ([]helm.KubernetesResource, error) {
if namespace == "" {
namespace = "default"
}
@@ -60,19 +67,25 @@ func List(namespace string, kubeclient kubernetes.Interface) ([]string, error) {
opts := metaV1.ListOptions{
Limit: utils.ResourcesListLimit,
}
- opts.APIVersion = "apps/v1"
- opts.Kind = "Service"
- list, err := kubeclient.CoreV1().Services(namespace).List(opts)
+ list, err := client.GetStandardClient().CoreV1().Services(namespace).List(opts)
if err != nil {
return nil, pkgerrors.Wrap(err, "Get Service list error")
}
- result := make([]string, 0, utils.ResourcesListLimit)
+ result := make([]helm.KubernetesResource, 0, utils.ResourcesListLimit)
if list != nil {
- for _, deployment := range list.Items {
- log.Printf("%v", deployment.Name)
- result = append(result, deployment.Name)
+ for _, service := range list.Items {
+ log.Printf("%v", service.Name)
+ result = append(result,
+ helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service",
+ },
+ Name: service.GetName(),
+ })
}
}
@@ -80,7 +93,7 @@ func List(namespace string, kubeclient kubernetes.Interface) ([]string, error) {
}
// Delete an existing service hosted in a specific Kubernetes cluster
-func Delete(name string, namespace string, kubeclient kubernetes.Interface) error {
+func (p servicePlugin) Delete(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) error {
if namespace == "" {
namespace = "default"
}
@@ -90,8 +103,8 @@ func Delete(name string, namespace string, kubeclient kubernetes.Interface) erro
PropagationPolicy: &deletePolicy,
}
- log.Println("Deleting service: " + name)
- if err := kubeclient.CoreV1().Services(namespace).Delete(name, opts); err != nil {
+ log.Println("Deleting service: " + resource.Name)
+ if err := client.GetStandardClient().CoreV1().Services(namespace).Delete(resource.Name, opts); err != nil {
return pkgerrors.Wrap(err, "Delete service error")
}
@@ -99,18 +112,15 @@ func Delete(name string, namespace string, kubeclient kubernetes.Interface) erro
}
// Get an existing service hosted in a specific Kubernetes cluster
-func Get(name string, namespace string, kubeclient kubernetes.Interface) (string, error) {
+func (p servicePlugin) Get(resource helm.KubernetesResource, namespace string, client plugin.KubernetesConnector) (string, error) {
if namespace == "" {
namespace = "default"
}
opts := metaV1.GetOptions{}
- opts.APIVersion = "apps/v1"
- opts.Kind = "Service"
-
- service, err := kubeclient.CoreV1().Services(namespace).Get(name, opts)
+ service, err := client.GetStandardClient().CoreV1().Services(namespace).Get(resource.Name, opts)
if err != nil {
- return "", pkgerrors.Wrap(err, "Get Deployment error")
+ return "", pkgerrors.Wrap(err, "Get Service error")
}
return service.Name, nil
diff --git a/src/k8splugin/plugins/service/plugin_test.go b/src/k8splugin/plugins/service/plugin_test.go
index d3614860..66703089 100644
--- a/src/k8splugin/plugins/service/plugin_test.go
+++ b/src/k8splugin/plugins/service/plugin_test.go
@@ -14,54 +14,67 @@ limitations under the License.
package main
import (
+ "k8splugin/internal/helm"
"reflect"
"strings"
"testing"
- utils "k8splugin/internal"
-
coreV1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/meta"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- testclient "k8s.io/client-go/kubernetes/fake"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/client-go/dynamic"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/kubernetes/fake"
)
+type TestKubernetesConnector struct {
+ object runtime.Object
+}
+
+func (t TestKubernetesConnector) GetMapper() meta.RESTMapper {
+ return nil
+}
+
+func (t TestKubernetesConnector) GetDynamicClient() dynamic.Interface {
+ return nil
+}
+
+func (t TestKubernetesConnector) GetStandardClient() kubernetes.Interface {
+ return fake.NewSimpleClientset(t.object)
+}
+
func TestCreateService(t *testing.T) {
- namespace := "test1"
name := "mock-service"
testCases := []struct {
label string
- input *utils.ResourceData
- clientOutput *coreV1.Service
+ input string
+ namespace string
+ object *coreV1.Service
expectedResult string
expectedError string
}{
{
- label: "Fail to create a service with invalid type",
- input: &utils.ResourceData{
- YamlFilePath: "../../mock_files/mock_yamls/deployment.yaml",
- },
- clientOutput: &coreV1.Service{},
+ label: "Fail to create a service with invalid type",
+ input: "../../mock_files/mock_yamls/deployment.yaml",
+ namespace: "test1",
+ object: &coreV1.Service{},
expectedError: "contains another resource different than Service",
},
{
- label: "Successfully create a service",
- input: &utils.ResourceData{
- YamlFilePath: "../../mock_files/mock_yamls/service.yaml",
- },
- clientOutput: &coreV1.Service{
- ObjectMeta: metaV1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- },
+ label: "Successfully create a service",
+ input: "../../mock_files/mock_yamls/service.yaml",
+ namespace: "test1",
+ object: &coreV1.Service{},
expectedResult: name,
},
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- result, err := Create(testCase.input, client)
+ result, err := servicePlugin{}.Create(testCase.input, testCase.namespace, client)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Create method return an un-expected (%s)", err)
@@ -86,38 +99,42 @@ func TestCreateService(t *testing.T) {
}
func TestListService(t *testing.T) {
- namespace := "test1"
testCases := []struct {
label string
- input string
- clientOutput *coreV1.ServiceList
- expectedResult []string
+ namespace string
+ object *coreV1.ServiceList
+ expectedResult []helm.KubernetesResource
}{
{
label: "Sucessfully to display an empty service list",
- input: namespace,
- clientOutput: &coreV1.ServiceList{},
- expectedResult: []string{},
+ namespace: "test1",
+ object: &coreV1.ServiceList{},
+ expectedResult: []helm.KubernetesResource{},
},
{
- label: "Sucessfully to display a list of existing services",
- input: namespace,
- clientOutput: &coreV1.ServiceList{
+ label: "Sucessfully to display a list of existing services",
+ namespace: "test1",
+ object: &coreV1.ServiceList{
Items: []coreV1.Service{
coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test",
- Namespace: namespace,
+ Namespace: "test1",
},
},
},
},
- expectedResult: []string{"test"},
+ expectedResult: []helm.KubernetesResource{
+ {
+ Name: "test",
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"},
+ },
+ },
},
{
- label: "Sucessfully display a list of existing services in default namespace",
- input: "",
- clientOutput: &coreV1.ServiceList{
+ label: "Sucessfully display a list of existing services in default namespace",
+ namespace: "",
+ object: &coreV1.ServiceList{
Items: []coreV1.Service{
coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
@@ -128,19 +145,27 @@ func TestListService(t *testing.T) {
coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test2",
- Namespace: namespace,
+ Namespace: "test1",
},
},
},
},
- expectedResult: []string{"test"},
+ expectedResult: []helm.KubernetesResource{
+ {
+ Name: "test",
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"},
+ },
+ },
},
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- result, err := List(testCase.input, client)
+ result, err := servicePlugin{}.List(schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"}, testCase.namespace, client)
if err != nil {
t.Fatalf("List method returned an error (%s)", err)
} else {
@@ -158,14 +183,14 @@ func TestListService(t *testing.T) {
func TestDeleteService(t *testing.T) {
testCases := []struct {
- label string
- input map[string]string
- clientOutput *coreV1.Service
+ label string
+ input map[string]string
+ object *coreV1.Service
}{
{
label: "Sucessfully to delete an existing service",
input: map[string]string{"name": "test-service", "namespace": "test-namespace"},
- clientOutput: &coreV1.Service{
+ object: &coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-service",
Namespace: "test-namespace",
@@ -175,7 +200,7 @@ func TestDeleteService(t *testing.T) {
{
label: "Sucessfully delete an existing service in default namespace",
input: map[string]string{"name": "test-service", "namespace": ""},
- clientOutput: &coreV1.Service{
+ object: &coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-service",
Namespace: "default",
@@ -185,9 +210,12 @@ func TestDeleteService(t *testing.T) {
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- err := Delete(testCase.input["name"], testCase.input["namespace"], client)
+ err := servicePlugin{}.Delete(helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"},
+ Name: testCase.input["name"],
+ }, testCase.input["namespace"], client)
if err != nil {
t.Fatalf("Delete method returned an error (%s)", err)
}
@@ -199,14 +227,14 @@ func TestGetService(t *testing.T) {
testCases := []struct {
label string
input map[string]string
- clientOutput *coreV1.Service
+ object *coreV1.Service
expectedResult string
expectedError string
}{
{
label: "Sucessfully to get an existing service",
input: map[string]string{"name": "test-service", "namespace": "test-namespace"},
- clientOutput: &coreV1.Service{
+ object: &coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-service",
Namespace: "test-namespace",
@@ -217,7 +245,7 @@ func TestGetService(t *testing.T) {
{
label: "Sucessfully get an existing service from default namespaces",
input: map[string]string{"name": "test-service", "namespace": ""},
- clientOutput: &coreV1.Service{
+ object: &coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-service",
Namespace: "default",
@@ -228,7 +256,7 @@ func TestGetService(t *testing.T) {
{
label: "Fail to get an non-existing namespace",
input: map[string]string{"name": "test-name", "namespace": "test-namespace"},
- clientOutput: &coreV1.Service{
+ object: &coreV1.Service{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-service",
Namespace: "default",
@@ -239,9 +267,12 @@ func TestGetService(t *testing.T) {
}
for _, testCase := range testCases {
- client := testclient.NewSimpleClientset(testCase.clientOutput)
+ client := TestKubernetesConnector{testCase.object}
t.Run(testCase.label, func(t *testing.T) {
- result, err := Get(testCase.input["name"], testCase.input["namespace"], client)
+ result, err := servicePlugin{}.Get(helm.KubernetesResource{
+ GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"},
+ Name: testCase.input["name"],
+ }, testCase.input["namespace"], client)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("Get method return an un-expected (%s)", err)