aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/k8splugin/api/api.go13
-rw-r--r--src/k8splugin/api/brokerhandler_test.go6
-rw-r--r--src/k8splugin/api/confighandler.go15
-rw-r--r--src/k8splugin/internal/app/config.go (renamed from src/k8splugin/internal/rb/config.go)8
-rw-r--r--src/k8splugin/internal/app/config_backend.go (renamed from src/k8splugin/internal/rb/config_backend.go)52
-rw-r--r--src/k8splugin/internal/app/config_test.go (renamed from src/k8splugin/internal/rb/config_test.go)2
-rw-r--r--src/k8splugin/internal/app/instance.go43
-rw-r--r--src/k8splugin/internal/app/instance_test.go390
-rw-r--r--src/k8splugin/mock_files/mock_yamls/ovn4nfvk8s.yaml16
-rw-r--r--src/k8splugin/plugins/network/plugin.go7
-rw-r--r--src/k8splugin/plugins/network/plugin_test.go2
-rw-r--r--src/k8splugin/plugins/network/v1/types.go23
-rw-r--r--src/k8splugin/plugins/ovn4nfvk8s-network/plugin.go34
-rw-r--r--src/k8splugin/plugins/ovn4nfvk8s-network/plugin_test.go6
14 files changed, 530 insertions, 87 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go
index 5fed28a0..58e50a16 100644
--- a/src/k8splugin/api/api.go
+++ b/src/k8splugin/api/api.go
@@ -25,7 +25,7 @@ import (
func NewRouter(defClient rb.DefinitionManager,
profileClient rb.ProfileManager,
instClient app.InstanceManager,
- configClient rb.ConfigManager,
+ configClient app.ConfigManager,
templateClient rb.ConfigTemplateManager) *mux.Router {
router := mux.NewRouter()
@@ -43,12 +43,11 @@ func NewRouter(defClient rb.DefinitionManager,
// instRouter.HandleFunc("/{vnfInstanceId}", UpdateHandler).Methods("PUT")
//Setup the broker handler here
+ //Use the base router without any path prefixes
brokerHandler := brokerInstanceHandler{client: instClient}
- instRouter.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload", brokerHandler.createHandler).Methods("POST")
- instRouter.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload/{instID}",
- brokerHandler.getHandler).Methods("GET")
- instRouter.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload/{instID}",
- brokerHandler.deleteHandler).Methods("DELETE")
+ router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload", brokerHandler.createHandler).Methods("POST")
+ router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload/{instID}", brokerHandler.getHandler).Methods("GET")
+ router.HandleFunc("/{cloud-owner}/{cloud-region}/infra_workload/{instID}", brokerHandler.deleteHandler).Methods("DELETE")
//Setup the connectivity api handler here
connectionClient := connection.NewConnectionClient()
@@ -91,7 +90,7 @@ func NewRouter(defClient rb.DefinitionManager,
// Config value
if configClient == nil {
- configClient = rb.NewConfigClient()
+ configClient = app.NewConfigClient()
}
configHandler := rbConfigHandler{client: configClient}
resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/config", configHandler.createHandler).Methods("POST")
diff --git a/src/k8splugin/api/brokerhandler_test.go b/src/k8splugin/api/brokerhandler_test.go
index d9991e68..16046634 100644
--- a/src/k8splugin/api/brokerhandler_test.go
+++ b/src/k8splugin/api/brokerhandler_test.go
@@ -122,7 +122,7 @@ func TestBrokerCreateHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
- request := httptest.NewRequest("POST", "/v1/cloudowner/cloudregion/infra_workload", testCase.input)
+ request := httptest.NewRequest("POST", "/cloudowner/cloudregion/infra_workload", testCase.input)
resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil))
if testCase.expectedCode != resp.StatusCode {
@@ -204,7 +204,7 @@ func TestBrokerGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
- request := httptest.NewRequest("GET", "/v1/cloudowner/cloudregion/infra_workload/"+testCase.input, nil)
+ request := httptest.NewRequest("GET", "/cloudowner/cloudregion/infra_workload/"+testCase.input, nil)
resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil))
if testCase.expectedCode != resp.StatusCode {
@@ -251,7 +251,7 @@ func TestBrokerDeleteHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
- request := httptest.NewRequest("DELETE", "/v1/cloudowner/cloudregion/infra_workload/"+testCase.input, nil)
+ request := httptest.NewRequest("DELETE", "/cloudowner/cloudregion/infra_workload/"+testCase.input, nil)
resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil))
if testCase.expectedCode != resp.StatusCode {
diff --git a/src/k8splugin/api/confighandler.go b/src/k8splugin/api/confighandler.go
index 93098d61..9bd9db83 100644
--- a/src/k8splugin/api/confighandler.go
+++ b/src/k8splugin/api/confighandler.go
@@ -18,9 +18,10 @@ package api
import (
"encoding/json"
- "k8splugin/internal/rb"
"net/http"
+ "k8splugin/internal/app"
+
"github.com/gorilla/mux"
)
@@ -29,12 +30,12 @@ import (
type rbConfigHandler struct {
// Interface that implements bundle Definition operations
// We will set this variable with a mock interface for testing
- client rb.ConfigManager
+ client app.ConfigManager
}
// createHandler handles creation of the definition entry in the database
func (h rbConfigHandler) createHandler(w http.ResponseWriter, r *http.Request) {
- var p rb.Config
+ var p app.Config
vars := mux.Vars(r)
rbName := vars["rbname"]
rbVersion := vars["rbversion"]
@@ -73,7 +74,7 @@ func (h rbConfigHandler) createHandler(w http.ResponseWriter, r *http.Request) {
}
// getHandler handles GET operations on a particular config
-// Returns a rb.Definition
+// Returns a app.Definition
func (h rbConfigHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
rbName := vars["rbname"]
@@ -128,7 +129,7 @@ func (h rbConfigHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
prName := vars["prname"]
cfgName := vars["cfgname"]
- var p rb.Config
+ var p app.Config
if r.Body == nil {
http.Error(w, "Empty body", http.StatusBadRequest)
@@ -168,7 +169,7 @@ func (h rbConfigHandler) rollbackHandler(w http.ResponseWriter, r *http.Request)
return
}
- var p rb.ConfigRollback
+ var p app.ConfigRollback
err := json.NewDecoder(r.Body).Decode(&p)
if err != nil {
http.Error(w, err.Error(), http.StatusUnprocessableEntity)
@@ -194,7 +195,7 @@ func (h rbConfigHandler) tagitHandler(w http.ResponseWriter, r *http.Request) {
return
}
- var p rb.ConfigTagit
+ var p app.ConfigTagit
err := json.NewDecoder(r.Body).Decode(&p)
if err != nil {
http.Error(w, err.Error(), http.StatusUnprocessableEntity)
diff --git a/src/k8splugin/internal/rb/config.go b/src/k8splugin/internal/app/config.go
index 3bd8347b..f7e81358 100644
--- a/src/k8splugin/internal/rb/config.go
+++ b/src/k8splugin/internal/app/config.go
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package rb
+package app
import (
- pkgerrors "github.com/pkg/errors"
- "k8splugin/internal/db"
"strconv"
"strings"
+
+ "k8splugin/internal/db"
+
+ pkgerrors "github.com/pkg/errors"
)
// Config contains the parameters needed for configuration
diff --git a/src/k8splugin/internal/rb/config_backend.go b/src/k8splugin/internal/app/config_backend.go
index e2fa5b3c..763aed0d 100644
--- a/src/k8splugin/internal/rb/config_backend.go
+++ b/src/k8splugin/internal/app/config_backend.go
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package rb
+package app
import (
"bytes"
@@ -25,9 +25,11 @@ import (
"strconv"
"strings"
"sync"
+ "time"
"k8splugin/internal/db"
"k8splugin/internal/helm"
+ "k8splugin/internal/rb"
"github.com/ghodss/yaml"
pkgerrors "github.com/pkg/errors"
@@ -57,7 +59,8 @@ type ConfigVersionStore struct {
type configResourceList struct {
resourceTemplates []helm.KubernetesResourceTemplate
- profile Profile
+ createdResources []helm.KubernetesResource
+ profile rb.Profile
action string
}
@@ -339,17 +342,50 @@ func scheduleResources(c chan configResourceList) {
for {
data := <-c
//TODO: ADD Check to see if Application running
+ ic := NewInstanceClient()
+ resp, err := ic.Find(data.profile.RBName, data.profile.RBVersion, data.profile.ProfileName)
+ if err != nil || len(resp) == 0 {
+ log.Println("Error finding a running instance. Retrying later...")
+ time.Sleep(time.Second * 10)
+ continue
+ }
switch {
case data.action == "POST":
log.Printf("[scheduleResources]: POST %v %v", data.profile, data.resourceTemplates)
+ for _, inst := range resp {
+ k8sClient := KubernetesClient{}
+ err = k8sClient.init(inst.CloudRegion)
+ if err != nil {
+ log.Printf("Getting CloudRegion Information: %s", err.Error())
+ //Move onto the next cloud region
+ continue
+ }
+ data.createdResources, err = k8sClient.createResources(data.resourceTemplates, inst.Namespace)
+ if err != nil {
+ log.Printf("Error Creating resources: %s", err.Error())
+ continue
+ }
+ }
//TODO: Needs to add code to call Kubectl create
case data.action == "PUT":
log.Printf("[scheduleResources]: PUT %v %v", data.profile, data.resourceTemplates)
//TODO: Needs to add code to call Kubectl apply
case data.action == "DELETE":
log.Printf("[scheduleResources]: DELETE %v %v", data.profile, data.resourceTemplates)
- //TODO: Needs to add code to call Kubectl delete
-
+ for _, inst := range resp {
+ k8sClient := KubernetesClient{}
+ err = k8sClient.init(inst.CloudRegion)
+ if err != nil {
+ log.Printf("Getting CloudRegion Information: %s", err.Error())
+ //Move onto the next cloud region
+ continue
+ }
+ err = k8sClient.deleteResources(data.createdResources, inst.Namespace)
+ if err != nil {
+ log.Printf("Error Deleting resources: %s", err.Error())
+ continue
+ }
+ }
}
}
}
@@ -360,12 +396,12 @@ var resolve = func(rbName, rbVersion, profileName string, p Config) (configResou
var resTemplates []helm.KubernetesResourceTemplate
- profile, err := NewProfileClient().Get(rbName, rbVersion, profileName)
+ profile, err := rb.NewProfileClient().Get(rbName, rbVersion, profileName)
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Reading Profile Data")
}
- t, err := NewConfigTemplateClient().Get(rbName, rbVersion, p.TemplateName)
+ t, err := rb.NewConfigTemplateClient().Get(rbName, rbVersion, p.TemplateName)
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Getting Template")
}
@@ -373,7 +409,7 @@ var resolve = func(rbName, rbVersion, profileName string, p Config) (configResou
return configResourceList{}, pkgerrors.New("Invalid template no Chart.yaml file found")
}
- def, err := NewConfigTemplateClient().Download(rbName, rbVersion, p.TemplateName)
+ def, err := rb.NewConfigTemplateClient().Download(rbName, rbVersion, p.TemplateName)
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Downloading Template")
}
@@ -398,7 +434,7 @@ var resolve = func(rbName, rbVersion, profileName string, p Config) (configResou
}
defer outputfile.Close()
- chartBasePath, err := ExtractTarBall(bytes.NewBuffer(def))
+ chartBasePath, err := rb.ExtractTarBall(bytes.NewBuffer(def))
if err != nil {
return configResourceList{}, pkgerrors.Wrap(err, "Extracting Template")
}
diff --git a/src/k8splugin/internal/rb/config_test.go b/src/k8splugin/internal/app/config_test.go
index 9bf97a51..11a300ff 100644
--- a/src/k8splugin/internal/rb/config_test.go
+++ b/src/k8splugin/internal/app/config_test.go
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package rb
+package app
import (
"k8splugin/internal/db"
diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go
index 6d0910d0..41eca211 100644
--- a/src/k8splugin/internal/app/instance.go
+++ b/src/k8splugin/internal/app/instance.go
@@ -53,6 +53,7 @@ type InstanceResponse struct {
type InstanceManager interface {
Create(i InstanceRequest) (InstanceResponse, error)
Get(id string) (InstanceResponse, error)
+ Find(rbName string, ver string, profile string) ([]InstanceResponse, error)
Delete(id string) error
}
@@ -176,6 +177,48 @@ func (v *InstanceClient) Get(id string) (InstanceResponse, error) {
return InstanceResponse{}, pkgerrors.New("Error getting Instance")
}
+// Find returns the instances that match the given criteria
+// If version is empty, it will return all instances for a given rbName
+// If profile is empty, it will return all instances for a given rbName+version
+func (v *InstanceClient) Find(rbName string, version string, profile string) ([]InstanceResponse, error) {
+ if rbName == "" {
+ return []InstanceResponse{}, pkgerrors.New("rbName is required and cannot be empty")
+ }
+
+ values, err := db.DBconn.ReadAll(v.storeName, v.tagInst)
+ if err != nil || len(values) == 0 {
+ return []InstanceResponse{}, pkgerrors.Wrap(err, "Find Instance")
+ }
+
+ response := []InstanceResponse{}
+ //values is a map[string][]byte
+ for _, value := range values {
+ resp := InstanceResponse{}
+ db.DBconn.Unmarshal(value, &resp)
+ if err != nil {
+ return []InstanceResponse{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value")
+ }
+
+ if resp.RBName == rbName {
+
+ //Check if a version is provided and if it matches
+ if version != "" {
+ if resp.RBVersion == version {
+ //Check if a profilename matches or if it is not provided
+ if profile == "" || resp.ProfileName == profile {
+ response = append(response, resp)
+ }
+ }
+ } else {
+ //Append all versions as version is not provided
+ response = append(response, resp)
+ }
+ }
+ }
+
+ return response, nil
+}
+
// Delete the Instance from database
func (v *InstanceClient) Delete(id string) error {
inst, err := v.Get(id)
diff --git a/src/k8splugin/internal/app/instance_test.go b/src/k8splugin/internal/app/instance_test.go
index 6ab14a34..2fa2115b 100644
--- a/src/k8splugin/internal/app/instance_test.go
+++ b/src/k8splugin/internal/app/instance_test.go
@@ -18,6 +18,7 @@ import (
"io/ioutil"
"log"
"reflect"
+ "sort"
"testing"
utils "k8splugin/internal"
@@ -312,6 +313,395 @@ func TestInstanceGet(t *testing.T) {
})
}
+func TestInstanceFind(t *testing.T) {
+ oldkrdPluginData := utils.LoadedPlugins
+
+ defer func() {
+ utils.LoadedPlugins = oldkrdPluginData
+ }()
+
+ err := LoadMockPlugins(utils.LoadedPlugins)
+ if err != nil {
+ t.Fatalf("LoadMockPlugins returned an error (%s)", err)
+ }
+
+ items := map[string]map[string][]byte{
+ InstanceKey{ID: "HaKpys8e"}.String(): {
+ "instance": []byte(
+ `{
+ "profile-name":"profile1",
+ "id":"HaKpys8e",
+ "namespace":"testnamespace",
+ "rb-name":"test-rbdef",
+ "rb-version":"v1",
+ "cloud-region":"region1",
+ "resources": [
+ {
+ "GVK": {
+ "Group":"apps",
+ "Version":"v1",
+ "Kind":"Deployment"
+ },
+ "Name": "deployment-1"
+ },
+ {
+ "GVK": {
+ "Group":"",
+ "Version":"v1",
+ "Kind":"Service"
+ },
+ "Name": "service-1"
+ }
+ ]
+ }`),
+ },
+ InstanceKey{ID: "HaKpys8f"}.String(): {
+ "instance": []byte(
+ `{
+ "profile-name":"profile2",
+ "id":"HaKpys8f",
+ "namespace":"testnamespace",
+ "rb-name":"test-rbdef",
+ "rb-version":"v1",
+ "cloud-region":"region1",
+ "resources": [
+ {
+ "GVK": {
+ "Group":"apps",
+ "Version":"v1",
+ "Kind":"Deployment"
+ },
+ "Name": "deployment-1"
+ },
+ {
+ "GVK": {
+ "Group":"",
+ "Version":"v1",
+ "Kind":"Service"
+ },
+ "Name": "service-1"
+ }
+ ]
+ }`),
+ },
+ InstanceKey{ID: "HaKpys8g"}.String(): {
+ "instance": []byte(
+ `{
+ "profile-name":"profile1",
+ "id":"HaKpys8g",
+ "namespace":"testnamespace",
+ "rb-name":"test-rbdef",
+ "rb-version":"v2",
+ "cloud-region":"region1",
+ "resources": [
+ {
+ "GVK": {
+ "Group":"apps",
+ "Version":"v1",
+ "Kind":"Deployment"
+ },
+ "Name": "deployment-1"
+ },
+ {
+ "GVK": {
+ "Group":"",
+ "Version":"v1",
+ "Kind":"Service"
+ },
+ "Name": "service-1"
+ }
+ ]
+ }`),
+ },
+ }
+
+ t.Run("Successfully Find Instance By Name", func(t *testing.T) {
+ db.DBconn = &db.MockDB{
+ Items: items,
+ }
+
+ expected := []InstanceResponse{
+ {
+ ID: "HaKpys8e",
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile1",
+ CloudRegion: "region1",
+ Namespace: "testnamespace",
+
+ Resources: []helm.KubernetesResource{
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "apps",
+ Version: "v1",
+ Kind: "Deployment"},
+ Name: "deployment-1",
+ },
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"},
+ Name: "service-1",
+ },
+ },
+ },
+ {
+ ID: "HaKpys8f",
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile2",
+ CloudRegion: "region1",
+ Namespace: "testnamespace",
+
+ Resources: []helm.KubernetesResource{
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "apps",
+ Version: "v1",
+ Kind: "Deployment"},
+ Name: "deployment-1",
+ },
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"},
+ Name: "service-1",
+ },
+ },
+ },
+ {
+ ID: "HaKpys8g",
+ RBName: "test-rbdef",
+ RBVersion: "v2",
+ ProfileName: "profile1",
+ CloudRegion: "region1",
+ Namespace: "testnamespace",
+
+ Resources: []helm.KubernetesResource{
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "apps",
+ Version: "v1",
+ Kind: "Deployment"},
+ Name: "deployment-1",
+ },
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"},
+ Name: "service-1",
+ },
+ },
+ },
+ }
+ ic := NewInstanceClient()
+ name := "test-rbdef"
+ data, err := ic.Find(name, "", "")
+ if err != nil {
+ t.Fatalf("TestInstanceFind returned an error (%s)", err)
+ }
+
+ // Since the order of returned slice is not guaranteed
+ // Check both and return error if both don't match
+ sort.Slice(data, func(i, j int) bool {
+ return data[i].ID < data[j].ID
+ })
+ // Sort both as it is not expected that testCase.expected
+ // is sorted
+ sort.Slice(expected, func(i, j int) bool {
+ return expected[i].ID < expected[j].ID
+ })
+
+ if !reflect.DeepEqual(expected, data) {
+ t.Fatalf("TestInstanceFind returned:\n result=%v\n expected=%v",
+ data, expected)
+ }
+ })
+
+ t.Run("Successfully Find Instance By Name Version", func(t *testing.T) {
+ db.DBconn = &db.MockDB{
+ Items: items,
+ }
+
+ expected := []InstanceResponse{
+ {
+ ID: "HaKpys8e",
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile1",
+ CloudRegion: "region1",
+ Namespace: "testnamespace",
+
+ Resources: []helm.KubernetesResource{
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "apps",
+ Version: "v1",
+ Kind: "Deployment"},
+ Name: "deployment-1",
+ },
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"},
+ Name: "service-1",
+ },
+ },
+ },
+ {
+ ID: "HaKpys8f",
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile2",
+ CloudRegion: "region1",
+ Namespace: "testnamespace",
+
+ Resources: []helm.KubernetesResource{
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "apps",
+ Version: "v1",
+ Kind: "Deployment"},
+ Name: "deployment-1",
+ },
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"},
+ Name: "service-1",
+ },
+ },
+ },
+ }
+ ic := NewInstanceClient()
+ name := "test-rbdef"
+ data, err := ic.Find(name, "v1", "")
+ if err != nil {
+ t.Fatalf("TestInstanceFind returned an error (%s)", err)
+ }
+
+ // Since the order of returned slice is not guaranteed
+ // Check both and return error if both don't match
+ sort.Slice(data, func(i, j int) bool {
+ return data[i].ID < data[j].ID
+ })
+ // Sort both as it is not expected that testCase.expected
+ // is sorted
+ sort.Slice(expected, func(i, j int) bool {
+ return expected[i].ID < expected[j].ID
+ })
+
+ if !reflect.DeepEqual(expected, data) {
+ t.Fatalf("TestInstanceFind returned:\n result=%v\n expected=%v",
+ data, expected)
+ }
+ })
+
+ t.Run("Successfully Find Instance By Name Version Profile", func(t *testing.T) {
+ db.DBconn = &db.MockDB{
+ Items: items,
+ }
+
+ expected := []InstanceResponse{
+ {
+ ID: "HaKpys8e",
+ RBName: "test-rbdef",
+ RBVersion: "v1",
+ ProfileName: "profile1",
+ CloudRegion: "region1",
+ Namespace: "testnamespace",
+
+ Resources: []helm.KubernetesResource{
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "apps",
+ Version: "v1",
+ Kind: "Deployment"},
+ Name: "deployment-1",
+ },
+ {
+ GVK: schema.GroupVersionKind{
+ Group: "",
+ Version: "v1",
+ Kind: "Service"},
+ Name: "service-1",
+ },
+ },
+ },
+ }
+ ic := NewInstanceClient()
+ name := "test-rbdef"
+ data, err := ic.Find(name, "v1", "profile1")
+ if err != nil {
+ t.Fatalf("TestInstanceFind returned an error (%s)", err)
+ }
+
+ // Since the order of returned slice is not guaranteed
+ // Check both and return error if both don't match
+ sort.Slice(data, func(i, j int) bool {
+ return data[i].ID < data[j].ID
+ })
+ // Sort both as it is not expected that testCase.expected
+ // is sorted
+ sort.Slice(expected, func(i, j int) bool {
+ return expected[i].ID < expected[j].ID
+ })
+
+ if !reflect.DeepEqual(expected, data) {
+ t.Fatalf("TestInstanceFind returned:\n result=%v\n expected=%v",
+ data, expected)
+ }
+ })
+
+ t.Run("Find non-existing Instance", func(t *testing.T) {
+ db.DBconn = &db.MockDB{
+ Items: map[string]map[string][]byte{
+ InstanceKey{ID: "HaKpys8e"}.String(): {
+ "instance": []byte(
+ `{
+ "profile-name":"profile1",
+ "id":"HaKpys8e",
+ "namespace":"testnamespace",
+ "rb-name":"test-rbdef",
+ "rb-version":"v1",
+ "cloud-region":"region1",
+ "resources": [
+ {
+ "GVK": {
+ "Group":"apps",
+ "Version":"v1",
+ "Kind":"Deployment"
+ },
+ "Name": "deployment-1"
+ },
+ {
+ "GVK": {
+ "Group":"",
+ "Version":"v1",
+ "Kind":"Service"
+ },
+ "Name": "service-1"
+ }
+ ]
+ }`),
+ },
+ },
+ }
+
+ ic := NewInstanceClient()
+ name := "non-existing"
+ resp, _ := ic.Find(name, "", "")
+ if len(resp) != 0 {
+ t.Fatalf("Expected 0 responses, but got %d", len(resp))
+ }
+ })
+}
+
func TestInstanceDelete(t *testing.T) {
oldkrdPluginData := utils.LoadedPlugins
diff --git a/src/k8splugin/mock_files/mock_yamls/ovn4nfvk8s.yaml b/src/k8splugin/mock_files/mock_yamls/ovn4nfvk8s.yaml
index 1a262753..31351dee 100644
--- a/src/k8splugin/mock_files/mock_yamls/ovn4nfvk8s.yaml
+++ b/src/k8splugin/mock_files/mock_yamls/ovn4nfvk8s.yaml
@@ -1,15 +1,9 @@
apiVersion: v1
-kind: OnapNetwork
+kind: Network
metadata:
name: ovn-priv-net
spec:
- config: '{
- "cnitype": "ovn4nfvk8s",
- "name": "mynet",
- "subnet": "172.16.33.0/24",
- "gateway": "172.16.33.1",
- "routes": [{
- "dst": "172.16.29.1/24",
- "gw": "100.64.1.1"
- }]
- }' \ No newline at end of file
+ cnitype: "ovn4nfvk8s"
+ name: "ovn-priv-net"
+ subnet: "172.16.33.0/24"
+ gateway: "172.16.33.1/24"
diff --git a/src/k8splugin/plugins/network/plugin.go b/src/k8splugin/plugins/network/plugin.go
index fb163189..74ac3473 100644
--- a/src/k8splugin/plugins/network/plugin.go
+++ b/src/k8splugin/plugins/network/plugin.go
@@ -42,12 +42,7 @@ func Create(data *utils.ResourceData, client kubernetes.Interface) (string, erro
return "", pkgerrors.Wrap(err, "Decode network object error")
}
- config, err := network.DecodeConfig()
- if err != nil {
- return "", pkgerrors.Wrap(err, "Fail to decode network's configuration")
- }
-
- cniType := config["cnitype"].(string)
+ cniType := network.Spec.CniType
typePlugin, ok := utils.LoadedPlugins[cniType+"-network"]
if !ok {
return "", pkgerrors.New("No plugin for resource " + cniType + " found")
diff --git a/src/k8splugin/plugins/network/plugin_test.go b/src/k8splugin/plugins/network/plugin_test.go
index 5bf649a9..e8e113b2 100644
--- a/src/k8splugin/plugins/network/plugin_test.go
+++ b/src/k8splugin/plugins/network/plugin_test.go
@@ -71,7 +71,7 @@ func TestCreateNetwork(t *testing.T) {
input: &utils.ResourceData{
YamlFilePath: "../../mock_files/mock_yamls/service.yaml",
},
- expectedError: "Fail to decode network's configuration: Invalid configuration value",
+ expectedError: "No plugin for resource",
},
{
label: "Fail to create a network",
diff --git a/src/k8splugin/plugins/network/v1/types.go b/src/k8splugin/plugins/network/v1/types.go
index b4efa39a..96484efa 100644
--- a/src/k8splugin/plugins/network/v1/types.go
+++ b/src/k8splugin/plugins/network/v1/types.go
@@ -14,9 +14,7 @@ limitations under the License.
package v1
import (
- "encoding/json"
- pkgerrors "github.com/pkg/errors"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -33,7 +31,11 @@ type OnapNetwork struct {
// OnapNetworkSpec is the spec for OnapNetwork resource
type OnapNetworkSpec struct {
- Config string `json:"config"`
+ CniType string `json:"cnitype"`
+ Name string `json:"name"`
+ Subnet string `json:"subnet"`
+ Gateway string `json:"gateway"`
+
}
// DeepCopyObject returns a generically typed copy of an object
@@ -50,18 +52,3 @@ func (in OnapNetwork) DeepCopyObject() runtime.Object {
func (in OnapNetwork) GetObjectKind() schema.ObjectKind {
return &in.TypeMeta
}
-
-// DecodeConfig content
-func (in OnapNetwork) DecodeConfig() (map[string]interface{}, error) {
- var raw map[string]interface{}
-
- if in.Spec.Config == "" {
- return nil, pkgerrors.New("Invalid configuration value")
- }
-
- if err := json.Unmarshal([]byte(in.Spec.Config), &raw); err != nil {
- return nil, pkgerrors.Wrap(err, "JSON unmarshalling error")
- }
-
- return raw, nil
-}
diff --git a/src/k8splugin/plugins/ovn4nfvk8s-network/plugin.go b/src/k8splugin/plugins/ovn4nfvk8s-network/plugin.go
index 959586bc..3f5d80ba 100644
--- a/src/k8splugin/plugins/ovn4nfvk8s-network/plugin.go
+++ b/src/k8splugin/plugins/ovn4nfvk8s-network/plugin.go
@@ -46,6 +46,9 @@ type OVNNbctl struct {
// Run a command via ovn-nbctl
func (ctl *OVNNbctl) Run(args ...string) (string, string, error) {
+ if ctl.exec == nil {
+ ctl.exec = kexec.New()
+ }
if ctl.path == "" {
nbctlPath, err := ctl.exec.LookPath(ovnNbctlCommand)
if err != nil {
@@ -53,9 +56,6 @@ func (ctl *OVNNbctl) Run(args ...string) (string, string, error) {
}
ctl.path = nbctlPath
}
- if ctl.exec == nil {
- ctl.exec = kexec.New()
- }
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}
@@ -76,25 +76,21 @@ func init() {
// CreateNetwork in OVN controller
func CreateNetwork(network *v1.OnapNetwork) (string, error) {
- config, err := network.DecodeConfig()
- if err != nil {
- return "", err
- }
- name := config["name"].(string)
- if name == "" {
- return "", pkgerrors.New("Empty Name value")
- }
+ name := network.Spec.Name
+ if name == "" {
+ return "", pkgerrors.New("Invalid Network Name")
+ }
- subnet := config["subnet"].(string)
- if subnet == "" {
- return "", pkgerrors.New("Empty Subnet value")
- }
+ subnet := network.Spec.Subnet
+ if subnet == "" {
+ return "", pkgerrors.New("Invalid Subnet Address")
+ }
- gatewayIPMask := config["gateway"].(string)
- if gatewayIPMask == "" {
- return "", pkgerrors.New("Empty Gateway IP Mask")
- }
+ gatewayIPMask := network.Spec.Gateway
+ if gatewayIPMask == "" {
+ return "", pkgerrors.New("Invalid Gateway Address")
+ }
routerMac, stderr, err := ovnCmd.Run(getAuthStr(), "--if-exist", "-v", "get", "logical_router_port", "rtos-"+name, "mac")
if err != nil {
diff --git a/src/k8splugin/plugins/ovn4nfvk8s-network/plugin_test.go b/src/k8splugin/plugins/ovn4nfvk8s-network/plugin_test.go
index ce848a71..6a1054ee 100644
--- a/src/k8splugin/plugins/ovn4nfvk8s-network/plugin_test.go
+++ b/src/k8splugin/plugins/ovn4nfvk8s-network/plugin_test.go
@@ -43,7 +43,7 @@ func TestCreateOVN4NFVK8SNetwork(t *testing.T) {
{
label: "Fail to decode a network",
input: &v1.OnapNetwork{},
- expectedError: "Invalid configuration value",
+ expectedError: "Invalid Network Name",
},
{
label: "Fail to create a network",
@@ -52,7 +52,7 @@ func TestCreateOVN4NFVK8SNetwork(t *testing.T) {
Name: "test",
},
Spec: v1.OnapNetworkSpec{
- Config: "{\"cnitype\": \"ovn4nfvk8s\",\"name\": \"mynet\",\"subnet\": \"172.16.33.0/24\",\"gateway\": \"172.16.33.1\",\"routes\": [{\"dst\": \"172.16.29.1/24\",\"gw\": \"100.64.1.1\"}]}",
+ CniType: "ovn4nfvk8s", Name: "mynet", Subnet: "172.16.33.0/24", Gateway: "172.16.33.1/24",
},
},
expectedError: "Failed to get logical router",
@@ -67,7 +67,7 @@ func TestCreateOVN4NFVK8SNetwork(t *testing.T) {
Name: "test",
},
Spec: v1.OnapNetworkSpec{
- Config: "{\"cnitype\": \"ovn4nfvk8s\",\"name\": \"mynet\",\"subnet\": \"172.16.33.0/24\",\"gateway\": \"172.16.33.1\",\"routes\": [{\"dst\": \"172.16.29.1/24\",\"gw\": \"100.64.1.1\"}]}",
+ CniType: "ovn4nfvk8s", Name: "mynet", Subnet: "172.16.33.0/24", Gateway: "172.16.33.1/24",
},
},
expectedResult: "mynet",