diff options
author | Eric Multanen <eric.w.multanen@intel.com> | 2020-05-28 17:07:20 -0700 |
---|---|---|
committer | Eric Multanen <eric.w.multanen@intel.com> | 2020-06-02 14:00:07 -0700 |
commit | ad7782cbf83c11f152a6457f3808a4da99a1ae56 (patch) | |
tree | e88276d8f0d55bd58a903d1c31ab4e43e4011193 /src/ncm | |
parent | c257a136355a794f5bf778f670c041e8958c3608 (diff) |
Create OVN network action controller from ncm
Split out part of ncm microservice to act as the
Onv4k8s network action controller for the orchestrator.
No code changes really - just moving around to fit the
architectural plan.
Issue-ID: MULTICLOUD-1029
Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>
Change-Id: I17292ac72d041050269f05fc4a0c2a6ca741aeb5
Diffstat (limited to 'src/ncm')
-rw-r--r-- | src/ncm/api/api.go | 65 | ||||
-rw-r--r-- | src/ncm/api/chainhandler.go | 290 | ||||
-rw-r--r-- | src/ncm/api/chainhandler_test.go | 56 | ||||
-rw-r--r-- | src/ncm/api/netcontrolintenthandler.go | 230 | ||||
-rw-r--r-- | src/ncm/api/workloadifintenthandler.go | 251 | ||||
-rw-r--r-- | src/ncm/api/workloadintenthandler.go | 218 | ||||
-rw-r--r-- | src/ncm/cmd/main.go | 58 | ||||
-rw-r--r-- | src/ncm/go.mod | 2 | ||||
-rw-r--r-- | src/ncm/pkg/grpc/contextupdateserver/contextupdateserver.go | 45 | ||||
-rw-r--r-- | src/ncm/pkg/grpc/register.go | 58 | ||||
-rw-r--r-- | src/ncm/pkg/module/chaining.go | 209 | ||||
-rw-r--r-- | src/ncm/pkg/module/module.go | 8 | ||||
-rw-r--r-- | src/ncm/pkg/module/module_definitions.go | 3 | ||||
-rw-r--r-- | src/ncm/pkg/module/netcontrolintent.go | 295 | ||||
-rw-r--r-- | src/ncm/pkg/module/resources.go | 273 | ||||
-rw-r--r-- | src/ncm/pkg/module/workloadifintent.go | 188 | ||||
-rw-r--r-- | src/ncm/pkg/module/workloadintent.go | 181 |
17 files changed, 2 insertions, 2428 deletions
diff --git a/src/ncm/api/api.go b/src/ncm/api/api.go index 29ed46bd..2b9c1b17 100644 --- a/src/ncm/api/api.go +++ b/src/ncm/api/api.go @@ -51,34 +51,6 @@ func setClient(client, testClient interface{}) interface{} { return c } } - case *moduleLib.NetControlIntentClient: - if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.NetControlIntentManager)(nil)).Elem()) { - c, ok := testClient.(moduleLib.NetControlIntentManager) - if ok { - return c - } - } - case *moduleLib.WorkloadIntentClient: - if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.WorkloadIntentManager)(nil)).Elem()) { - c, ok := testClient.(moduleLib.WorkloadIntentManager) - if ok { - return c - } - } - case *moduleLib.WorkloadIfIntentClient: - if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.WorkloadIfIntentManager)(nil)).Elem()) { - c, ok := testClient.(moduleLib.WorkloadIfIntentManager) - if ok { - return c - } - } - case *moduleLib.ChainClient: - if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.ChainManager)(nil)).Elem()) { - c, ok := testClient.(moduleLib.ChainManager) - if ok { - return c - } - } default: fmt.Printf("unknown type %T\n", cl) } @@ -134,42 +106,5 @@ func NewRouter(testClient interface{}) *mux.Router { 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") - netcontrolintentHandler := netcontrolintentHandler{ - client: setClient(moduleClient.NetControlIntent, testClient).(moduleLib.NetControlIntentManager), - } - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent", netcontrolintentHandler.createHandler).Methods("POST") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent", netcontrolintentHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}", netcontrolintentHandler.putHandler).Methods("PUT") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}", netcontrolintentHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}", netcontrolintentHandler.deleteHandler).Methods("DELETE") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}/apply", netcontrolintentHandler.applyHandler).Methods("POST") - - workloadintentHandler := workloadintentHandler{ - client: setClient(moduleClient.WorkloadIntent, testClient).(moduleLib.WorkloadIntentManager), - } - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents", workloadintentHandler.createHandler).Methods("POST") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents", workloadintentHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.putHandler).Methods("PUT") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.deleteHandler).Methods("DELETE") - - workloadifintentHandler := workloadifintentHandler{ - client: setClient(moduleClient.WorkloadIfIntent, testClient).(moduleLib.WorkloadIfIntentManager), - } - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces", workloadifintentHandler.createHandler).Methods("POST") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces", workloadifintentHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.putHandler).Methods("PUT") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.deleteHandler).Methods("DELETE") - - chainHandler := chainHandler{ - client: setClient(moduleClient.Chain, testClient).(moduleLib.ChainManager), - } - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains", chainHandler.createHandler).Methods("POST") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains", chainHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.putHandler).Methods("PUT") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.getHandler).Methods("GET") - router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.deleteHandler).Methods("DELETE") - return router } diff --git a/src/ncm/api/chainhandler.go b/src/ncm/api/chainhandler.go deleted file mode 100644 index 7169014b..00000000 --- a/src/ncm/api/chainhandler.go +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 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 chainHandler struct { - // Interface that implements workload intent operations - // We will set this variable with a mock interface for testing - client moduleLib.ChainManager -} - -func validateRoutingNetwork(r moduleLib.RoutingNetwork) error { - errs := validation.IsValidName(r.NetworkName) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid routing network name: %v", errs) - } - - err := validation.IsIpv4Cidr(r.Subnet) - if err != nil { - return pkgerrors.Wrap(err, "Invalid routing network subnet") - } - - err = validation.IsIpv4(r.GatewayIP) - if err != nil { - return pkgerrors.Wrap(err, "Invalid routing network gateway IP") - } - - return nil -} - -// validateNetworkChain checks that the network chain string input follows the -// generic format: "app=app1,net1,app=app2,net2, ..... ,netN-1,app=appN" -// assume "app=app1" can conform to validation.IsValidLabel() with an "=" -func validateNetworkChain(chain string) error { - elems := strings.Split(chain, ",") - - // chain needs at least two apps and a network - if len(elems) < 3 { - return pkgerrors.Errorf("Network chain is too short") - } - - // chain needs to have an odd number of elements - if len(elems)%2 == 0 { - return pkgerrors.Errorf("Invalid network chain - even number of elements") - } - - for i, s := range elems { - // allows whitespace in comma separated elements - t := strings.TrimSpace(s) - // if even element, verify a=b format - if i%2 == 0 { - if strings.Index(t, "=") < 1 { - return pkgerrors.Errorf("Invalid deployment label element of network chain") - } - errs := validation.IsValidLabel(t) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid deployment label element: %v", errs) - } - } else { - errs := validation.IsValidName(t) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid network element of network chain: %v", errs) - } - } - } - return nil -} - -// Check for valid format of input parameters -func validateChainInputs(ch moduleLib.Chain) error { - // validate metadata - err := moduleLib.IsValidMetadata(ch.Metadata) - if err != nil { - return pkgerrors.Wrap(err, "Invalid network chain metadata") - } - - if strings.ToLower(ch.Spec.ChainType) != moduleLib.RoutingChainType { - return pkgerrors.Wrap(err, "Invalid network chain type") - } - - for _, r := range ch.Spec.RoutingSpec.LeftNetwork { - err = validateRoutingNetwork(r) - if err != nil { - return err - } - } - - for _, r := range ch.Spec.RoutingSpec.RightNetwork { - err = validateRoutingNetwork(r) - if err != nil { - return err - } - } - - err = validateNetworkChain(ch.Spec.RoutingSpec.NetworkChain) - if err != nil { - return err - } - - errs := validation.IsValidName(ch.Spec.RoutingSpec.Namespace) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid network chain route spec namespace: %v", errs) - } - - return nil -} - -// Create handles creation of the Chain entry in the database -func (h chainHandler) createHandler(w http.ResponseWriter, r *http.Request) { - var ch moduleLib.Chain - vars := mux.Vars(r) - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - - err := json.NewDecoder(r.Body).Decode(&ch) - - 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 ch.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) - return - } - - err = validateChainInputs(ch) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateChain(ch, project, compositeApp, compositeAppVersion, netControlIntent, 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 Chain entry in the database -func (h chainHandler) putHandler(w http.ResponseWriter, r *http.Request) { - var ch moduleLib.Chain - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - - err := json.NewDecoder(r.Body).Decode(&ch) - - 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 ch.Metadata.Name == "" { - http.Error(w, "Missing name in PUT request", http.StatusBadRequest) - return - } - - // Name in URL should match name in body - if ch.Metadata.Name != name { - fmt.Printf("bodyname = %v, name= %v\n", ch.Metadata.Name, name) - http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest) - return - } - - err = validateChainInputs(ch) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateChain(ch, project, compositeApp, compositeAppVersion, netControlIntent, 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 Chain Name -// Returns a Chain -func (h chainHandler) getHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - var ret interface{} - var err error - - if len(name) == 0 { - ret, err = h.client.GetChains(project, compositeApp, compositeAppVersion, netControlIntent) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } else { - ret, err = h.client.GetChain(name, project, compositeApp, compositeAppVersion, netControlIntent) - 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 Chain -func (h chainHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - - err := h.client.DeleteChain(name, project, compositeApp, compositeAppVersion, netControlIntent) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} diff --git a/src/ncm/api/chainhandler_test.go b/src/ncm/api/chainhandler_test.go deleted file mode 100644 index f13a90c4..00000000 --- a/src/ncm/api/chainhandler_test.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 ( - "testing" -) - -func TestIsValidNetworkChain(t *testing.T) { - t.Run("Valid Chains", func(t *testing.T) { - validchains := []string{ - "app=abc,net1,app=xyz", - "app=abc, net1, app=xyz", - " app=abc , net1 , app=xyz ", - "app.kubernets.io/name=abc,net1,app.kubernets.io/name=xyz", - "app.kubernets.io/name=abc,net1,app.kubernets.io/name=xyz, net2, anotherlabel=wex", - } - for _, chain := range validchains { - err := validateNetworkChain(chain) - if err != nil { - t.Errorf("Valid network chain failed to pass: %v %v", chain, err) - } - } - }) - - t.Run("Invalid Chains", func(t *testing.T) { - invalidchains := []string{ - "", - "app=abc,net1,app= xyz", - "app=abc,net1,xyz", - "app=abc,net1", - "app.kubernets.io/name=abc,net1,=xyz", - "abcdefg", - } - for _, chain := range invalidchains { - err := validateNetworkChain(chain) - if err == nil { - t.Errorf("Invalid network chain passed: %v", chain) - } - } - }) -} diff --git a/src/ncm/api/netcontrolintenthandler.go b/src/ncm/api/netcontrolintenthandler.go deleted file mode 100644 index 48ef1de2..00000000 --- a/src/ncm/api/netcontrolintenthandler.go +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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" - pkgerrors "github.com/pkg/errors" - - "github.com/gorilla/mux" -) - -// Used to store backend implementations objects -// Also simplifies mocking for unit testing purposes -type netcontrolintentHandler struct { - // Interface that implements Cluster operations - // We will set this variable with a mock interface for testing - client moduleLib.NetControlIntentManager -} - -// Check for valid format of input parameters -func validateNetControlIntentInputs(nci moduleLib.NetControlIntent) error { - // validate metadata - err := moduleLib.IsValidMetadata(nci.Metadata) - if err != nil { - return pkgerrors.Wrap(err, "Invalid network controller intent metadata") - } - return nil -} - -// Create handles creation of the NetControlIntent entry in the database -func (h netcontrolintentHandler) createHandler(w http.ResponseWriter, r *http.Request) { - var nci moduleLib.NetControlIntent - vars := mux.Vars(r) - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - - err := json.NewDecoder(r.Body).Decode(&nci) - - 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 nci.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) - return - } - - err = validateNetControlIntentInputs(nci) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateNetControlIntent(nci, project, compositeApp, compositeAppVersion, 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 NetControlIntent entry in the database -func (h netcontrolintentHandler) putHandler(w http.ResponseWriter, r *http.Request) { - var nci moduleLib.NetControlIntent - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - - err := json.NewDecoder(r.Body).Decode(&nci) - - 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 nci.Metadata.Name == "" { - http.Error(w, "Missing name in PUT request", http.StatusBadRequest) - return - } - - // Name in URL should match name in body - if nci.Metadata.Name != name { - fmt.Printf("bodyname = %v, name= %v\n", nci.Metadata.Name, name) - http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest) - return - } - - err = validateNetControlIntentInputs(nci) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateNetControlIntent(nci, project, compositeApp, compositeAppVersion, 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 NetControlIntent Name -// Returns a NetControlIntent -func (h netcontrolintentHandler) getHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - var ret interface{} - var err error - - if len(name) == 0 { - ret, err = h.client.GetNetControlIntents(project, compositeApp, compositeAppVersion) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } else { - ret, err = h.client.GetNetControlIntent(name, project, compositeApp, compositeAppVersion) - 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 NetControlIntent Name -func (h netcontrolintentHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - - err := h.client.DeleteNetControlIntent(name, project, compositeApp, compositeAppVersion) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} - -// Apply handles POST operations to Apply a particular NetControlIntent to the App Context -func (h netcontrolintentHandler) applyHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - - var aci struct { - AppContextId string `json:"appContextId"` - } - - err := json.NewDecoder(r.Body).Decode(&aci) - - switch { - case err == io.EOF: - http.Error(w, "Empty body", http.StatusBadRequest) - return - case err != nil: - http.Error(w, err.Error(), http.StatusUnprocessableEntity) - return - } - - err = h.client.ApplyNetControlIntent(name, project, compositeApp, compositeAppVersion, aci.AppContextId) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} diff --git a/src/ncm/api/workloadifintenthandler.go b/src/ncm/api/workloadifintenthandler.go deleted file mode 100644 index 31472a5d..00000000 --- a/src/ncm/api/workloadifintenthandler.go +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 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 workloadifintentHandler struct { - // Interface that implements workload intent operations - // We will set this variable with a mock interface for testing - client moduleLib.WorkloadIfIntentManager -} - -// Check for valid format of input parameters -func validateWorkloadIfIntentInputs(wif moduleLib.WorkloadIfIntent) error { - // validate metadata - err := moduleLib.IsValidMetadata(wif.Metadata) - if err != nil { - return pkgerrors.Wrap(err, "Invalid network controller intent metadata") - } - - errs := validation.IsValidName(wif.Spec.IfName) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid interface name = [%v], errors: %v", wif.Spec.IfName, errs) - } - - errs = validation.IsValidName(wif.Spec.NetworkName) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid network name = [%v], errors: %v", wif.Spec.NetworkName, errs) - } - - // optional - only validate if supplied - if len(wif.Spec.DefaultGateway) > 0 { - errs = validation.IsValidName(wif.Spec.DefaultGateway) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid default interface = [%v], errors: %v", wif.Spec.DefaultGateway, errs) - } - } - - // optional - only validate if supplied - if len(wif.Spec.IpAddr) > 0 { - err = validation.IsIp(wif.Spec.IpAddr) - if err != nil { - return pkgerrors.Errorf("Invalid IP address = [%v], errors: %v", wif.Spec.IpAddr, err) - } - } - - // optional - only validate if supplied - if len(wif.Spec.MacAddr) > 0 { - err = validation.IsMac(wif.Spec.MacAddr) - if err != nil { - return pkgerrors.Errorf("Invalid MAC address = [%v], errors: %v", wif.Spec.MacAddr, err) - } - } - return nil -} - -// Create handles creation of the Network entry in the database -func (h workloadifintentHandler) createHandler(w http.ResponseWriter, r *http.Request) { - var wif moduleLib.WorkloadIfIntent - vars := mux.Vars(r) - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - workloadIntent := vars["workload-intent"] - - err := json.NewDecoder(r.Body).Decode(&wif) - - 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 wif.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) - return - } - - // set default value - if len(wif.Spec.DefaultGateway) == 0 { - wif.Spec.DefaultGateway = "false" // set default value - } - - err = validateWorkloadIfIntentInputs(wif) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateWorkloadIfIntent(wif, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent, 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 workloadifintentHandler) putHandler(w http.ResponseWriter, r *http.Request) { - var wif moduleLib.WorkloadIfIntent - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - workloadIntent := vars["workload-intent"] - - err := json.NewDecoder(r.Body).Decode(&wif) - - 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 wif.Metadata.Name == "" { - http.Error(w, "Missing name in PUT request", http.StatusBadRequest) - return - } - - // Name in URL should match name in body - if wif.Metadata.Name != name { - fmt.Printf("bodyname = %v, name= %v\n", wif.Metadata.Name, name) - http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest) - return - } - - // set default value - if len(wif.Spec.DefaultGateway) == 0 { - wif.Spec.DefaultGateway = "false" // set default value - } - - err = validateWorkloadIfIntentInputs(wif) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateWorkloadIfIntent(wif, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent, 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 workloadifintentHandler) getHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - workloadIntent := vars["workload-intent"] - var ret interface{} - var err error - - if len(name) == 0 { - ret, err = h.client.GetWorkloadIfIntents(project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } else { - ret, err = h.client.GetWorkloadIfIntent(name, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent) - 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 workloadifintentHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - workloadIntent := vars["workload-intent"] - - err := h.client.DeleteWorkloadIfIntent(name, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} diff --git a/src/ncm/api/workloadintenthandler.go b/src/ncm/api/workloadintenthandler.go deleted file mode 100644 index f1d0093d..00000000 --- a/src/ncm/api/workloadintenthandler.go +++ /dev/null @@ -1,218 +0,0 @@ -/* - * 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 workloadintentHandler struct { - // Interface that implements workload intent operations - // We will set this variable with a mock interface for testing - client moduleLib.WorkloadIntentManager -} - -// Check for valid format of input parameters -func validateWorkloadIntentInputs(wi moduleLib.WorkloadIntent) error { - // validate metadata - err := moduleLib.IsValidMetadata(wi.Metadata) - if err != nil { - return pkgerrors.Wrap(err, "Invalid network controller intent metadata") - } - - errs := validation.IsValidName(wi.Spec.AppName) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid application name = [%v], errors: %v", wi.Spec.AppName, errs) - } - - errs = validation.IsValidName(wi.Spec.WorkloadResource) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid workload resource = [%v], errors: %v", wi.Spec.WorkloadResource, errs) - } - - errs = validation.IsValidName(wi.Spec.Type) - if len(errs) > 0 { - return pkgerrors.Errorf("Invalid workload type = [%v], errors: %v", wi.Spec.Type, errs) - } - return nil -} - -// Create handles creation of the Network entry in the database -func (h workloadintentHandler) createHandler(w http.ResponseWriter, r *http.Request) { - var wi moduleLib.WorkloadIntent - vars := mux.Vars(r) - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - - err := json.NewDecoder(r.Body).Decode(&wi) - - 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 wi.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) - return - } - - err = validateWorkloadIntentInputs(wi) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateWorkloadIntent(wi, project, compositeApp, compositeAppVersion, netControlIntent, 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 workloadintentHandler) putHandler(w http.ResponseWriter, r *http.Request) { - var wi moduleLib.WorkloadIntent - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - - err := json.NewDecoder(r.Body).Decode(&wi) - - 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 wi.Metadata.Name == "" { - http.Error(w, "Missing name in PUT request", http.StatusBadRequest) - return - } - - // Name in URL should match name in body - if wi.Metadata.Name != name { - fmt.Printf("bodyname = %v, name= %v\n", wi.Metadata.Name, name) - http.Error(w, "Mismatched name in PUT request", http.StatusBadRequest) - return - } - - err = validateWorkloadIntentInputs(wi) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - ret, err := h.client.CreateWorkloadIntent(wi, project, compositeApp, compositeAppVersion, netControlIntent, 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 workloadintentHandler) getHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - var ret interface{} - var err error - - if len(name) == 0 { - ret, err = h.client.GetWorkloadIntents(project, compositeApp, compositeAppVersion, netControlIntent) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } else { - ret, err = h.client.GetWorkloadIntent(name, project, compositeApp, compositeAppVersion, netControlIntent) - 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 workloadintentHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - project := vars["project"] - compositeApp := vars["composite-app-name"] - compositeAppVersion := vars["version"] - netControlIntent := vars["net-control-intent"] - - err := h.client.DeleteWorkloadIntent(name, project, compositeApp, compositeAppVersion, netControlIntent) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} diff --git a/src/ncm/cmd/main.go b/src/ncm/cmd/main.go index 49af81ee..640fa3ea 100644 --- a/src/ncm/cmd/main.go +++ b/src/ncm/cmd/main.go @@ -15,72 +15,21 @@ package main import ( "context" - "fmt" "log" "math/rand" - "net" "net/http" "os" "os/signal" - "strings" "time" "github.com/gorilla/handlers" "github.com/onap/multicloud-k8s/src/ncm/api" - register "github.com/onap/multicloud-k8s/src/ncm/pkg/grpc" - "github.com/onap/multicloud-k8s/src/ncm/pkg/grpc/contextupdateserver" - updatepb "github.com/onap/multicloud-k8s/src/orchestrator/pkg/grpc/contextupdate" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/auth" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/config" contextDb "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/contextdb" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/testdata" ) -func startGrpcServer() error { - var tls bool - - if strings.Contains(config.GetConfiguration().GrpcEnableTLS, "enable") { - tls = true - } else { - tls = false - } - certFile := config.GetConfiguration().GrpcServerCert - keyFile := config.GetConfiguration().GrpcServerKey - - host, port := register.GetServerHostPort() - - lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port)) - if err != nil { - log.Fatalf("Could not listen to port: %v", err) - } - var opts []grpc.ServerOption - if tls { - if certFile == "" { - certFile = testdata.Path("server.pem") - } - if keyFile == "" { - keyFile = testdata.Path("server.key") - } - creds, err := credentials.NewServerTLSFromFile(certFile, keyFile) - if err != nil { - log.Fatalf("Could not generate credentials %v", err) - } - opts = []grpc.ServerOption{grpc.Creds(creds)} - } - grpcServer := grpc.NewServer(opts...) - updatepb.RegisterContextupdateServer(grpcServer, contextupdateserver.NewContextupdateServer()) - - log.Println("Starting Network Configuration Manager gRPC Server") - err = grpcServer.Serve(lis) - if err != nil { - log.Fatalf("ncm grpc server is not serving %v", err) - } - return err -} - func main() { rand.Seed(time.Now().UnixNano()) @@ -106,13 +55,6 @@ func main() { Addr: ":" + config.GetConfiguration().ServicePort, } - go func() { - err := startGrpcServer() - if err != nil { - log.Fatalf("GRPC server failed to start") - } - }() - connectionsClose := make(chan struct{}) go func() { c := make(chan os.Signal, 1) diff --git a/src/ncm/go.mod b/src/ncm/go.mod index d9fde682..41f2b5ff 100644 --- a/src/ncm/go.mod +++ b/src/ncm/go.mod @@ -8,6 +8,7 @@ require ( github.com/gorilla/mux v1.6.2 github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200127152046-0ee521d56061 github.com/onap/multicloud-k8s/src/orchestrator v0.0.0-20200527175204-ef27eb4d63f1 + github.com/onap/multicloud-k8s/src/rsync v0.0.0-20200529003854-0a7bf256bde5 github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pkg/errors v0.8.1 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect @@ -23,6 +24,7 @@ require ( replace ( github.com/onap/multicloud-k8s/src/orchestrator => ../orchestrator + github.com/onap/multicloud-k8s/src/rsync => ../rsync k8s.io/api => k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8 k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d diff --git a/src/ncm/pkg/grpc/contextupdateserver/contextupdateserver.go b/src/ncm/pkg/grpc/contextupdateserver/contextupdateserver.go deleted file mode 100644 index fc548ccc..00000000 --- a/src/ncm/pkg/grpc/contextupdateserver/contextupdateserver.go +++ /dev/null @@ -1,45 +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 contextupdateserver - -import ( - "context" - "encoding/json" - "log" - - contextpb "github.com/onap/multicloud-k8s/src/orchestrator/pkg/grpc/contextupdate" - //"google.golang.org/grpc/codes" - //"google.golang.org/grpc/status" -) - -type contextupdateServer struct { - contextpb.UnimplementedContextupdateServer -} - -func (cs *contextupdateServer) UpdateAppContext(ctx context.Context, req *contextpb.ContextUpdateRequest) (*contextpb.ContextUpdateResponse, error) { - contextUpdateReq, _ := json.Marshal(req) - log.Println("GRPC Server received contextupdateRequest: ", string(contextUpdateReq)) - - // Insert call to Server Functionality here - // - // - - return &contextpb.ContextUpdateResponse{AppContextUpdated: true}, nil -} - -// NewContextUpdateServer exported -func NewContextupdateServer() *contextupdateServer { - s := &contextupdateServer{} - return s -} diff --git a/src/ncm/pkg/grpc/register.go b/src/ncm/pkg/grpc/register.go deleted file mode 100644 index 07d8f5c0..00000000 --- a/src/ncm/pkg/grpc/register.go +++ /dev/null @@ -1,58 +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 ( - "os" - "strconv" - "strings" - - log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils" -) - -const default_host = "localhost" -const default_port = 9030 -const default_ncm_name = "ncm" -const ENV_NCM_NAME = "NCM_NAME" - -func GetServerHostPort() (string, int) { - - // expect name of this ncm program to be in env variable "NCM_NAME" - e.g. NCM_NAME="ncm" - serviceName := os.Getenv(ENV_NCM_NAME) - if serviceName == "" { - serviceName = default_ncm_name - log.Info("Using default name for NCM service name", log.Fields{ - "Name": serviceName, - }) - } - - // expect service name to be in env variable - e.g. NCM_SERVICE_HOST - host := os.Getenv(strings.ToUpper(serviceName) + "_SERVICE_HOST") - if host == "" { - host = default_host - log.Info("Using default host for ncm gRPC controller", log.Fields{ - "Host": host, - }) - } - - // expect service port to be in env variable - e.g. NCM_SERVICE_PORT - port, err := strconv.Atoi(os.Getenv(strings.ToUpper(serviceName) + "_SERVICE_PORT")) - if err != nil || port < 0 { - port = default_port - log.Info("Using default port for ncm gRPC controller", log.Fields{ - "Port": port, - }) - } - return host, port -} diff --git a/src/ncm/pkg/module/chaining.go b/src/ncm/pkg/module/chaining.go deleted file mode 100644 index 45f061fa..00000000 --- a/src/ncm/pkg/module/chaining.go +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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 21adaf9d..e3ebcccc 100644 --- a/src/ncm/pkg/module/module.go +++ b/src/ncm/pkg/module/module.go @@ -21,10 +21,6 @@ type Client struct { Cluster *ClusterClient Network *NetworkClient ProviderNet *ProviderNetClient - NetControlIntent *NetControlIntentClient - WorkloadIntent *WorkloadIntentClient - WorkloadIfIntent *WorkloadIfIntentClient - Chain *ChainClient // Add Clients for API's here } @@ -34,10 +30,6 @@ func NewClient() *Client { c.Cluster = NewClusterClient() c.Network = NewNetworkClient() c.ProviderNet = NewProviderNetClient() - c.NetControlIntent = NewNetControlIntentClient() - c.WorkloadIntent = NewWorkloadIntentClient() - c.WorkloadIfIntent = NewWorkloadIfIntentClient() - c.Chain = NewChainClient() // 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 index 8d4b3ad7..efcbca95 100644 --- a/src/ncm/pkg/module/module_definitions.go +++ b/src/ncm/pkg/module/module_definitions.go @@ -31,9 +31,6 @@ const CNI_TYPE_OVN4NFV string = "ovn4nfv" var CNI_TYPES = [...]string{CNI_TYPE_OVN4NFV} -const YAML_START = "---\n" -const YAML_END = "...\n" - // It implements the interface for managing the ClusterProviders const MAX_DESCRIPTION_LEN int = 1024 const MAX_USERDATA_LEN int = 4096 diff --git a/src/ncm/pkg/module/netcontrolintent.go b/src/ncm/pkg/module/netcontrolintent.go deleted file mode 100644 index c005a935..00000000 --- a/src/ncm/pkg/module/netcontrolintent.go +++ /dev/null @@ -1,295 +0,0 @@ -/* - * 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 ( - "encoding/json" - "strings" - - jyaml "github.com/ghodss/yaml" - - nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - "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" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - - pkgerrors "github.com/pkg/errors" -) - -// NetControlIntent contains the parameters needed for dynamic networks -type NetControlIntent struct { - Metadata Metadata `json:"metadata"` -} - -// NetControlIntentKey is the key structure that is used in the database -type NetControlIntentKey struct { - NetControlIntent string `json:"netcontrolintent"` - Project string `json:"project"` - CompositeApp string `json:"compositeapp"` - CompositeAppVersion string `json:"compositeappversion"` -} - -// Manager is an interface exposing the NetControlIntent functionality -type NetControlIntentManager interface { - CreateNetControlIntent(nci NetControlIntent, project, compositeapp, compositeappversion string, exists bool) (NetControlIntent, error) - GetNetControlIntent(name, project, compositeapp, compositeappversion string) (NetControlIntent, error) - GetNetControlIntents(project, compositeapp, compositeappversion string) ([]NetControlIntent, error) - DeleteNetControlIntent(name, project, compositeapp, compositeappversion string) error - ApplyNetControlIntent(name, project, compositeapp, compositeappversion, appContextId string) error -} - -// NetControlIntentClient implements the Manager -// It will also be used to maintain some localized state -type NetControlIntentClient struct { - db ClientDbInfo -} - -// NewNetControlIntentClient returns an instance of the NetControlIntentClient -// which implements the Manager -func NewNetControlIntentClient() *NetControlIntentClient { - return &NetControlIntentClient{ - db: ClientDbInfo{ - storeName: "orchestrator", - tagMeta: "netcontrolintentmetadata", - }, - } -} - -// CreateNetControlIntent - create a new NetControlIntent -func (v *NetControlIntentClient) CreateNetControlIntent(nci NetControlIntent, project, compositeapp, compositeappversion string, exists bool) (NetControlIntent, error) { - - //Construct key and tag to select the entry - key := NetControlIntentKey{ - NetControlIntent: nci.Metadata.Name, - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - } - - //Check if this NetControlIntent already exists - _, err := v.GetNetControlIntent(nci.Metadata.Name, project, compositeapp, compositeappversion) - if err == nil && !exists { - return NetControlIntent{}, pkgerrors.New("NetControlIntent already exists") - } - - err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, nci) - if err != nil { - return NetControlIntent{}, pkgerrors.Wrap(err, "Creating DB Entry") - } - - return nci, nil -} - -// GetNetControlIntent returns the NetControlIntent for corresponding name -func (v *NetControlIntentClient) GetNetControlIntent(name, project, compositeapp, compositeappversion string) (NetControlIntent, error) { - - //Construct key and tag to select the entry - key := NetControlIntentKey{ - NetControlIntent: name, - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - } - - value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) - if err != nil { - return NetControlIntent{}, pkgerrors.Wrap(err, "Get NetControlIntent") - } - - //value is a byte array - if value != nil { - nci := NetControlIntent{} - err = db.DBconn.Unmarshal(value[0], &nci) - if err != nil { - return NetControlIntent{}, pkgerrors.Wrap(err, "Unmarshalling Value") - } - return nci, nil - } - - return NetControlIntent{}, pkgerrors.New("Error getting NetControlIntent") -} - -// GetNetControlIntentList returns all of the NetControlIntent for corresponding name -func (v *NetControlIntentClient) GetNetControlIntents(project, compositeapp, compositeappversion string) ([]NetControlIntent, error) { - - //Construct key and tag to select the entry - key := NetControlIntentKey{ - NetControlIntent: "", - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - } - - var resp []NetControlIntent - values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) - if err != nil { - return []NetControlIntent{}, pkgerrors.Wrap(err, "Get NetControlIntents") - } - - for _, value := range values { - nci := NetControlIntent{} - err = db.DBconn.Unmarshal(value, &nci) - if err != nil { - return []NetControlIntent{}, pkgerrors.Wrap(err, "Unmarshalling Value") - } - resp = append(resp, nci) - } - - return resp, nil -} - -// Delete the NetControlIntent from database -func (v *NetControlIntentClient) DeleteNetControlIntent(name, project, compositeapp, compositeappversion string) error { - - //Construct key and tag to select the entry - key := NetControlIntentKey{ - NetControlIntent: name, - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - } - - err := db.DBconn.Remove(v.db.storeName, key) - if err != nil { - return pkgerrors.Wrap(err, "Delete NetControlIntent Entry;") - } - - return nil -} - -// (Test Routine) - Apply network-control-intent -func (v *NetControlIntentClient) ApplyNetControlIntent(name, project, compositeapp, compositeappversion, appContextId string) error { - // TODO: Handle all Network Chain Intents for the Network Control Intent - - // Handle all Workload Intents for the Network Control Intent - wis, err := NewWorkloadIntentClient().GetWorkloadIntents(project, compositeapp, compositeappversion, name) - if err != nil { - return pkgerrors.Wrapf(err, "Error getting Workload Intents for Network Control Intent %v for %v/%v%v not found", name, project, compositeapp, compositeappversion) - } - - // Setup the AppContext - var context appcontext.AppContext - _, err = context.LoadAppContext(appContextId) - if err != nil { - return pkgerrors.Wrapf(err, "Error getting AppContext with Id: %v for %v/%v%v", - appContextId, project, compositeapp, compositeappversion) - } - - // Handle all intents (currently just Interface intents) for each Workload Intent - for _, wi := range wis { - // The app/resource identified in the workload intent needs to be updated with two annotations. - // 1 - The "k8s.v1.cni.cncf.io/networks" annotation will have {"name": "ovn-networkobj", "namespace": "default"} added - // to it (preserving any existing values for this annotation. - // 2 - The "k8s.plugin.opnfv.org/nfn-network" annotation will add any network interfaces that are provided by the - // workload/interfaces intents. - - // Prepare the list of interfaces from the workload intent - wifs, err := NewWorkloadIfIntentClient().GetWorkloadIfIntents(project, - compositeapp, - compositeappversion, - name, - wi.Metadata.Name) - if err != nil { - return pkgerrors.Wrapf(err, - "Error getting Workload Interface Intents for Workload Intent %v under Network Control Intent %v for %v/%v%v not found", - wi.Metadata.Name, name, project, compositeapp, compositeappversion) - } - if len(wifs) == 0 { - log.Warn("No interface intents provided for workload intent", log.Fields{ - "project": project, - "composite app": compositeapp, - "composite app version": compositeappversion, - "network control intent": name, - "workload intent": wi.Metadata.Name, - }) - continue - } - - // Get all clusters for the current App from the AppContext - clusters, err := context.GetClusterNames(wi.Spec.AppName) - for _, c := range clusters { - rh, err := context.GetResourceHandle(wi.Spec.AppName, c, - strings.Join([]string{wi.Spec.WorkloadResource, wi.Spec.Type}, "+")) - if err != nil { - log.Warn("App Context resource handle not found", log.Fields{ - "project": project, - "composite app": compositeapp, - "composite app version": compositeappversion, - "network control intent": name, - "workload name": wi.Metadata.Name, - "app": wi.Spec.AppName, - "resource": wi.Spec.WorkloadResource, - "resource type": wi.Spec.Type, - }) - continue - } - r, err := context.GetValue(rh) - if err != nil { - log.Error("Error retrieving resource from App Context", log.Fields{ - "error": err, - "resource handle": rh, - }) - } - - // Unmarshal resource to K8S object - robj, err := runtime.Decode(scheme.Codecs.UniversalDeserializer(), []byte(r.(string))) - - // Add network annotation to object - netAnnot := nettypes.NetworkSelectionElement{ - Name: "ovn-networkobj", - Namespace: "default", - } - AddNetworkAnnotation(robj, netAnnot) - - // Add nfn interface annotations to object - var newNfnIfs []WorkloadIfIntentSpec - for _, i := range wifs { - newNfnIfs = append(newNfnIfs, i.Spec) - } - AddNfnAnnotation(robj, newNfnIfs) - - // Marshal object back to yaml format (via json - seems to eliminate most clutter) - j, err := json.Marshal(robj) - if err != nil { - log.Error("Error marshalling resource to JSON", log.Fields{ - "error": err, - }) - continue - } - y, err := jyaml.JSONToYAML(j) - if err != nil { - log.Error("Error marshalling resource to YAML", log.Fields{ - "error": err, - }) - continue - } - - // Update resource in AppContext - err = context.UpdateResourceValue(rh, string(y)) - if err != nil { - log.Error("Network updating app context resource handle", log.Fields{ - "error": err, - "resource handle": rh, - }) - } - } - } - - return nil -} diff --git a/src/ncm/pkg/module/resources.go b/src/ncm/pkg/module/resources.go deleted file mode 100644 index 24c9833e..00000000 --- a/src/ncm/pkg/module/resources.go +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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 ( - "encoding/json" - "fmt" - - nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - netutils "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils" - log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils" - v1 "k8s.io/api/apps/v1" - batch "k8s.io/api/batch/v1" - batchv1beta1 "k8s.io/api/batch/v1beta1" - v1core "k8s.io/api/core/v1" - _ "k8s.io/kubernetes/pkg/apis/apps/install" - _ "k8s.io/kubernetes/pkg/apis/batch/install" - _ "k8s.io/kubernetes/pkg/apis/core/install" - _ "k8s.io/kubernetes/pkg/apis/extensions/install" - - pkgerrors "github.com/pkg/errors" -) - -type NfnAnnotation struct { - CniType string - Interface []WorkloadIfIntentSpec -} - -const NfnAnnotationKey = "k8s.plugin.opnfv.org/nfn-network" - -// ParsePodTemplateNetworkAnnotation parses Pod annotation in PodTemplate -func ParsePodTemplateNetworkAnnotation(pt *v1core.PodTemplateSpec) ([]*nettypes.NetworkSelectionElement, error) { - netAnnot := pt.Annotations[nettypes.NetworkAttachmentAnnot] - defaultNamespace := pt.Namespace - - if len(netAnnot) == 0 { - return nil, pkgerrors.Errorf("No kubernetes network annotation found") - } - - networks, err := netutils.ParseNetworkAnnotation(netAnnot, defaultNamespace) - if err != nil { - return nil, err - } - return networks, nil -} - -// GetPodTemplateNetworkAnnotation gets Pod Nfn annotation in PodTemplate -func GetPodTemplateNfnAnnotation(pt *v1core.PodTemplateSpec) NfnAnnotation { - var nfn NfnAnnotation - - nfnAnnot := pt.Annotations[NfnAnnotationKey] - if len(nfnAnnot) == 0 { - return nfn - } - - err := json.Unmarshal([]byte(nfnAnnot), &nfn) - if err != nil { - log.Warn("Error unmarshalling nfn annotation", log.Fields{ - "annotation": nfnAnnot, - }) - } - return nfn -} - -// GetPodNetworkAnnotation gets Pod Nfn annotation in PodTemplate -func GetPodNfnAnnotation(p *v1core.Pod) NfnAnnotation { - var nfn NfnAnnotation - - nfnAnnot := p.Annotations[NfnAnnotationKey] - if len(nfnAnnot) == 0 { - return nfn - } - - err := json.Unmarshal([]byte(nfnAnnot), &nfn) - if err != nil { - log.Warn("Error unmarshalling nfn annotation", log.Fields{ - "annotation": nfnAnnot, - }) - } - return nfn -} - -func addNetworkAnnotation(a nettypes.NetworkSelectionElement, as []*nettypes.NetworkSelectionElement) []*nettypes.NetworkSelectionElement { - var netElements []*nettypes.NetworkSelectionElement - - found := false - for _, e := range as { - if e.Name == a.Name { - found = true - } - netElements = append(netElements, e) - } - if !found { - netElements = append(netElements, &a) - } - - return netElements -} - -// Add the interfaces in the 'new' parameter to the nfn annotation -func newNfnIfs(nfn NfnAnnotation, new []WorkloadIfIntentSpec) NfnAnnotation { - // Prepare a new interface list - combining the original plus new ones - var newNfn NfnAnnotation - - if nfn.CniType != CNI_TYPE_OVN4NFV { - if len(nfn.CniType) > 0 { - log.Warn("Error existing nfn cnitype is invalid", log.Fields{ - "existing cnitype": nfn.CniType, - "using cnitype": CNI_TYPE_OVN4NFV, - }) - } - } - newNfn.CniType = CNI_TYPE_OVN4NFV - - // update any interfaces already in the list with the updated interface - for _, i := range nfn.Interface { - for _, j := range new { - if i.NetworkName == j.NetworkName && i.IfName == j.IfName { - i.DefaultGateway = j.DefaultGateway - i.IpAddr = j.IpAddr - i.MacAddr = j.MacAddr - break - } - } - newNfn.Interface = append(newNfn.Interface, i) - } - - // add new interfaces not present in original list - for _, j := range new { - found := false - for _, i := range nfn.Interface { - if i.NetworkName == j.NetworkName && i.IfName == j.IfName { - found = true - break - } - } - if !found { - newNfn.Interface = append(newNfn.Interface, j) - } - } - return newNfn -} - -func updatePodTemplateNetworkAnnotation(pt *v1core.PodTemplateSpec, a nettypes.NetworkSelectionElement) { - netAnnotation, _ := ParsePodTemplateNetworkAnnotation(pt) - elements := addNetworkAnnotation(a, netAnnotation) - j, err := json.Marshal(elements) - if err != nil { - log.Error("Existing network annotation has invalid format", log.Fields{ - "error": err, - }) - return - } - if pt.Annotations == nil { - pt.Annotations = make(map[string]string) - } - pt.Annotations[nettypes.NetworkAttachmentAnnot] = string(j) -} - -// Add a network annotation to the resource -func AddNetworkAnnotation(r interface{}, a nettypes.NetworkSelectionElement) { - - switch o := r.(type) { - case *batch.Job: - updatePodTemplateNetworkAnnotation(&o.Spec.Template, a) - case *batchv1beta1.CronJob: - updatePodTemplateNetworkAnnotation(&o.Spec.JobTemplate.Spec.Template, a) - case *v1.DaemonSet: - updatePodTemplateNetworkAnnotation(&o.Spec.Template, a) - case *v1.Deployment: - updatePodTemplateNetworkAnnotation(&o.Spec.Template, a) - case *v1.ReplicaSet: - updatePodTemplateNetworkAnnotation(&o.Spec.Template, a) - case *v1.StatefulSet: - updatePodTemplateNetworkAnnotation(&o.Spec.Template, a) - case *v1core.Pod: - netAnnotation, _ := netutils.ParsePodNetworkAnnotation(o) - elements := addNetworkAnnotation(a, netAnnotation) - j, err := json.Marshal(elements) - if err != nil { - log.Error("Existing network annotation has invalid format", log.Fields{ - "error": err, - }) - break - } - if o.Annotations == nil { - o.Annotations = make(map[string]string) - } - o.Annotations[nettypes.NetworkAttachmentAnnot] = string(j) - return - case *v1core.ReplicationController: - updatePodTemplateNetworkAnnotation(o.Spec.Template, a) - default: - typeStr := fmt.Sprintf("%T", o) - log.Warn("Network annotations not supported for resource type", log.Fields{ - "resource type": typeStr, - }) - } -} - -func updatePodTemplateNfnAnnotation(pt *v1core.PodTemplateSpec, new []WorkloadIfIntentSpec) { - nfnAnnotation := GetPodTemplateNfnAnnotation(pt) - newNfnAnnotation := newNfnIfs(nfnAnnotation, new) - j, err := json.Marshal(newNfnAnnotation) - if err != nil { - log.Error("Network nfn annotation has invalid format", log.Fields{ - "error": err, - }) - return - } - if pt.Annotations == nil { - pt.Annotations = make(map[string]string) - } - pt.Annotations[NfnAnnotationKey] = string(j) -} - -// Add an nfn annotation to the resource -func AddNfnAnnotation(r interface{}, new []WorkloadIfIntentSpec) { - - switch o := r.(type) { - case *batch.Job: - updatePodTemplateNfnAnnotation(&o.Spec.Template, new) - case *batchv1beta1.CronJob: - updatePodTemplateNfnAnnotation(&o.Spec.JobTemplate.Spec.Template, new) - case *v1.DaemonSet: - updatePodTemplateNfnAnnotation(&o.Spec.Template, new) - return - case *v1.Deployment: - updatePodTemplateNfnAnnotation(&o.Spec.Template, new) - return - case *v1.ReplicaSet: - updatePodTemplateNfnAnnotation(&o.Spec.Template, new) - case *v1.StatefulSet: - updatePodTemplateNfnAnnotation(&o.Spec.Template, new) - case *v1core.Pod: - nfnAnnotation := GetPodNfnAnnotation(o) - newNfnAnnotation := newNfnIfs(nfnAnnotation, new) - j, err := json.Marshal(newNfnAnnotation) - if err != nil { - log.Error("Network nfn annotation has invalid format", log.Fields{ - "error": err, - }) - break - } - if o.Annotations == nil { - o.Annotations = make(map[string]string) - } - o.Annotations[NfnAnnotationKey] = string(j) - return - case *v1core.ReplicationController: - updatePodTemplateNfnAnnotation(o.Spec.Template, new) - return - default: - typeStr := fmt.Sprintf("%T", o) - log.Warn("Network nfn annotations not supported for resource type", log.Fields{ - "resource type": typeStr, - }) - } -} diff --git a/src/ncm/pkg/module/workloadifintent.go b/src/ncm/pkg/module/workloadifintent.go deleted file mode 100644 index 55062564..00000000 --- a/src/ncm/pkg/module/workloadifintent.go +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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" -) - -// WorkloadIfIntent contains the parameters needed for dynamic networks -type WorkloadIfIntent struct { - Metadata Metadata `json:"metadata"` - Spec WorkloadIfIntentSpec `json:"spec"` -} - -type WorkloadIfIntentSpec struct { - IfName string `json:"interface"` - NetworkName string `json:"name"` - DefaultGateway string `json:"defaultGateway"` // optional, default value is "false" - IpAddr string `json:"ipAddress,omitempty"` // optional, if not provided then will be dynamically allocated - MacAddr string `json:"macAddress,omitempty"` // optional, if not provided then will be dynamically allocated -} - -// WorkloadIfIntentKey is the key structure that is used in the database -type WorkloadIfIntentKey struct { - Project string `json:"provider"` - CompositeApp string `json:"compositeapp"` - CompositeAppVersion string `json:"compositeappversion"` - NetControlIntent string `json:"netcontrolintent"` - WorkloadIntent string `json:"workloadintent"` - WorkloadIfIntent string `json:"workloadifintent"` -} - -// Manager is an interface exposing the WorkloadIfIntent functionality -type WorkloadIfIntentManager interface { - CreateWorkloadIfIntent(wi WorkloadIfIntent, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string, exists bool) (WorkloadIfIntent, error) - GetWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) (WorkloadIfIntent, error) - GetWorkloadIfIntents(project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) ([]WorkloadIfIntent, error) - DeleteWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) error -} - -// WorkloadIfIntentClient implements the Manager -// It will also be used to maintain some localized state -type WorkloadIfIntentClient struct { - db ClientDbInfo -} - -// NewWorkloadIfIntentClient returns an instance of the WorkloadIfIntentClient -// which implements the Manager -func NewWorkloadIfIntentClient() *WorkloadIfIntentClient { - return &WorkloadIfIntentClient{ - db: ClientDbInfo{ - storeName: "orchestrator", - tagMeta: "workloadifintentmetadata", - }, - } -} - -// CreateWorkloadIfIntent - create a new WorkloadIfIntent -func (v *WorkloadIfIntentClient) CreateWorkloadIfIntent(wif WorkloadIfIntent, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string, exists bool) (WorkloadIfIntent, error) { - - //Construct key and tag to select the entry - key := WorkloadIfIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: workloadintent, - WorkloadIfIntent: wif.Metadata.Name, - } - - //Check if the Workload Intent exists - _, err := NewWorkloadIntentClient().GetWorkloadIntent(workloadintent, project, compositeapp, compositeappversion, netcontrolintent) - if err != nil { - return WorkloadIfIntent{}, pkgerrors.Errorf("Workload Intent %v does not exist", workloadintent) - } - - //Check if this WorkloadIfIntent already exists - _, err = v.GetWorkloadIfIntent(wif.Metadata.Name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent) - if err == nil && !exists { - return WorkloadIfIntent{}, pkgerrors.New("WorkloadIfIntent already exists") - } - - err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, wif) - if err != nil { - return WorkloadIfIntent{}, pkgerrors.Wrap(err, "Creating DB Entry") - } - - return wif, nil -} - -// GetWorkloadIfIntent returns the WorkloadIfIntent for corresponding name -func (v *WorkloadIfIntentClient) GetWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) (WorkloadIfIntent, error) { - - //Construct key and tag to select the entry - key := WorkloadIfIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: workloadintent, - WorkloadIfIntent: name, - } - - value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) - if err != nil { - return WorkloadIfIntent{}, pkgerrors.Wrap(err, "Get WorkloadIfIntent") - } - - //value is a byte array - if value != nil { - wif := WorkloadIfIntent{} - err = db.DBconn.Unmarshal(value[0], &wif) - if err != nil { - return WorkloadIfIntent{}, pkgerrors.Wrap(err, "Unmarshalling Value") - } - return wif, nil - } - - return WorkloadIfIntent{}, pkgerrors.New("Error getting WorkloadIfIntent") -} - -// GetWorkloadIfIntentList returns all of the WorkloadIfIntent for corresponding name -func (v *WorkloadIfIntentClient) GetWorkloadIfIntents(project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) ([]WorkloadIfIntent, error) { - - //Construct key and tag to select the entry - key := WorkloadIfIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: workloadintent, - WorkloadIfIntent: "", - } - - var resp []WorkloadIfIntent - values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) - if err != nil { - return []WorkloadIfIntent{}, pkgerrors.Wrap(err, "Get WorkloadIfIntents") - } - - for _, value := range values { - wif := WorkloadIfIntent{} - err = db.DBconn.Unmarshal(value, &wif) - if err != nil { - return []WorkloadIfIntent{}, pkgerrors.Wrap(err, "Unmarshalling Value") - } - resp = append(resp, wif) - } - - return resp, nil -} - -// Delete the WorkloadIfIntent from database -func (v *WorkloadIfIntentClient) DeleteWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) error { - - //Construct key and tag to select the entry - key := WorkloadIfIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: workloadintent, - WorkloadIfIntent: name, - } - - err := db.DBconn.Remove(v.db.storeName, key) - if err != nil { - return pkgerrors.Wrap(err, "Delete WorkloadIfIntent Entry;") - } - - return nil -} diff --git a/src/ncm/pkg/module/workloadintent.go b/src/ncm/pkg/module/workloadintent.go deleted file mode 100644 index e6916954..00000000 --- a/src/ncm/pkg/module/workloadintent.go +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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" -) - -// WorkloadIntent contains the parameters needed for dynamic networks -type WorkloadIntent struct { - Metadata Metadata `json:"metadata"` - Spec WorkloadIntentSpec `json:"spec"` -} - -type WorkloadIntentSpec struct { - AppName string `json:"application-name"` - WorkloadResource string `json:"workload-resource"` - Type string `json:"type"` -} - -// WorkloadIntentKey is the key structure that is used in the database -type WorkloadIntentKey struct { - Project string `json:"provider"` - CompositeApp string `json:"compositeapp"` - CompositeAppVersion string `json:"compositeappversion"` - NetControlIntent string `json:"netcontrolintent"` - WorkloadIntent string `json:"workloadintent"` -} - -// Manager is an interface exposing the WorkloadIntent functionality -type WorkloadIntentManager interface { - CreateWorkloadIntent(wi WorkloadIntent, project, compositeapp, compositeappversion, netcontrolintent string, exists bool) (WorkloadIntent, error) - GetWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) (WorkloadIntent, error) - GetWorkloadIntents(project, compositeapp, compositeappversion, netcontrolintent string) ([]WorkloadIntent, error) - DeleteWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) error -} - -// WorkloadIntentClient implements the Manager -// It will also be used to maintain some localized state -type WorkloadIntentClient struct { - db ClientDbInfo -} - -// NewWorkloadIntentClient returns an instance of the WorkloadIntentClient -// which implements the Manager -func NewWorkloadIntentClient() *WorkloadIntentClient { - return &WorkloadIntentClient{ - db: ClientDbInfo{ - storeName: "orchestrator", - tagMeta: "workloadintentmetadata", - }, - } -} - -// CreateWorkloadIntent - create a new WorkloadIntent -func (v *WorkloadIntentClient) CreateWorkloadIntent(wi WorkloadIntent, project, compositeapp, compositeappversion, netcontrolintent string, exists bool) (WorkloadIntent, error) { - - //Construct key and tag to select the entry - key := WorkloadIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: wi.Metadata.Name, - } - - //Check if the Network Control Intent exists - _, err := NewNetControlIntentClient().GetNetControlIntent(netcontrolintent, project, compositeapp, compositeappversion) - if err != nil { - return WorkloadIntent{}, pkgerrors.Errorf("Network Control Intent %v does not exist", netcontrolintent) - } - - //Check if this WorkloadIntent already exists - _, err = v.GetWorkloadIntent(wi.Metadata.Name, project, compositeapp, compositeappversion, netcontrolintent) - if err == nil && !exists { - return WorkloadIntent{}, pkgerrors.New("WorkloadIntent already exists") - } - - err = db.DBconn.Insert(v.db.storeName, key, nil, v.db.tagMeta, wi) - if err != nil { - return WorkloadIntent{}, pkgerrors.Wrap(err, "Creating DB Entry") - } - - return wi, nil -} - -// GetWorkloadIntent returns the WorkloadIntent for corresponding name -func (v *WorkloadIntentClient) GetWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) (WorkloadIntent, error) { - - //Construct key and tag to select the entry - key := WorkloadIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: name, - } - - value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) - if err != nil { - return WorkloadIntent{}, pkgerrors.Wrap(err, "Get WorkloadIntent") - } - - //value is a byte array - if value != nil { - wi := WorkloadIntent{} - err = db.DBconn.Unmarshal(value[0], &wi) - if err != nil { - return WorkloadIntent{}, pkgerrors.Wrap(err, "Unmarshalling Value") - } - return wi, nil - } - - return WorkloadIntent{}, pkgerrors.New("Error getting WorkloadIntent") -} - -// GetWorkloadIntentList returns all of the WorkloadIntent for corresponding name -func (v *WorkloadIntentClient) GetWorkloadIntents(project, compositeapp, compositeappversion, netcontrolintent string) ([]WorkloadIntent, error) { - - //Construct key and tag to select the entry - key := WorkloadIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: "", - } - - var resp []WorkloadIntent - values, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta) - if err != nil { - return []WorkloadIntent{}, pkgerrors.Wrap(err, "Get WorkloadIntents") - } - - for _, value := range values { - wi := WorkloadIntent{} - err = db.DBconn.Unmarshal(value, &wi) - if err != nil { - return []WorkloadIntent{}, pkgerrors.Wrap(err, "Unmarshalling Value") - } - resp = append(resp, wi) - } - - return resp, nil -} - -// Delete the WorkloadIntent from database -func (v *WorkloadIntentClient) DeleteWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) error { - - //Construct key and tag to select the entry - key := WorkloadIntentKey{ - Project: project, - CompositeApp: compositeapp, - CompositeAppVersion: compositeappversion, - NetControlIntent: netcontrolintent, - WorkloadIntent: name, - } - - err := db.DBconn.Remove(v.db.storeName, key) - if err != nil { - return pkgerrors.Wrap(err, "Delete WorkloadIntent Entry;") - } - - return nil -} |