summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Multanen <eric.w.multanen@intel.com>2020-03-13 17:39:40 -0700
committerRitu Sood <Ritu.Sood@intel.com>2020-03-23 22:40:28 +0000
commit529906640a6844dd371de37631e3948d328a390b (patch)
treea8e56469d3fa70726d0a4623fecae43dc987c121
parente201896e60374698da18cf4258448a0d97617e37 (diff)
Add Network and Provider Network Intent API support
Add API for CRUD operations to manage network and provider-network intent resources. Issue-ID: MULTICLOUD-1029 Signed-off-by: Eric Multanen <eric.w.multanen@intel.com> Change-Id: If3c71691b3825db50eacdb0ea87b0d5c436ad80f
-rw-r--r--src/ncm/api/api.go39
-rw-r--r--src/ncm/api/networkhandler.go215
-rw-r--r--src/ncm/api/providernethandler.go268
-rw-r--r--src/ncm/pkg/module/cluster.go74
-rw-r--r--src/ncm/pkg/module/module.go6
-rw-r--r--src/ncm/pkg/module/module_definitions.go101
-rw-r--r--src/ncm/pkg/module/network.go170
-rw-r--r--src/ncm/pkg/module/providernet.go172
8 files changed, 999 insertions, 46 deletions
diff --git a/src/ncm/api/api.go b/src/ncm/api/api.go
index c26f54e9..34b46c67 100644
--- a/src/ncm/api/api.go
+++ b/src/ncm/api/api.go
@@ -25,7 +25,7 @@ import (
var moduleClient *moduleLib.Client
-// for the given client and testClient, if the testClient is not null and
+// For the given client and testClient, if the testClient is not null and
// implements the client manager interface corresponding to client, then
// return the testClient, otherwise return the client.
func setClient(client, testClient interface{}) interface{} {
@@ -37,6 +37,20 @@ func setClient(client, testClient interface{}) interface{} {
return c
}
}
+ case *moduleLib.NetworkClient:
+ if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.NetworkManager)(nil)).Elem()) {
+ c, ok := testClient.(moduleLib.NetworkManager)
+ if ok {
+ return c
+ }
+ }
+ case *moduleLib.ProviderNetClient:
+ if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.ProviderNetManager)(nil)).Elem()) {
+ c, ok := testClient.(moduleLib.ProviderNetManager)
+ if ok {
+ return c
+ }
+ }
default:
fmt.Printf("unknown type %T\n", cl)
}
@@ -49,12 +63,11 @@ func NewRouter(testClient interface{}) *mux.Router {
moduleClient = moduleLib.NewClient()
+ router := mux.NewRouter().PathPrefix("/v2").Subrouter()
+
clusterHandler := clusterHandler{
client: setClient(moduleClient.Cluster, testClient).(moduleLib.ClusterManager),
}
-
- router := mux.NewRouter().PathPrefix("/v2").Subrouter()
-
router.HandleFunc("/cluster-providers", clusterHandler.createClusterProviderHandler).Methods("POST")
router.HandleFunc("/cluster-providers", clusterHandler.getClusterProviderHandler).Methods("GET")
router.HandleFunc("/cluster-providers/{name}", clusterHandler.getClusterProviderHandler).Methods("GET")
@@ -72,5 +85,23 @@ func NewRouter(testClient interface{}) *mux.Router {
router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs/{kvpair}", clusterHandler.getClusterKvPairsHandler).Methods("GET")
router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs/{kvpair}", clusterHandler.deleteClusterKvPairsHandler).Methods("DELETE")
+ networkHandler := networkHandler{
+ client: setClient(moduleClient.Network, testClient).(moduleLib.NetworkManager),
+ }
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/networks", networkHandler.createNetworkHandler).Methods("POST")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/networks", networkHandler.getNetworkHandler).Methods("GET")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/networks/{name}", networkHandler.putNetworkHandler).Methods("PUT")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/networks/{name}", networkHandler.getNetworkHandler).Methods("GET")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/networks/{name}", networkHandler.deleteNetworkHandler).Methods("DELETE")
+
+ providernetHandler := providernetHandler{
+ client: setClient(moduleClient.ProviderNet, testClient).(moduleLib.ProviderNetManager),
+ }
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/provider-networks", providernetHandler.createProviderNetHandler).Methods("POST")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/provider-networks", providernetHandler.getProviderNetHandler).Methods("GET")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/provider-networks/{name}", providernetHandler.putProviderNetHandler).Methods("PUT")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/provider-networks/{name}", providernetHandler.getProviderNetHandler).Methods("GET")
+ router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/provider-networks/{name}", providernetHandler.deleteProviderNetHandler).Methods("DELETE")
+
return router
}
diff --git a/src/ncm/api/networkhandler.go b/src/ncm/api/networkhandler.go
new file mode 100644
index 00000000..01d077a7
--- /dev/null
+++ b/src/ncm/api/networkhandler.go
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package api
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+
+ moduleLib "github.com/onap/multicloud-k8s/src/ncm/pkg/module"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
+ pkgerrors "github.com/pkg/errors"
+
+ "github.com/gorilla/mux"
+)
+
+// Used to store backend implementations objects
+// Also simplifies mocking for unit testing purposes
+type networkHandler struct {
+ // Interface that implements Cluster operations
+ // We will set this variable with a mock interface for testing
+ client moduleLib.NetworkManager
+}
+
+// Check for valid format of input parameters
+func validateNetworkInputs(p moduleLib.Network) error {
+ // validate name
+ errs := validation.IsValidName(p.Metadata.Name)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid network name - name=[%v], errors: %v", p.Metadata.Name, errs)
+ }
+
+ // validate cni type
+ found := false
+ for _, val := range moduleLib.CNI_TYPES {
+ if p.Spec.CniType == val {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return pkgerrors.Errorf("Invalid cni type: %v", p.Spec.CniType)
+ }
+
+ subnets := p.Spec.Ipv4Subnets
+ for _, subnet := range subnets {
+ err := moduleLib.ValidateSubnet(subnet)
+ if err != nil {
+ return pkgerrors.Wrap(err, "invalid subnet")
+ }
+ }
+ return nil
+}
+
+// Create handles creation of the Network entry in the database
+func (h networkHandler) createNetworkHandler(w http.ResponseWriter, r *http.Request) {
+ var p moduleLib.Network
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Name is required.
+ if p.Metadata.Name == "" {
+ http.Error(w, "Missing name in POST request", http.StatusBadRequest)
+ return
+ }
+
+ err = validateNetworkInputs(p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ ret, err := h.client.CreateNetwork(p, clusterProvider, cluster, false)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Put handles creation/update of the Network entry in the database
+func (h networkHandler) putNetworkHandler(w http.ResponseWriter, r *http.Request) {
+ var p moduleLib.Network
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+ name := vars["name"]
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Name is required.
+ if p.Metadata.Name == "" {
+ http.Error(w, "Missing name in PUT request", http.StatusBadRequest)
+ return
+ }
+
+ // Name in URL should match name in body
+ if p.Metadata.Name != name {
+ fmt.Printf("bodyname = %v, name= %v\n", p.Metadata.Name, name)
+ http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest)
+ return
+ }
+
+ err = validateNetworkInputs(p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ ret, err := h.client.CreateNetwork(p, clusterProvider, cluster, true)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Get handles GET operations on a particular Network Name
+// Returns a Network
+func (h networkHandler) getNetworkHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+ name := vars["name"]
+ var ret interface{}
+ var err error
+
+ if len(name) == 0 {
+ ret, err = h.client.GetNetworks(clusterProvider, cluster)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ } else {
+ ret, err = h.client.GetNetwork(name, clusterProvider, cluster)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Delete handles DELETE operations on a particular Network Name
+func (h networkHandler) deleteNetworkHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+ name := vars["name"]
+
+ err := h.client.DeleteNetwork(name, clusterProvider, cluster)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusNoContent)
+}
diff --git a/src/ncm/api/providernethandler.go b/src/ncm/api/providernethandler.go
new file mode 100644
index 00000000..b38a16c5
--- /dev/null
+++ b/src/ncm/api/providernethandler.go
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package api
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ moduleLib "github.com/onap/multicloud-k8s/src/ncm/pkg/module"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
+ pkgerrors "github.com/pkg/errors"
+
+ "github.com/gorilla/mux"
+)
+
+// Used to store backend implementations objects
+// Also simplifies mocking for unit testing purposes
+type providernetHandler struct {
+ // Interface that implements Cluster operations
+ // We will set this variable with a mock interface for testing
+ client moduleLib.ProviderNetManager
+}
+
+// Check for valid format of input parameters
+func validateProviderNetInputs(p moduleLib.ProviderNet) error {
+ // validate name
+ errs := validation.IsValidName(p.Metadata.Name)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid provider network name=[%v], errors: %v", p.Metadata.Name, errs)
+ }
+
+ // validate cni type
+ found := false
+ for _, val := range moduleLib.CNI_TYPES {
+ if p.Spec.CniType == val {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return pkgerrors.Errorf("Invalid cni type: %v", p.Spec.CniType)
+ }
+
+ // validate the provider network type
+ found = false
+ for _, val := range moduleLib.PROVIDER_NET_TYPES {
+ if strings.ToUpper(p.Spec.ProviderNetType) == val {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return pkgerrors.Errorf("Invalid provider network type: %v", p.Spec.ProviderNetType)
+ }
+
+ // validate the subnets
+ subnets := p.Spec.Ipv4Subnets
+ for _, subnet := range subnets {
+ err := moduleLib.ValidateSubnet(subnet)
+ if err != nil {
+ return pkgerrors.Wrap(err, "invalid subnet")
+ }
+ }
+
+ // validate the VLAN ID
+ errs = validation.IsValidNumber(p.Spec.Vlan.VlanId, 0, 4095)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid VlAN ID %v - error: %v", p.Spec.Vlan.VlanId, errs)
+ }
+
+ // validate the VLAN Node Selector value
+ expectLabels := false
+ found = false
+ for _, val := range moduleLib.VLAN_NODE_SELECTORS {
+ if strings.ToLower(p.Spec.Vlan.VlanNodeSelector) == val {
+ found = true
+ if val == moduleLib.VLAN_NODE_SPECIFIC {
+ expectLabels = true
+ }
+ break
+ }
+ }
+ if !found {
+ return pkgerrors.Errorf("Invalid VlAN Node Selector %v", p.Spec.Vlan.VlanNodeSelector)
+ }
+
+ // validate the node label list
+ gotLabels := false
+ for _, label := range p.Spec.Vlan.NodeLabelList {
+ errs = validation.IsValidLabel(label)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid Label=%v - errors: %v", label, errs)
+ }
+ gotLabels = true
+ }
+
+ // Need at least one label if node selector value was "specific"
+ // (if selector is "any" - don't care if labels were supplied or not
+ if expectLabels && !gotLabels {
+ return pkgerrors.Errorf("Node Labels required for VlAN node selector \"%v\"", moduleLib.VLAN_NODE_SPECIFIC)
+ }
+
+ return nil
+}
+
+// Create handles creation of the ProviderNet entry in the database
+func (h providernetHandler) createProviderNetHandler(w http.ResponseWriter, r *http.Request) {
+ var p moduleLib.ProviderNet
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Name is required.
+ if p.Metadata.Name == "" {
+ http.Error(w, "Missing name in POST request", http.StatusBadRequest)
+ return
+ }
+
+ err = validateProviderNetInputs(p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ ret, err := h.client.CreateProviderNet(p, clusterProvider, cluster, false)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Put handles creation/update of the ProviderNet entry in the database
+func (h providernetHandler) putProviderNetHandler(w http.ResponseWriter, r *http.Request) {
+ var p moduleLib.ProviderNet
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+ name := vars["name"]
+
+ err := json.NewDecoder(r.Body).Decode(&p)
+
+ switch {
+ case err == io.EOF:
+ http.Error(w, "Empty body", http.StatusBadRequest)
+ return
+ case err != nil:
+ http.Error(w, err.Error(), http.StatusUnprocessableEntity)
+ return
+ }
+
+ // Name is required.
+ if p.Metadata.Name == "" {
+ http.Error(w, "Missing name in PUT request", http.StatusBadRequest)
+ return
+ }
+
+ // Name in URL should match name in body
+ if p.Metadata.Name != name {
+ fmt.Printf("bodyname = %v, name= %v\n", p.Metadata.Name, name)
+ http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest)
+ return
+ }
+
+ err = validateProviderNetInputs(p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ ret, err := h.client.CreateProviderNet(p, clusterProvider, cluster, true)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Get handles GET operations on a particular ProviderNet Name
+// Returns a ProviderNet
+func (h providernetHandler) getProviderNetHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+ name := vars["name"]
+ var ret interface{}
+ var err error
+
+ if len(name) == 0 {
+ ret, err = h.client.GetProviderNets(clusterProvider, cluster)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ } else {
+ ret, err = h.client.GetProviderNet(name, clusterProvider, cluster)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// Delete handles DELETE operations on a particular ProviderNet Name
+func (h providernetHandler) deleteProviderNetHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ clusterProvider := vars["provider-name"]
+ cluster := vars["cluster-name"]
+ name := vars["name"]
+
+ err := h.client.DeleteProviderNet(name, clusterProvider, cluster)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusNoContent)
+}
diff --git a/src/ncm/pkg/module/cluster.go b/src/ncm/pkg/module/cluster.go
index c9ddad6e..e3260b7e 100644
--- a/src/ncm/pkg/module/cluster.go
+++ b/src/ncm/pkg/module/cluster.go
@@ -23,14 +23,6 @@ import (
)
// ClusterProvider contains the parameters needed for ClusterProviders
-// It implements the interface for managing the ClusterProviders
-type Metadata struct {
- Name string `json:"name"`
- Description string `json:"description"`
- UserData1 string `json:"userData1"`
- UserData2 string `json:"userData2"`
-}
-
type ClusterProvider struct {
Metadata Metadata `json:"metadata"`
}
@@ -105,18 +97,18 @@ type ClusterManager interface {
// ClusterClient implements the Manager
// It will also be used to maintain some localized state
type ClusterClient struct {
- storeName string
- tagMeta string
- tagContent string
+ db ClientDbInfo
}
// NewClusterClient returns an instance of the ClusterClient
// which implements the Manager
func NewClusterClient() *ClusterClient {
return &ClusterClient{
- storeName: "cluster",
- tagMeta: "clustermetadata",
- tagContent: "clustercontent",
+ db: ClientDbInfo{
+ storeName: "cluster",
+ tagMeta: "clustermetadata",
+ tagContent: "clustercontent",
+ },
}
}
@@ -134,7 +126,7 @@ func (v *ClusterClient) CreateClusterProvider(p ClusterProvider) (ClusterProvide
return ClusterProvider{}, pkgerrors.New("ClusterProvider already exists")
}
- err = db.DBconn.Insert(v.storeName, key, nil, v.tagMeta, p)
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
if err != nil {
return ClusterProvider{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -150,7 +142,7 @@ func (v *ClusterClient) GetClusterProvider(name string) (ClusterProvider, error)
ClusterProviderName: name,
}
- value, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return ClusterProvider{}, pkgerrors.Wrap(err, "Get ClusterProvider")
}
@@ -160,7 +152,7 @@ func (v *ClusterClient) GetClusterProvider(name string) (ClusterProvider, error)
cp := ClusterProvider{}
err = db.DBconn.Unmarshal(value[0], &cp)
if err != nil {
- return ClusterProvider{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return ClusterProvider{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
return cp, nil
}
@@ -177,7 +169,7 @@ func (v *ClusterClient) GetClusterProviders() ([]ClusterProvider, error) {
}
var resp []ClusterProvider
- values, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return []ClusterProvider{}, pkgerrors.Wrap(err, "Get ClusterProviders")
}
@@ -186,7 +178,7 @@ func (v *ClusterClient) GetClusterProviders() ([]ClusterProvider, error) {
cp := ClusterProvider{}
err = db.DBconn.Unmarshal(value, &cp)
if err != nil {
- return []ClusterProvider{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return []ClusterProvider{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
resp = append(resp, cp)
}
@@ -202,7 +194,7 @@ func (v *ClusterClient) DeleteClusterProvider(name string) error {
ClusterProviderName: name,
}
- err := db.DBconn.Remove(v.storeName, key)
+ err := db.DBconn.Remove(v.db.storeName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete ClusterProvider Entry;")
}
@@ -231,11 +223,11 @@ func (v *ClusterClient) CreateCluster(provider string, p Cluster, q ClusterConte
return Cluster{}, pkgerrors.New("Cluster already exists")
}
- err = db.DBconn.Insert(v.storeName, key, nil, v.tagMeta, p)
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
if err != nil {
return Cluster{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
- err = db.DBconn.Insert(v.storeName, key, nil, v.tagContent, q)
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagContent, q)
if err != nil {
return Cluster{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -251,7 +243,7 @@ func (v *ClusterClient) GetCluster(provider, name string) (Cluster, error) {
ClusterName: name,
}
- value, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return Cluster{}, pkgerrors.Wrap(err, "Get Cluster")
}
@@ -261,7 +253,7 @@ func (v *ClusterClient) GetCluster(provider, name string) (Cluster, error) {
cl := Cluster{}
err = db.DBconn.Unmarshal(value[0], &cl)
if err != nil {
- return Cluster{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return Cluster{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
return cl, nil
}
@@ -277,7 +269,7 @@ func (v *ClusterClient) GetClusterContent(provider, name string) (ClusterContent
ClusterName: name,
}
- value, err := db.DBconn.Find(v.storeName, key, v.tagContent)
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagContent)
if err != nil {
return ClusterContent{}, pkgerrors.Wrap(err, "Get Cluster Content")
}
@@ -287,7 +279,7 @@ func (v *ClusterClient) GetClusterContent(provider, name string) (ClusterContent
cc := ClusterContent{}
err = db.DBconn.Unmarshal(value[0], &cc)
if err != nil {
- return ClusterContent{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return ClusterContent{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
return cc, nil
}
@@ -303,7 +295,7 @@ func (v *ClusterClient) GetClusters(provider string) ([]Cluster, error) {
ClusterName: "",
}
- values, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return []Cluster{}, pkgerrors.Wrap(err, "Get Clusters")
}
@@ -314,7 +306,7 @@ func (v *ClusterClient) GetClusters(provider string) ([]Cluster, error) {
cp := Cluster{}
err = db.DBconn.Unmarshal(value, &cp)
if err != nil {
- return []Cluster{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return []Cluster{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
resp = append(resp, cp)
}
@@ -330,7 +322,7 @@ func (v *ClusterClient) DeleteCluster(provider, name string) error {
ClusterName: name,
}
- err := db.DBconn.Remove(v.storeName, key)
+ err := db.DBconn.Remove(v.db.storeName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete Cluster Entry;")
}
@@ -359,7 +351,7 @@ func (v *ClusterClient) CreateClusterLabel(provider string, cluster string, p Cl
return ClusterLabel{}, pkgerrors.New("Cluster Label already exists")
}
- err = db.DBconn.Insert(v.storeName, key, nil, v.tagMeta, p)
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
if err != nil {
return ClusterLabel{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -376,7 +368,7 @@ func (v *ClusterClient) GetClusterLabel(provider, cluster, label string) (Cluste
ClusterLabelName: label,
}
- value, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return ClusterLabel{}, pkgerrors.Wrap(err, "Get Cluster")
}
@@ -386,7 +378,7 @@ func (v *ClusterClient) GetClusterLabel(provider, cluster, label string) (Cluste
cl := ClusterLabel{}
err = db.DBconn.Unmarshal(value[0], &cl)
if err != nil {
- return ClusterLabel{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return ClusterLabel{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
return cl, nil
}
@@ -403,7 +395,7 @@ func (v *ClusterClient) GetClusterLabels(provider, cluster string) ([]ClusterLab
ClusterLabelName: "",
}
- values, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return []ClusterLabel{}, pkgerrors.Wrap(err, "Get Cluster Labels")
}
@@ -414,7 +406,7 @@ func (v *ClusterClient) GetClusterLabels(provider, cluster string) ([]ClusterLab
cp := ClusterLabel{}
err = db.DBconn.Unmarshal(value, &cp)
if err != nil {
- return []ClusterLabel{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return []ClusterLabel{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
resp = append(resp, cp)
}
@@ -431,7 +423,7 @@ func (v *ClusterClient) DeleteClusterLabel(provider, cluster, label string) erro
ClusterLabelName: label,
}
- err := db.DBconn.Remove(v.storeName, key)
+ err := db.DBconn.Remove(v.db.storeName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete ClusterLabel Entry;")
}
@@ -459,7 +451,7 @@ func (v *ClusterClient) CreateClusterKvPairs(provider string, cluster string, p
return ClusterKvPairs{}, pkgerrors.New("Cluster KV Pair already exists")
}
- err = db.DBconn.Insert(v.storeName, key, nil, v.tagMeta, p)
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
if err != nil {
return ClusterKvPairs{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -476,7 +468,7 @@ func (v *ClusterClient) GetClusterKvPairs(provider, cluster, kvpair string) (Clu
ClusterKvPairsName: kvpair,
}
- value, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return ClusterKvPairs{}, pkgerrors.Wrap(err, "Get Cluster")
}
@@ -486,7 +478,7 @@ func (v *ClusterClient) GetClusterKvPairs(provider, cluster, kvpair string) (Clu
ckvp := ClusterKvPairs{}
err = db.DBconn.Unmarshal(value[0], &ckvp)
if err != nil {
- return ClusterKvPairs{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return ClusterKvPairs{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
return ckvp, nil
}
@@ -503,7 +495,7 @@ func (v *ClusterClient) GetAllClusterKvPairs(provider, cluster string) ([]Cluste
ClusterKvPairsName: "",
}
- values, err := db.DBconn.Find(v.storeName, key, v.tagMeta)
+ values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
if err != nil {
return []ClusterKvPairs{}, pkgerrors.Wrap(err, "Get Cluster KV Pairs")
}
@@ -514,7 +506,7 @@ func (v *ClusterClient) GetAllClusterKvPairs(provider, cluster string) ([]Cluste
cp := ClusterKvPairs{}
err = db.DBconn.Unmarshal(value, &cp)
if err != nil {
- return []ClusterKvPairs{}, pkgerrors.Wrap(err, "Unmarshaling Value")
+ return []ClusterKvPairs{}, pkgerrors.Wrap(err, "Unmarshalling Value")
}
resp = append(resp, cp)
}
@@ -531,7 +523,7 @@ func (v *ClusterClient) DeleteClusterKvPairs(provider, cluster, kvpair string) e
ClusterKvPairsName: kvpair,
}
- err := db.DBconn.Remove(v.storeName, key)
+ err := db.DBconn.Remove(v.db.storeName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete ClusterKvPairs Entry;")
}
diff --git a/src/ncm/pkg/module/module.go b/src/ncm/pkg/module/module.go
index c1c24510..a9950901 100644
--- a/src/ncm/pkg/module/module.go
+++ b/src/ncm/pkg/module/module.go
@@ -18,7 +18,9 @@ package module
// Client for using the services in the orchestrator
type Client struct {
- Cluster *ClusterClient
+ Cluster *ClusterClient
+ Network *NetworkClient
+ ProviderNet *ProviderNetClient
// Add Clients for API's here
}
@@ -26,6 +28,8 @@ type Client struct {
func NewClient() *Client {
c := &Client{}
c.Cluster = NewClusterClient()
+ c.Network = NewNetworkClient()
+ c.ProviderNet = NewProviderNetClient()
// Add Client API handlers here
return c
}
diff --git a/src/ncm/pkg/module/module_definitions.go b/src/ncm/pkg/module/module_definitions.go
new file mode 100644
index 00000000..1e839014
--- /dev/null
+++ b/src/ncm/pkg/module/module_definitions.go
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package module
+
+import (
+ "strings"
+
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
+ pkgerrors "github.com/pkg/errors"
+)
+
+const VLAN_PROVIDER_NET_TYPE_VLAN string = "VLAN"
+const VLAN_PROVIDER_NET_TYPE_DIRECT string = "DIRECT"
+
+var PROVIDER_NET_TYPES = [...]string{VLAN_PROVIDER_NET_TYPE_VLAN, VLAN_PROVIDER_NET_TYPE_DIRECT}
+
+const CNI_TYPE_OVN4NFV string = "ovn4nfv"
+
+var CNI_TYPES = [...]string{CNI_TYPE_OVN4NFV}
+
+// It implements the interface for managing the ClusterProviders
+type Metadata struct {
+ Name string `json:"name"`
+ Description string `json:"description"`
+ UserData1 string `json:"userData1"`
+ UserData2 string `json:"userData2"`
+}
+
+type ClientDbInfo struct {
+ storeName string // name of the mongodb collection to use for client documents
+ tagMeta string // attribute key name for the json data of a client document
+ tagContent string // attribute key name for the file data of a client document
+}
+
+type Ipv4Subnet struct {
+ Subnet string `json:"subnet"` // CIDR notation, e.g. 172.16.33.0/24
+ Name string `json:"name"`
+ Gateway string `json:"gateway"` // IPv4 addre, e.g. 172.16.33.1/24
+ Exclude string `json:"excludeIps"` // space separated list of single IPs or ranges e.g. "172.16.33.2 172.16.33.5..172.16.33.10"
+}
+
+const VLAN_NODE_ANY = "any"
+const VLAN_NODE_SPECIFIC = "specific"
+
+var VLAN_NODE_SELECTORS = [...]string{VLAN_NODE_ANY, VLAN_NODE_SPECIFIC}
+
+type Vlan struct {
+ VlanId int `json:"vlanID"`
+ ProviderInterfaceName string `json:"providerInterfaceName"`
+ LogicalInterfaceName string `json:"logicalInterfaceName"`
+ VlanNodeSelector string `json:"vlanNodeSelector"`
+ NodeLabelList []string `json:"nodeLabelList"`
+}
+
+// Check for valid format of an Ipv4Subnet
+func ValidateSubnet(sub Ipv4Subnet) error {
+ // verify subnet is in valid cidr format
+ err := validation.IsIpv4Cidr(sub.Subnet)
+ if err != nil {
+ return pkgerrors.Wrap(err, "invalid subnet")
+ }
+
+ // just a size check on interface name - system dependent
+ errs := validation.IsValidName(sub.Name)
+ if len(errs) > 0 {
+ return pkgerrors.Errorf("Invalid subnet name=[%v], errors: %v", sub.Name, errs)
+ }
+
+ // verify gateway is in valid cidr format
+ if len(sub.Gateway) > 0 {
+ err = validation.IsIpv4Cidr(sub.Gateway)
+ if err != nil {
+ return pkgerrors.Wrap(err, "invalid gateway")
+ }
+ }
+
+ // verify excludeIps is composed of space separated ipv4 addresses and
+ // ipv4 address ranges separated by '..'
+ for _, value := range strings.Fields(sub.Exclude) {
+ for _, ip := range strings.SplitN(value, "..", 2) {
+ err = validation.IsIpv4(ip)
+ if err != nil {
+ return pkgerrors.Errorf("invalid ipv4 exclude list %v", sub.Exclude)
+ }
+ }
+ }
+ return nil
+}
diff --git a/src/ncm/pkg/module/network.go b/src/ncm/pkg/module/network.go
new file mode 100644
index 00000000..2d4121e9
--- /dev/null
+++ b/src/ncm/pkg/module/network.go
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package module
+
+import (
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+// Network contains the parameters needed for dynamic networks
+type Network struct {
+ Metadata Metadata `json:"metadata"`
+ Spec NetworkSpec `json:"spec"`
+}
+
+type NetworkSpec struct {
+ CniType string `json:"cniType"`
+ Ipv4Subnets []Ipv4Subnet `json:"ipv4Subnets"`
+}
+
+// NetworkKey is the key structure that is used in the database
+type NetworkKey struct {
+ ClusterProviderName string `json:"provider"`
+ ClusterName string `json:"cluster"`
+ NetworkName string `json:"network"`
+}
+
+// Manager is an interface exposing the Network functionality
+type NetworkManager interface {
+ CreateNetwork(pr Network, clusterProvider, cluster string, exists bool) (Network, error)
+ GetNetwork(name, clusterProvider, cluster string) (Network, error)
+ GetNetworks(clusterProvider, cluster string) ([]Network, error)
+ DeleteNetwork(name, clusterProvider, cluster string) error
+}
+
+// NetworkClient implements the Manager
+// It will also be used to maintain some localized state
+type NetworkClient struct {
+ db ClientDbInfo
+}
+
+// NewNetworkClient returns an instance of the NetworkClient
+// which implements the Manager
+func NewNetworkClient() *NetworkClient {
+ return &NetworkClient{
+ db: ClientDbInfo{
+ storeName: "cluster",
+ tagMeta: "networkmetadata",
+ },
+ }
+}
+
+// CreateNetwork - create a new Network
+func (v *NetworkClient) CreateNetwork(p Network, clusterProvider, cluster string, exists bool) (Network, error) {
+
+ //Construct key and tag to select the entry
+ key := NetworkKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ NetworkName: p.Metadata.Name,
+ }
+
+ //Check if cluster exists
+ _, err := NewClusterClient().GetCluster(clusterProvider, cluster)
+ if err != nil {
+ return Network{}, pkgerrors.New("Unable to find the cluster")
+ }
+
+ //Check if this Network already exists
+ _, err = v.GetNetwork(p.Metadata.Name, clusterProvider, cluster)
+ if err == nil && !exists {
+ return Network{}, pkgerrors.New("Network already exists")
+ }
+
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
+ if err != nil {
+ return Network{}, pkgerrors.Wrap(err, "Creating DB Entry")
+ }
+
+ return p, nil
+}
+
+// GetNetwork returns the Network for corresponding name
+func (v *NetworkClient) GetNetwork(name, clusterProvider, cluster string) (Network, error) {
+
+ //Construct key and tag to select the entry
+ key := NetworkKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ NetworkName: name,
+ }
+
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ if err != nil {
+ return Network{}, pkgerrors.Wrap(err, "Get Network")
+ }
+
+ //value is a byte array
+ if value != nil {
+ cp := Network{}
+ err = db.DBconn.Unmarshal(value[0], &cp)
+ if err != nil {
+ return Network{}, pkgerrors.Wrap(err, "Unmarshalling Value")
+ }
+ return cp, nil
+ }
+
+ return Network{}, pkgerrors.New("Error getting Network")
+}
+
+// GetNetworkList returns all of the Network for corresponding name
+func (v *NetworkClient) GetNetworks(clusterProvider, cluster string) ([]Network, error) {
+
+ //Construct key and tag to select the entry
+ key := NetworkKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ NetworkName: "",
+ }
+
+ var resp []Network
+ values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ if err != nil {
+ return []Network{}, pkgerrors.Wrap(err, "Get Networks")
+ }
+
+ for _, value := range values {
+ cp := Network{}
+ err = db.DBconn.Unmarshal(value, &cp)
+ if err != nil {
+ return []Network{}, pkgerrors.Wrap(err, "Unmarshalling Value")
+ }
+ resp = append(resp, cp)
+ }
+
+ return resp, nil
+}
+
+// Delete the Network from database
+func (v *NetworkClient) DeleteNetwork(name, clusterProvider, cluster string) error {
+
+ //Construct key and tag to select the entry
+ key := NetworkKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ NetworkName: name,
+ }
+
+ err := db.DBconn.Remove(v.db.storeName, key)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Delete Network Entry;")
+ }
+
+ return nil
+}
diff --git a/src/ncm/pkg/module/providernet.go b/src/ncm/pkg/module/providernet.go
new file mode 100644
index 00000000..5e2c0343
--- /dev/null
+++ b/src/ncm/pkg/module/providernet.go
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package module
+
+import (
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+// ProviderNet contains the parameters needed for dynamic networks
+type ProviderNet struct {
+ Metadata Metadata `json:"metadata"`
+ Spec ProviderNetSpec `json:"spec"`
+}
+
+type ProviderNetSpec struct {
+ CniType string `json:"cniType"`
+ Ipv4Subnets []Ipv4Subnet `json:"ipv4Subnets"`
+ ProviderNetType string `json:"providerNetType"`
+ Vlan Vlan `json:"vlan"`
+}
+
+// ProviderNetKey is the key structure that is used in the database
+type ProviderNetKey struct {
+ ClusterProviderName string `json:"provider"`
+ ClusterName string `json:"cluster"`
+ ProviderNetName string `json:"providernet"`
+}
+
+// Manager is an interface exposing the ProviderNet functionality
+type ProviderNetManager interface {
+ CreateProviderNet(pr ProviderNet, clusterProvider, cluster string, exists bool) (ProviderNet, error)
+ GetProviderNet(name, clusterProvider, cluster string) (ProviderNet, error)
+ GetProviderNets(clusterProvider, cluster string) ([]ProviderNet, error)
+ DeleteProviderNet(name, clusterProvider, cluster string) error
+}
+
+// ProviderNetClient implements the Manager
+// It will also be used to maintain some localized state
+type ProviderNetClient struct {
+ db ClientDbInfo
+}
+
+// NewProviderNetClient returns an instance of the ProviderNetClient
+// which implements the Manager
+func NewProviderNetClient() *ProviderNetClient {
+ return &ProviderNetClient{
+ db: ClientDbInfo{
+ storeName: "cluster",
+ tagMeta: "networkmetadata",
+ },
+ }
+}
+
+// CreateProviderNet - create a new ProviderNet
+func (v *ProviderNetClient) CreateProviderNet(p ProviderNet, clusterProvider, cluster string, exists bool) (ProviderNet, error) {
+
+ //Construct key and tag to select the entry
+ key := ProviderNetKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ ProviderNetName: p.Metadata.Name,
+ }
+
+ //Check if cluster exists
+ _, err := NewClusterClient().GetCluster(clusterProvider, cluster)
+ if err != nil {
+ return ProviderNet{}, pkgerrors.New("Unable to find the cluster")
+ }
+
+ //Check if this ProviderNet already exists
+ _, err = v.GetProviderNet(p.Metadata.Name, clusterProvider, cluster)
+ if err == nil && !exists {
+ return ProviderNet{}, pkgerrors.New("ProviderNet already exists")
+ }
+
+ err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
+ if err != nil {
+ return ProviderNet{}, pkgerrors.Wrap(err, "Creating DB Entry")
+ }
+
+ return p, nil
+}
+
+// GetProviderNet returns the ProviderNet for corresponding name
+func (v *ProviderNetClient) GetProviderNet(name, clusterProvider, cluster string) (ProviderNet, error) {
+
+ //Construct key and tag to select the entry
+ key := ProviderNetKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ ProviderNetName: name,
+ }
+
+ value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ if err != nil {
+ return ProviderNet{}, pkgerrors.Wrap(err, "Get ProviderNet")
+ }
+
+ //value is a byte array
+ if value != nil {
+ cp := ProviderNet{}
+ err = db.DBconn.Unmarshal(value[0], &cp)
+ if err != nil {
+ return ProviderNet{}, pkgerrors.Wrap(err, "Unmarshalling Value")
+ }
+ return cp, nil
+ }
+
+ return ProviderNet{}, pkgerrors.New("Error getting ProviderNet")
+}
+
+// GetProviderNetList returns all of the ProviderNet for corresponding name
+func (v *ProviderNetClient) GetProviderNets(clusterProvider, cluster string) ([]ProviderNet, error) {
+
+ //Construct key and tag to select the entry
+ key := ProviderNetKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ ProviderNetName: "",
+ }
+
+ var resp []ProviderNet
+ values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ if err != nil {
+ return []ProviderNet{}, pkgerrors.Wrap(err, "Get ProviderNets")
+ }
+
+ for _, value := range values {
+ cp := ProviderNet{}
+ err = db.DBconn.Unmarshal(value, &cp)
+ if err != nil {
+ return []ProviderNet{}, pkgerrors.Wrap(err, "Unmarshalling Value")
+ }
+ resp = append(resp, cp)
+ }
+
+ return resp, nil
+}
+
+// Delete the ProviderNet from database
+func (v *ProviderNetClient) DeleteProviderNet(name, clusterProvider, cluster string) error {
+
+ //Construct key and tag to select the entry
+ key := ProviderNetKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ ProviderNetName: name,
+ }
+
+ err := db.DBconn.Remove(v.db.storeName, key)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Delete ProviderNet Entry;")
+ }
+
+ return nil
+}