From 529906640a6844dd371de37631e3948d328a390b Mon Sep 17 00:00:00 2001 From: Eric Multanen Date: Fri, 13 Mar 2020 17:39:40 -0700 Subject: 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 Change-Id: If3c71691b3825db50eacdb0ea87b0d5c436ad80f --- src/ncm/pkg/module/cluster.go | 74 ++++++------- src/ncm/pkg/module/module.go | 6 +- src/ncm/pkg/module/module_definitions.go | 101 ++++++++++++++++++ src/ncm/pkg/module/network.go | 170 ++++++++++++++++++++++++++++++ src/ncm/pkg/module/providernet.go | 172 +++++++++++++++++++++++++++++++ 5 files changed, 481 insertions(+), 42 deletions(-) create mode 100644 src/ncm/pkg/module/module_definitions.go create mode 100644 src/ncm/pkg/module/network.go create mode 100644 src/ncm/pkg/module/providernet.go (limited to 'src/ncm/pkg') 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 +} -- cgit 1.2.3-korg