summaryrefslogtreecommitdiffstats
path: root/src/ncm/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'src/ncm/pkg')
-rw-r--r--src/ncm/pkg/cluster/cluster.go (renamed from src/ncm/pkg/module/cluster.go)312
-rw-r--r--src/ncm/pkg/grpc/rsyncclient.go41
-rw-r--r--src/ncm/pkg/module/module.go20
-rw-r--r--src/ncm/pkg/module/types/module_definitions.go24
-rw-r--r--src/ncm/pkg/networkintents/network.go (renamed from src/ncm/pkg/module/network.go)32
-rw-r--r--src/ncm/pkg/networkintents/providernet.go (renamed from src/ncm/pkg/module/providernet.go)34
-rw-r--r--src/ncm/pkg/networkintents/types/types.go90
-rw-r--r--src/ncm/pkg/scheduler/scheduler.go220
8 files changed, 418 insertions, 355 deletions
diff --git a/src/ncm/pkg/module/cluster.go b/src/ncm/pkg/cluster/cluster.go
index 5d1f577f..f656688c 100644
--- a/src/ncm/pkg/module/cluster.go
+++ b/src/ncm/pkg/cluster/cluster.go
@@ -14,31 +14,24 @@
* limitations under the License.
*/
-package module
+package cluster
import (
- "context"
- "encoding/json"
- "time"
-
- "github.com/onap/multicloud-k8s/src/ncm/pkg/grpc"
+ ncmtypes "github.com/onap/multicloud-k8s/src/ncm/pkg/module/types"
appcontext "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
- log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
- "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/rpc"
- installpb "github.com/onap/multicloud-k8s/src/rsync/pkg/grpc/installapp"
- "gopkg.in/yaml.v2"
+ mtypes "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/types"
pkgerrors "github.com/pkg/errors"
)
// ClusterProvider contains the parameters needed for ClusterProviders
type ClusterProvider struct {
- Metadata Metadata `json:"metadata"`
+ Metadata mtypes.Metadata `json:"metadata"`
}
type Cluster struct {
- Metadata Metadata `json:"metadata"`
+ Metadata mtypes.Metadata `json:"metadata"`
}
type ClusterContent struct {
@@ -50,8 +43,8 @@ type ClusterLabel struct {
}
type ClusterKvPairs struct {
- Metadata Metadata `json:"metadata"`
- Spec ClusterKvSpec `json:"spec"`
+ Metadata mtypes.Metadata `json:"metadata"`
+ Spec ClusterKvSpec `json:"spec"`
}
type ClusterKvSpec struct {
@@ -106,8 +99,6 @@ type ClusterManager interface {
GetClusters(provider string) ([]Cluster, error)
GetClustersWithLabel(provider, label string) ([]string, error)
DeleteCluster(provider, name string) error
- ApplyNetworkIntents(provider, name string) error
- TerminateNetworkIntents(provider, name string) error
CreateClusterLabel(provider, cluster string, pr ClusterLabel) (ClusterLabel, error)
GetClusterLabel(provider, cluster, label string) (ClusterLabel, error)
GetClusterLabels(provider, cluster string) ([]ClusterLabel, error)
@@ -121,18 +112,18 @@ type ClusterManager interface {
// ClusterClient implements the Manager
// It will also be used to maintain some localized state
type ClusterClient struct {
- db ClientDbInfo
+ db ncmtypes.ClientDbInfo
}
// NewClusterClient returns an instance of the ClusterClient
// which implements the Manager
func NewClusterClient() *ClusterClient {
return &ClusterClient{
- db: ClientDbInfo{
- storeName: "cluster",
- tagMeta: "clustermetadata",
- tagContent: "clustercontent",
- tagContext: "clustercontext",
+ db: ncmtypes.ClientDbInfo{
+ StoreName: "cluster",
+ TagMeta: "clustermetadata",
+ TagContent: "clustercontent",
+ TagContext: "clustercontext",
},
}
}
@@ -151,7 +142,7 @@ func (v *ClusterClient) CreateClusterProvider(p ClusterProvider) (ClusterProvide
return ClusterProvider{}, pkgerrors.New("ClusterProvider already exists")
}
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.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")
}
@@ -167,7 +158,7 @@ func (v *ClusterClient) GetClusterProvider(name string) (ClusterProvider, error)
ClusterProviderName: name,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return ClusterProvider{}, pkgerrors.Wrap(err, "Get ClusterProvider")
}
@@ -194,7 +185,7 @@ func (v *ClusterClient) GetClusterProviders() ([]ClusterProvider, error) {
}
var resp []ClusterProvider
- values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ values, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return []ClusterProvider{}, pkgerrors.Wrap(err, "Get ClusterProviders")
}
@@ -219,7 +210,7 @@ func (v *ClusterClient) DeleteClusterProvider(name string) error {
ClusterProviderName: name,
}
- err := db.DBconn.Remove(v.db.storeName, key)
+ err := db.DBconn.Remove(v.db.StoreName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete ClusterProvider Entry;")
}
@@ -248,11 +239,11 @@ func (v *ClusterClient) CreateCluster(provider string, p Cluster, q ClusterConte
return Cluster{}, pkgerrors.New("Cluster already exists")
}
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.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.db.storeName, key, nil, v.db.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")
}
@@ -268,7 +259,7 @@ func (v *ClusterClient) GetCluster(provider, name string) (Cluster, error) {
ClusterName: name,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return Cluster{}, pkgerrors.Wrap(err, "Get Cluster")
}
@@ -294,7 +285,7 @@ func (v *ClusterClient) GetClusterContent(provider, name string) (ClusterContent
ClusterName: name,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagContent)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagContent)
if err != nil {
return ClusterContent{}, pkgerrors.Wrap(err, "Get Cluster Content")
}
@@ -320,7 +311,7 @@ func (v *ClusterClient) GetClusterContext(provider, name string) (appcontext.App
ClusterName: name,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagContext)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagContext)
if err != nil {
return appcontext.AppContext{}, pkgerrors.Wrap(err, "Get Cluster Context")
}
@@ -347,7 +338,7 @@ func (v *ClusterClient) GetClusters(provider string) ([]Cluster, error) {
ClusterName: "",
}
- values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ values, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return []Cluster{}, pkgerrors.Wrap(err, "Get Clusters")
}
@@ -375,7 +366,7 @@ func (v *ClusterClient) GetClustersWithLabel(provider, label string) ([]string,
ClusterLabelName: label,
}
- values, err := db.DBconn.Find(v.db.storeName, key, "cluster")
+ values, err := db.DBconn.Find(v.db.StoreName, key, "cluster")
if err != nil {
return []string{}, pkgerrors.Wrap(err, "Get Clusters by label")
}
@@ -401,7 +392,7 @@ func (v *ClusterClient) DeleteCluster(provider, name string) error {
return pkgerrors.Errorf("Cannot delete cluster until context is deleted: %v, %v", provider, name)
}
- err = db.DBconn.Remove(v.db.storeName, key)
+ err = db.DBconn.Remove(v.db.StoreName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete Cluster Entry;")
}
@@ -409,243 +400,6 @@ func (v *ClusterClient) DeleteCluster(provider, name string) error {
return nil
}
-// Apply Network Intents associated with a cluster
-func (v *ClusterClient) ApplyNetworkIntents(provider, name string) error {
-
- _, err := v.GetClusterContext(provider, name)
- if err == nil {
- return pkgerrors.Errorf("Cluster network intents have already been applied: %v, %v", provider, name)
- }
-
- type resource struct {
- name string
- value string
- }
-
- var resources []resource
-
- // Find all Network Intents for this cluster
- networkIntents, err := NewNetworkClient().GetNetworks(provider, name)
- if err != nil {
- return pkgerrors.Wrap(err, "Error finding Network Intents")
- }
- for _, intent := range networkIntents {
- var crNetwork = CrNetwork{
- ApiVersion: NETWORK_APIVERSION,
- Kind: NETWORK_KIND,
- }
- crNetwork.Network = intent
- // Produce the yaml CR document for each intent
- y, err := yaml.Marshal(&crNetwork)
- if err != nil {
- log.Info("Error marshalling network intent to yaml", log.Fields{
- "error": err,
- "intent": intent,
- })
- continue
- }
- resources = append(resources, resource{
- name: intent.Metadata.Name + SEPARATOR + NETWORK_KIND,
- value: string(y),
- })
- }
-
- // Find all Provider Network Intents for this cluster
- providerNetworkIntents, err := NewProviderNetClient().GetProviderNets(provider, name)
- if err != nil {
- return pkgerrors.Wrap(err, "Error finding Provider Network Intents")
- }
- for _, intent := range providerNetworkIntents {
- var crProviderNet = CrProviderNet{
- ApiVersion: PROVIDER_NETWORK_APIVERSION,
- Kind: PROVIDER_NETWORK_KIND,
- }
- crProviderNet.ProviderNet = intent
- // Produce the yaml CR document for each intent
- y, err := yaml.Marshal(&crProviderNet)
- if err != nil {
- log.Info("Error marshalling provider network intent to yaml", log.Fields{
- "error": err,
- "intent": intent,
- })
- continue
- }
- resources = append(resources, resource{
- name: intent.Metadata.Name + SEPARATOR + PROVIDER_NETWORK_KIND,
- value: string(y),
- })
- }
-
- if len(resources) == 0 {
- return nil
- }
-
- // Make an app context for the network intent resources
- ac := appcontext.AppContext{}
- ctxVal, err := ac.InitAppContext()
- if err != nil {
- return pkgerrors.Wrap(err, "Error creating AppContext")
- }
- handle, err := ac.CreateCompositeApp()
- if err != nil {
- return pkgerrors.Wrap(err, "Error creating AppContext CompositeApp")
- }
-
- // Add an app (fixed value) to the app context
- apphandle, err := ac.AddApp(handle, CONTEXT_CLUSTER_APP)
- if err != nil {
- cleanuperr := ac.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext CompositeApp create failure", log.Fields{
- "cluster-provider": provider,
- "cluster": name,
- })
- }
- return pkgerrors.Wrap(err, "Error adding App to AppContext")
- }
-
- // Add an app order instruction
- appinstr := struct {
- Apporder []string `json:"apporder"`
- }{
- []string{CONTEXT_CLUSTER_APP},
- }
- jinstr, _ := json.Marshal(appinstr)
-
- appdepinstr := struct {
- Appdep map[string]string `json:"appdependency"`
- }{
- map[string]string{CONTEXT_CLUSTER_APP: "go"},
- }
- jdep, _ := json.Marshal(appdepinstr)
-
- _, err = ac.AddInstruction(handle, "app", "order", string(jinstr))
- _, err = ac.AddInstruction(handle, "app", "dependency", string(jdep))
-
- // Add a cluster to the app
- clusterhandle, err := ac.AddCluster(apphandle, provider+SEPARATOR+name)
- if err != nil {
- cleanuperr := ac.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add cluster failure", log.Fields{
- "cluster-provider": provider,
- "cluster": name,
- })
- }
- return pkgerrors.Wrap(err, "Error adding Cluster to AppContext")
- }
-
- // add the resources to the app context
-
- var orderinstr struct {
- Resorder []string `json:"resorder"`
- }
- var depinstr struct {
- Resdep map[string]string `json:"resdependency"`
- }
- resdep := make(map[string]string)
- for _, resource := range resources {
- orderinstr.Resorder = append(orderinstr.Resorder, resource.name)
- resdep[resource.name] = "go"
- _, err = ac.AddResource(clusterhandle, resource.name, resource.value)
- if err != nil {
- cleanuperr := ac.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add resource failure", log.Fields{
- "cluster-provider": provider,
- "cluster": name,
- "resource": resource.name,
- })
- }
- return pkgerrors.Wrap(err, "Error adding Resource to AppContext")
- }
- }
- jresord, _ := json.Marshal(orderinstr)
- depinstr.Resdep = resdep
- jresdep, _ := json.Marshal(depinstr)
- _, err = ac.AddInstruction(clusterhandle, "resource", "order", string(jresord))
- _, err = ac.AddInstruction(clusterhandle, "resource", "dependency", string(jresdep))
-
- // save the context in the cluster db record
- key := ClusterKey{
- ClusterProviderName: provider,
- ClusterName: name,
- }
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagContext, ctxVal)
- if err != nil {
- cleanuperr := ac.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after DB insert failure", log.Fields{
- "cluster-provider": provider,
- "cluster": name,
- })
- }
- return pkgerrors.Wrap(err, "Error adding AppContext to DB")
- }
-
- // call resource synchronizer to instantiate the CRs in the cluster
- conn := rpc.GetRpcConn(grpc.RsyncName)
- if conn == nil {
- grpc.InitRsyncClient()
- conn = rpc.GetRpcConn(grpc.RsyncName)
- }
-
- var rpcClient installpb.InstallappClient
- var installRes *installpb.InstallAppResponse
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
-
- if conn != nil {
- rpcClient = installpb.NewInstallappClient(conn)
- installReq := new(installpb.InstallAppRequest)
- installReq.AppContext = ctxVal.(string)
- installRes, err = rpcClient.InstallApp(ctx, installReq)
- if err == nil {
- log.Info("Response from InstappApp GRPC call", log.Fields{
- "Succeeded": installRes.AppContextInstalled,
- "Message": installRes.AppContextInstallMessage,
- })
- }
- } else {
- return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", grpc.RsyncName)
- }
-
- return nil
-}
-
-// Terminate Network Intents associated with a cluster
-func (v *ClusterClient) TerminateNetworkIntents(provider, name string) error {
- context, err := v.GetClusterContext(provider, name)
- if err != nil {
- return pkgerrors.Wrapf(err, "Error finding AppContext for cluster: %v, %v", provider, name)
- }
-
- // TODO: call resource synchronizer to terminate the CRs in the cluster
-
- // remove the app context
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error deleted AppContext", log.Fields{
- "cluster-provider": provider,
- "cluster": name,
- })
- }
-
- // remove the app context field from the cluster db record
- key := ClusterKey{
- ClusterProviderName: provider,
- ClusterName: name,
- }
- err = db.DBconn.RemoveTag(v.db.storeName, key, v.db.tagContext)
- if err != nil {
- log.Warn("Error removing AppContext from Cluster document", log.Fields{
- "cluster-provider": provider,
- "cluster": name,
- })
- }
- return nil
-}
-
// CreateClusterLabel - create a new Cluster Label mongo document for a cluster-provider/cluster
func (v *ClusterClient) CreateClusterLabel(provider string, cluster string, p ClusterLabel) (ClusterLabel, error) {
//Construct key and tag to select the entry
@@ -667,7 +421,7 @@ func (v *ClusterClient) CreateClusterLabel(provider string, cluster string, p Cl
return ClusterLabel{}, pkgerrors.New("Cluster Label already exists")
}
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.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")
}
@@ -684,7 +438,7 @@ func (v *ClusterClient) GetClusterLabel(provider, cluster, label string) (Cluste
ClusterLabelName: label,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return ClusterLabel{}, pkgerrors.Wrap(err, "Get Cluster")
}
@@ -711,7 +465,7 @@ func (v *ClusterClient) GetClusterLabels(provider, cluster string) ([]ClusterLab
ClusterLabelName: "",
}
- values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ values, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return []ClusterLabel{}, pkgerrors.Wrap(err, "Get Cluster Labels")
}
@@ -739,7 +493,7 @@ func (v *ClusterClient) DeleteClusterLabel(provider, cluster, label string) erro
ClusterLabelName: label,
}
- err := db.DBconn.Remove(v.db.storeName, key)
+ err := db.DBconn.Remove(v.db.StoreName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete ClusterLabel Entry;")
}
@@ -767,7 +521,7 @@ func (v *ClusterClient) CreateClusterKvPairs(provider string, cluster string, p
return ClusterKvPairs{}, pkgerrors.New("Cluster KV Pair already exists")
}
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.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")
}
@@ -784,7 +538,7 @@ func (v *ClusterClient) GetClusterKvPairs(provider, cluster, kvpair string) (Clu
ClusterKvPairsName: kvpair,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return ClusterKvPairs{}, pkgerrors.Wrap(err, "Get Cluster")
}
@@ -811,7 +565,7 @@ func (v *ClusterClient) GetAllClusterKvPairs(provider, cluster string) ([]Cluste
ClusterKvPairsName: "",
}
- values, err := db.DBconn.Find(v.db.storeName, key, v.db.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")
}
@@ -839,7 +593,7 @@ func (v *ClusterClient) DeleteClusterKvPairs(provider, cluster, kvpair string) e
ClusterKvPairsName: kvpair,
}
- err := db.DBconn.Remove(v.db.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/grpc/rsyncclient.go b/src/ncm/pkg/grpc/rsyncclient.go
deleted file mode 100644
index 5eb870a7..00000000
--- a/src/ncm/pkg/grpc/rsyncclient.go
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-Copyright 2020 Intel Corporation.
-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 grpc
-
-import (
- log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
- "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/rpc"
- controller "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/controller"
-)
-
-const RsyncName = "rsync"
-
-// InitRsyncClient initializes connctions to the Resource Synchronizer serivice
-func InitRsyncClient() bool {
- client := controller.NewControllerClient()
-
- vals, _ := client.GetControllers()
- found := false
- for _, v := range vals {
- if v.Metadata.Name == RsyncName {
- log.Info("Initializing RPC connection to resource synchronizer", log.Fields{
- "Controller": v.Metadata.Name,
- })
- rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port)
- found = true
- break
- }
- }
- return found
-}
diff --git a/src/ncm/pkg/module/module.go b/src/ncm/pkg/module/module.go
index e3ebcccc..10b241f6 100644
--- a/src/ncm/pkg/module/module.go
+++ b/src/ncm/pkg/module/module.go
@@ -16,20 +16,28 @@
package module
+import (
+ "github.com/onap/multicloud-k8s/src/ncm/pkg/cluster"
+ "github.com/onap/multicloud-k8s/src/ncm/pkg/networkintents"
+ "github.com/onap/multicloud-k8s/src/ncm/pkg/scheduler"
+)
+
// Client for using the services in the ncm
type Client struct {
- Cluster *ClusterClient
- Network *NetworkClient
- ProviderNet *ProviderNetClient
+ Cluster *cluster.ClusterClient
+ Network *networkintents.NetworkClient
+ ProviderNet *networkintents.ProviderNetClient
+ Scheduler *scheduler.SchedulerClient
// Add Clients for API's here
}
// NewClient creates a new client for using the services
func NewClient() *Client {
c := &Client{}
- c.Cluster = NewClusterClient()
- c.Network = NewNetworkClient()
- c.ProviderNet = NewProviderNetClient()
+ c.Cluster = cluster.NewClusterClient()
+ c.Network = networkintents.NewNetworkClient()
+ c.ProviderNet = networkintents.NewProviderNetClient()
+ c.Scheduler = scheduler.NewSchedulerClient()
// Add Client API handlers here
return c
}
diff --git a/src/ncm/pkg/module/types/module_definitions.go b/src/ncm/pkg/module/types/module_definitions.go
new file mode 100644
index 00000000..0dd657ac
--- /dev/null
+++ b/src/ncm/pkg/module/types/module_definitions.go
@@ -0,0 +1,24 @@
+/*
+ * 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 types
+
+// TODO - should move to common module types location - e.g. in orchestrator
+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
+ TagContext string // attribute key name for context object in App Context
+}
diff --git a/src/ncm/pkg/module/network.go b/src/ncm/pkg/networkintents/network.go
index e753905e..e8480e0f 100644
--- a/src/ncm/pkg/module/network.go
+++ b/src/ncm/pkg/networkintents/network.go
@@ -14,23 +14,27 @@
* limitations under the License.
*/
-package module
+package networkintents
import (
+ clusterPkg "github.com/onap/multicloud-k8s/src/ncm/pkg/cluster"
+ ncmtypes "github.com/onap/multicloud-k8s/src/ncm/pkg/module/types"
+ nettypes "github.com/onap/multicloud-k8s/src/ncm/pkg/networkintents/types"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
+ mtypes "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/types"
pkgerrors "github.com/pkg/errors"
)
// Network contains the parameters needed for dynamic networks
type Network struct {
- Metadata Metadata `json:"metadata" yaml:"metadata"`
- Spec NetworkSpec `json:"spec" yaml:"spec"`
+ Metadata mtypes.Metadata `json:"metadata" yaml:"metadata"`
+ Spec NetworkSpec `json:"spec" yaml:"spec"`
}
type NetworkSpec struct {
- CniType string `json:"cniType" yaml:"cniType"`
- Ipv4Subnets []Ipv4Subnet `json:"ipv4Subnets" yaml:"ipv4Subnets"`
+ CniType string `json:"cniType" yaml:"cniType"`
+ Ipv4Subnets []nettypes.Ipv4Subnet `json:"ipv4Subnets" yaml:"ipv4Subnets"`
}
// NetworkKey is the key structure that is used in the database
@@ -61,16 +65,16 @@ type NetworkManager interface {
// NetworkClient implements the Manager
// It will also be used to maintain some localized state
type NetworkClient struct {
- db ClientDbInfo
+ db ncmtypes.ClientDbInfo
}
// NewNetworkClient returns an instance of the NetworkClient
// which implements the Manager
func NewNetworkClient() *NetworkClient {
return &NetworkClient{
- db: ClientDbInfo{
- storeName: "cluster",
- tagMeta: "networkmetadata",
+ db: ncmtypes.ClientDbInfo{
+ StoreName: "cluster",
+ TagMeta: "networkmetadata",
},
}
}
@@ -86,7 +90,7 @@ func (v *NetworkClient) CreateNetwork(p Network, clusterProvider, cluster string
}
//Check if cluster exists
- _, err := NewClusterClient().GetCluster(clusterProvider, cluster)
+ _, err := clusterPkg.NewClusterClient().GetCluster(clusterProvider, cluster)
if err != nil {
return Network{}, pkgerrors.New("Unable to find the cluster")
}
@@ -97,7 +101,7 @@ func (v *NetworkClient) CreateNetwork(p Network, clusterProvider, cluster string
return Network{}, pkgerrors.New("Network already exists")
}
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
+ err = db.DBconn.Insert(v.db.StoreName, key, nil, v.db.TagMeta, p)
if err != nil {
return Network{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -115,7 +119,7 @@ func (v *NetworkClient) GetNetwork(name, clusterProvider, cluster string) (Netwo
NetworkName: name,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return Network{}, pkgerrors.Wrap(err, "Get Network")
}
@@ -144,7 +148,7 @@ func (v *NetworkClient) GetNetworks(clusterProvider, cluster string) ([]Network,
}
var resp []Network
- values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ values, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return []Network{}, pkgerrors.Wrap(err, "Get Networks")
}
@@ -171,7 +175,7 @@ func (v *NetworkClient) DeleteNetwork(name, clusterProvider, cluster string) err
NetworkName: name,
}
- err := db.DBconn.Remove(v.db.storeName, key)
+ err := db.DBconn.Remove(v.db.StoreName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete Network Entry;")
}
diff --git a/src/ncm/pkg/module/providernet.go b/src/ncm/pkg/networkintents/providernet.go
index a1cbe940..0eb763c1 100644
--- a/src/ncm/pkg/module/providernet.go
+++ b/src/ncm/pkg/networkintents/providernet.go
@@ -14,25 +14,29 @@
* limitations under the License.
*/
-package module
+package networkintents
import (
+ clusterPkg "github.com/onap/multicloud-k8s/src/ncm/pkg/cluster"
+ ncmtypes "github.com/onap/multicloud-k8s/src/ncm/pkg/module/types"
+ nettypes "github.com/onap/multicloud-k8s/src/ncm/pkg/networkintents/types"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
+ mtypes "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/types"
pkgerrors "github.com/pkg/errors"
)
// ProviderNet contains the parameters needed for dynamic networks
type ProviderNet struct {
- Metadata Metadata `json:"metadata"`
+ Metadata mtypes.Metadata `json:"metadata"`
Spec ProviderNetSpec `json:"spec"`
}
type ProviderNetSpec struct {
- CniType string `json:"cniType" yaml:"cniType"`
- Ipv4Subnets []Ipv4Subnet `json:"ipv4Subnets" yaml:"ipv4Subnets"`
- ProviderNetType string `json:"providerNetType" yaml:"providerNetType"`
- Vlan Vlan `json:"vlan" yaml:"vlan"`
+ CniType string `json:"cniType" yaml:"cniType"`
+ Ipv4Subnets []nettypes.Ipv4Subnet `json:"ipv4Subnets" yaml:"ipv4Subnets"`
+ ProviderNetType string `json:"providerNetType" yaml:"providerNetType"`
+ Vlan nettypes.Vlan `json:"vlan" yaml:"vlan"`
}
// structure for the Network Custom Resource
@@ -63,16 +67,16 @@ type ProviderNetManager interface {
// ProviderNetClient implements the Manager
// It will also be used to maintain some localized state
type ProviderNetClient struct {
- db ClientDbInfo
+ db ncmtypes.ClientDbInfo
}
// NewProviderNetClient returns an instance of the ProviderNetClient
// which implements the Manager
func NewProviderNetClient() *ProviderNetClient {
return &ProviderNetClient{
- db: ClientDbInfo{
- storeName: "cluster",
- tagMeta: "networkmetadata",
+ db: ncmtypes.ClientDbInfo{
+ StoreName: "cluster",
+ TagMeta: "networkmetadata",
},
}
}
@@ -88,7 +92,7 @@ func (v *ProviderNetClient) CreateProviderNet(p ProviderNet, clusterProvider, cl
}
//Check if cluster exists
- _, err := NewClusterClient().GetCluster(clusterProvider, cluster)
+ _, err := clusterPkg.NewClusterClient().GetCluster(clusterProvider, cluster)
if err != nil {
return ProviderNet{}, pkgerrors.New("Unable to find the cluster")
}
@@ -99,7 +103,7 @@ func (v *ProviderNetClient) CreateProviderNet(p ProviderNet, clusterProvider, cl
return ProviderNet{}, pkgerrors.New("ProviderNet already exists")
}
- err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, p)
+ err = db.DBconn.Insert(v.db.StoreName, key, nil, v.db.TagMeta, p)
if err != nil {
return ProviderNet{}, pkgerrors.Wrap(err, "Creating DB Entry")
}
@@ -117,7 +121,7 @@ func (v *ProviderNetClient) GetProviderNet(name, clusterProvider, cluster string
ProviderNetName: name,
}
- value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ value, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return ProviderNet{}, pkgerrors.Wrap(err, "Get ProviderNet")
}
@@ -146,7 +150,7 @@ func (v *ProviderNetClient) GetProviderNets(clusterProvider, cluster string) ([]
}
var resp []ProviderNet
- values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
+ values, err := db.DBconn.Find(v.db.StoreName, key, v.db.TagMeta)
if err != nil {
return []ProviderNet{}, pkgerrors.Wrap(err, "Get ProviderNets")
}
@@ -173,7 +177,7 @@ func (v *ProviderNetClient) DeleteProviderNet(name, clusterProvider, cluster str
ProviderNetName: name,
}
- err := db.DBconn.Remove(v.db.storeName, key)
+ err := db.DBconn.Remove(v.db.StoreName, key)
if err != nil {
return pkgerrors.Wrap(err, "Delete ProviderNet Entry;")
}
diff --git a/src/ncm/pkg/networkintents/types/types.go b/src/ncm/pkg/networkintents/types/types.go
new file mode 100644
index 00000000..e6fea72e
--- /dev/null
+++ b/src/ncm/pkg/networkintents/types/types.go
@@ -0,0 +1,90 @@
+/*
+ * 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 types
+
+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"
+
+const SEPARATOR = "+"
+const CONTEXT_CLUSTER_APP = "network-intents"
+
+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}
+
+type Ipv4Subnet struct {
+ Subnet string `json:"subnet" yaml:"subnet"` // CIDR notation, e.g. 172.16.33.0/24
+ Name string `json:"name" yaml:"name"`
+ Gateway string `json:"gateway" yaml:"gateway"` // IPv4 addre, e.g. 172.16.33.1/24
+ Exclude string `json:"excludeIps" yaml:"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 string `json:"vlanID" yaml:"vlanId"`
+ ProviderInterfaceName string `json:"providerInterfaceName" yaml:"providerInterfaceName"`
+ LogicalInterfaceName string `json:"logicalInterfaceName" yaml:"logicalInterfaceName"`
+ VlanNodeSelector string `json:"vlanNodeSelector" yaml:"vlanNodeSelector"`
+ NodeLabelList []string `json:"nodeLabelList" yaml:"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/scheduler/scheduler.go b/src/ncm/pkg/scheduler/scheduler.go
new file mode 100644
index 00000000..e72085b7
--- /dev/null
+++ b/src/ncm/pkg/scheduler/scheduler.go
@@ -0,0 +1,220 @@
+/*
+ * 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 scheduler
+
+import (
+ "context"
+ "encoding/json"
+ "time"
+
+ "github.com/onap/multicloud-k8s/src/ncm/internal/grpc"
+ oc "github.com/onap/multicloud-k8s/src/ncm/internal/ovncontroller"
+ clusterPkg "github.com/onap/multicloud-k8s/src/ncm/pkg/cluster"
+ ncmtypes "github.com/onap/multicloud-k8s/src/ncm/pkg/module/types"
+ nettypes "github.com/onap/multicloud-k8s/src/ncm/pkg/networkintents/types"
+ appcontext "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
+ log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/rpc"
+ installpb "github.com/onap/multicloud-k8s/src/rsync/pkg/grpc/installapp"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+// ClusterManager is an interface exposes the Cluster functionality
+type SchedulerManager interface {
+ ApplyNetworkIntents(clusterProvider, cluster string) error
+ TerminateNetworkIntents(clusterProvider, cluster string) error
+}
+
+// ClusterClient implements the Manager
+// It will also be used to maintain some localized state
+type SchedulerClient struct {
+ db ncmtypes.ClientDbInfo
+}
+
+// NewSchedulerClient returns an instance of the SchedulerClient
+// which implements the Manager
+func NewSchedulerClient() *SchedulerClient {
+ return &SchedulerClient{
+ db: ncmtypes.ClientDbInfo{
+ StoreName: "cluster",
+ TagMeta: "clustermetadata",
+ TagContent: "clustercontent",
+ TagContext: "clustercontext",
+ },
+ }
+}
+
+// Apply Network Intents associated with a cluster
+func (v *SchedulerClient) ApplyNetworkIntents(clusterProvider, cluster string) error {
+
+ _, err := clusterPkg.NewClusterClient().GetClusterContext(clusterProvider, cluster)
+ if err == nil {
+ return pkgerrors.Errorf("Cluster network intents have already been applied: %v, %v", clusterProvider, cluster)
+ }
+
+ // Make an app context for the network intent resources
+ ac := appcontext.AppContext{}
+ ctxVal, err := ac.InitAppContext()
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error creating AppContext")
+ }
+ handle, err := ac.CreateCompositeApp()
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error creating AppContext CompositeApp")
+ }
+
+ // Add an app (fixed value) to the app context
+ apphandle, err := ac.AddApp(handle, nettypes.CONTEXT_CLUSTER_APP)
+ if err != nil {
+ cleanuperr := ac.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Warn("Error cleaning AppContext CompositeApp create failure", log.Fields{
+ "cluster-provider": clusterProvider,
+ "cluster": cluster,
+ })
+ }
+ return pkgerrors.Wrap(err, "Error adding App to AppContext")
+ }
+
+ // Add an app order instruction
+ appinstr := struct {
+ Apporder []string `json:"apporder"`
+ }{
+ []string{nettypes.CONTEXT_CLUSTER_APP},
+ }
+ jinstr, _ := json.Marshal(appinstr)
+
+ appdepinstr := struct {
+ Appdep map[string]string `json:"appdependency"`
+ }{
+ map[string]string{nettypes.CONTEXT_CLUSTER_APP: "go"},
+ }
+ jdep, _ := json.Marshal(appdepinstr)
+
+ _, err = ac.AddInstruction(handle, "app", "order", string(jinstr))
+ _, err = ac.AddInstruction(handle, "app", "dependency", string(jdep))
+
+ // Add a cluster to the app
+ _, err = ac.AddCluster(apphandle, clusterProvider+nettypes.SEPARATOR+cluster)
+ if err != nil {
+ cleanuperr := ac.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Warn("Error cleaning AppContext after add cluster failure", log.Fields{
+ "cluster-provider": clusterProvider,
+ "cluster": cluster,
+ })
+ }
+ return pkgerrors.Wrap(err, "Error adding Cluster to AppContext")
+ }
+
+ // Pass the context to the appropriate controller (just default ovncontroller now)
+ // for internal controller - pass the appcontext, cluster provider and cluster names in directly
+ // external controllers will be given the appcontext id and wiil have to recontstruct
+ // their own context
+ err = oc.Apply(ctxVal, clusterProvider, cluster)
+ if err != nil {
+ cleanuperr := ac.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Warn("Error cleaning AppContext after controller failure", log.Fields{
+ "cluster-provider": clusterProvider,
+ "cluster": cluster,
+ })
+ }
+ return pkgerrors.Wrap(err, "Error adding Cluster to AppContext")
+ }
+
+ // save the context in the cluster db record
+ key := clusterPkg.ClusterKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ }
+ err = db.DBconn.Insert(v.db.StoreName, key, nil, v.db.TagContext, ctxVal)
+ if err != nil {
+ cleanuperr := ac.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Warn("Error cleaning AppContext after DB insert failure", log.Fields{
+ "cluster-provider": clusterProvider,
+ "cluster": cluster,
+ })
+ }
+ return pkgerrors.Wrap(err, "Error adding AppContext to DB")
+ }
+
+ // call resource synchronizer to instantiate the CRs in the cluster
+ conn := rpc.GetRpcConn(grpc.RsyncName)
+ if conn == nil {
+ grpc.InitRsyncClient()
+ conn = rpc.GetRpcConn(grpc.RsyncName)
+ }
+
+ var rpcClient installpb.InstallappClient
+ var installRes *installpb.InstallAppResponse
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
+ if conn != nil {
+ rpcClient = installpb.NewInstallappClient(conn)
+ installReq := new(installpb.InstallAppRequest)
+ installReq.AppContext = ctxVal.(string)
+ installRes, err = rpcClient.InstallApp(ctx, installReq)
+ if err == nil {
+ log.Info("Response from InstappApp GRPC call", log.Fields{
+ "Succeeded": installRes.AppContextInstalled,
+ "Message": installRes.AppContextInstallMessage,
+ })
+ }
+ } else {
+ return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", grpc.RsyncName)
+ }
+
+ return nil
+}
+
+// Terminate Network Intents associated with a cluster
+func (v *SchedulerClient) TerminateNetworkIntents(clusterProvider, cluster string) error {
+ context, err := clusterPkg.NewClusterClient().GetClusterContext(clusterProvider, cluster)
+ if err != nil {
+ return pkgerrors.Wrapf(err, "Error finding AppContext for cluster: %v, %v", clusterProvider, cluster)
+ }
+
+ // TODO: call resource synchronizer to terminate the CRs in the cluster
+
+ // remove the app context
+ cleanuperr := context.DeleteCompositeApp()
+ if cleanuperr != nil {
+ log.Warn("Error deleted AppContext", log.Fields{
+ "cluster-provider": clusterProvider,
+ "cluster": cluster,
+ })
+ }
+
+ // remove the app context field from the cluster db record
+ key := clusterPkg.ClusterKey{
+ ClusterProviderName: clusterProvider,
+ ClusterName: cluster,
+ }
+ err = db.DBconn.RemoveTag(v.db.StoreName, key, v.db.TagContext)
+ if err != nil {
+ log.Warn("Error removing AppContext from Cluster document", log.Fields{
+ "cluster-provider": clusterProvider,
+ "cluster": cluster,
+ })
+ }
+ return nil
+}