From 4100bfb764c40e2a788d28691b0f891e2ae86b74 Mon Sep 17 00:00:00 2001 From: Eric Multanen Date: Mon, 27 Apr 2020 17:33:25 -0700 Subject: Add API support for network chain intent Adds API for managing Network Chain intents for composite applications. Issue-ID: MULTICLOUD-1029 Signed-off-by: Eric Multanen Change-Id: Ie3d4e8f1e3179397d86829d951e2bb877597b38d --- src/ncm/pkg/module/chaining.go | 209 +++++++++++++++++++++++++++++++++++++++++ src/ncm/pkg/module/module.go | 2 + 2 files changed, 211 insertions(+) create mode 100644 src/ncm/pkg/module/chaining.go (limited to 'src/ncm/pkg') diff --git a/src/ncm/pkg/module/chaining.go b/src/ncm/pkg/module/chaining.go new file mode 100644 index 00000000..45f061fa --- /dev/null +++ b/src/ncm/pkg/module/chaining.go @@ -0,0 +1,209 @@ +/* + * 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" +) + +// Chain defines the high level structure of a network chain document +type Chain struct { + Metadata Metadata `json:"metadata" yaml:"metadata"` + Spec NetworkChainingSpec `json:"spec" yaml:"spec"` +} + +// NetworkChainingSpec contains the specification of a network chain +type NetworkChainingSpec struct { + ChainType string `json:"type"` + RoutingSpec RouteSpec `json:"routingSpec"` +} + +// RouteSpec contains the routing specificaiton of a network chain +type RouteSpec struct { + LeftNetwork []RoutingNetwork `json:"leftNetwork"` + RightNetwork []RoutingNetwork `json:"rightNetwork"` + NetworkChain string `json:"networkChain"` + Namespace string `json:"namespace"` +} + +// RoutingNetwork contains the route networkroute network details for en element of a network chain +type RoutingNetwork struct { + NetworkName string `json:"networkName"` + GatewayIP string `json:"gatewayIp"` + Subnet string `json:"subnet"` +} + +// ChainKey is the key structure that is used in the database +type ChainKey struct { + Project string `json:"project"` + CompositeApp string `json:"compositeapp"` + CompositeAppVersion string `json:"compositeappversion"` + NetControlIntent string `json:"netcontrolintent"` + NetworkChain string `json:"networkchain"` +} + +// CrChain is the structure for the Network Chain Custom Resource +type CrChain struct { + APIVersion string `yaml:"apiVersion"` + Kind string `yaml:"kind"` + Chain Chain +} + +// RoutingChainType is currently only defined chaining type +const RoutingChainType = "routing" + +// ChainingAPIVersion is the kubernetes version of a network chain custom resource +const ChainingAPIVersion = "k8s.plugin.opnfv.org/v1" + +// ChainingKind is the Kind string for a network chain +const ChainingKind = "NetworkChaining" + +// ChainManager is an interface exposing the Chain functionality +type ChainManager interface { + CreateChain(ch Chain, pr, ca, caver, netctrlint string, exists bool) (Chain, error) + GetChain(name, pr, ca, caver, netctrlint string) (Chain, error) + GetChains(pr, ca, caver, netctrlint string) ([]Chain, error) + DeleteChain(name, pr, ca, caver, netctrlint string) error +} + +// ChainClient implements the Manager +// It will also be used to maintain some localized state +type ChainClient struct { + db ClientDbInfo +} + +// NewChainClient returns an instance of the ChainClient +// which implements the Manager +func NewChainClient() *ChainClient { + return &ChainClient{ + db: ClientDbInfo{ + storeName: "orchestrator", + tagMeta: "chainmetadata", + }, + } +} + +// CreateChain - create a new Chain +func (v *ChainClient) CreateChain(ch Chain, pr, ca, caver, netctrlint string, exists bool) (Chain, error) { + //Construct key and tag to select the entry + key := ChainKey{ + Project: pr, + CompositeApp: ca, + CompositeAppVersion: caver, + NetControlIntent: netctrlint, + NetworkChain: ch.Metadata.Name, + } + + //Check if the Network Control Intent exists + _, err := NewNetControlIntentClient().GetNetControlIntent(netctrlint, pr, ca, caver) + if err != nil { + return Chain{}, pkgerrors.Errorf("Network Control Intent %v does not exist", netctrlint) + } + + //Check if this Chain already exists + _, err = v.GetChain(ch.Metadata.Name, pr, ca, caver, netctrlint) + if err == nil && !exists { + return Chain{}, pkgerrors.New("Chain already exists") + } + + err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, ch) + if err != nil { + return Chain{}, pkgerrors.Wrap(err, "Creating DB Entry") + } + + return ch, nil +} + +// GetChain returns the Chain for corresponding name +func (v *ChainClient) GetChain(name, pr, ca, caver, netctrlint string) (Chain, error) { + //Construct key and tag to select the entry + key := ChainKey{ + Project: pr, + CompositeApp: ca, + CompositeAppVersion: caver, + NetControlIntent: netctrlint, + NetworkChain: name, + } + + value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) + if err != nil { + return Chain{}, pkgerrors.Wrap(err, "Get Chain") + } + + //value is a byte array + if value != nil { + ch := Chain{} + err = db.DBconn.Unmarshal(value[0], &ch) + if err != nil { + return Chain{}, pkgerrors.Wrap(err, "Unmarshalling Value") + } + return ch, nil + } + + return Chain{}, pkgerrors.New("Error getting Chain") +} + +// GetChains returns all of the Chains for for the given network control intent +func (v *ChainClient) GetChains(pr, ca, caver, netctrlint string) ([]Chain, error) { + //Construct key and tag to select the entry + key := ChainKey{ + Project: pr, + CompositeApp: ca, + CompositeAppVersion: caver, + NetControlIntent: netctrlint, + NetworkChain: "", + } + + var resp []Chain + values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) + if err != nil { + return []Chain{}, pkgerrors.Wrap(err, "Get Chains") + } + + for _, value := range values { + cp := Chain{} + err = db.DBconn.Unmarshal(value, &cp) + if err != nil { + return []Chain{}, pkgerrors.Wrap(err, "Unmarshalling Value") + } + resp = append(resp, cp) + } + + return resp, nil +} + +// DeleteChain deletes the Chain from the database +func (v *ChainClient) DeleteChain(name, pr, ca, caver, netctrlint string) error { + + //Construct key and tag to select the entry + key := ChainKey{ + Project: pr, + CompositeApp: ca, + CompositeAppVersion: caver, + NetControlIntent: netctrlint, + NetworkChain: name, + } + + err := db.DBconn.Remove(v.db.storeName, key) + if err != nil { + return pkgerrors.Wrap(err, "Delete Chain Entry;") + } + + return nil +} diff --git a/src/ncm/pkg/module/module.go b/src/ncm/pkg/module/module.go index 9655c1de..21adaf9d 100644 --- a/src/ncm/pkg/module/module.go +++ b/src/ncm/pkg/module/module.go @@ -24,6 +24,7 @@ type Client struct { NetControlIntent *NetControlIntentClient WorkloadIntent *WorkloadIntentClient WorkloadIfIntent *WorkloadIfIntentClient + Chain *ChainClient // Add Clients for API's here } @@ -36,6 +37,7 @@ func NewClient() *Client { c.NetControlIntent = NewNetControlIntentClient() c.WorkloadIntent = NewWorkloadIntentClient() c.WorkloadIfIntent = NewWorkloadIfIntentClient() + c.Chain = NewChainClient() // Add Client API handlers here return c } -- cgit 1.2.3-korg