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/api | |
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/api')
-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 |
6 files changed, 0 insertions, 1110 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) -} |