From: Le Yao Date: Thu, 10 Jun 2021 08:26:55 +0000 (+0000) Subject: Fix the format and comments X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F26%2F4326%2F1;p=icn%2Fsdwan.git Fix the format and comments Signed-off-by: Le Yao Change-Id: Ie6b8ec6b9a3ce6b9c992aad1ff73c1ae134edeb2 --- diff --git a/central-controller/src/scc/api/api.go b/central-controller/src/scc/api/api.go index 1f28dc1..08604f2 100644 --- a/central-controller/src/scc/api/api.go +++ b/central-controller/src/scc/api/api.go @@ -14,179 +14,179 @@ limitations under the License. package api import ( - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" - "github.com/gorilla/mux" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/gorilla/mux" ) // NewRouter creates a router that registers the various urls that are // supported func createHandlerMapping( - objectClient manager.ControllerObjectManager, - router *mux.Router, - collections string, - resource string ) { - objectHandler := ControllerHandler{client: objectClient} - if objectClient.IsOperationSupported("POST") == true { - router.HandleFunc( - "/" + collections, - objectHandler.createHandler).Methods("POST") - } - - if objectClient.IsOperationSupported("GETS") == true { - router.HandleFunc( - "/" + collections, - objectHandler.getsHandler).Methods("GET") - } - - if objectClient.IsOperationSupported("GET") == true { - router.HandleFunc( - "/" + collections + "/{" + resource + "}", - objectHandler.getHandler).Methods("GET") - } - - if objectClient.IsOperationSupported("DELETE") == true { - router.HandleFunc( - "/" + collections + "/{" + resource + "}", - objectHandler.deleteHandler).Methods("DELETE") - } - - if objectClient.IsOperationSupported("PUT") == true { - router.HandleFunc( - "/" + collections + "/{" + resource + "}", - objectHandler.updateHandler).Methods("PUT") - } + objectClient manager.ControllerObjectManager, + router *mux.Router, + collections string, + resource string) { + objectHandler := ControllerHandler{client: objectClient} + if objectClient.IsOperationSupported("POST") == true { + router.HandleFunc( + "/"+collections, + objectHandler.createHandler).Methods("POST") + } + + if objectClient.IsOperationSupported("GETS") == true { + router.HandleFunc( + "/"+collections, + objectHandler.getsHandler).Methods("GET") + } + + if objectClient.IsOperationSupported("GET") == true { + router.HandleFunc( + "/"+collections+"/{"+resource+"}", + objectHandler.getHandler).Methods("GET") + } + + if objectClient.IsOperationSupported("DELETE") == true { + router.HandleFunc( + "/"+collections+"/{"+resource+"}", + objectHandler.deleteHandler).Methods("DELETE") + } + + if objectClient.IsOperationSupported("PUT") == true { + router.HandleFunc( + "/"+collections+"/{"+resource+"}", + objectHandler.updateHandler).Methods("PUT") + } } func NewRouter( - overlayObjectClient manager.ControllerObjectManager, - proposalObjectClient manager.ControllerObjectManager, - hubObjectClient manager.ControllerObjectManager, - hubConnObjectClient manager.ControllerObjectManager, - hubDeviceObjectClient manager.ControllerObjectManager, - hubCNFObjectClient manager.ControllerObjectManager, - deviceObjectClient manager.ControllerObjectManager, - deviceConnObjectClient manager.ControllerObjectManager, - deviceCNFObjectClient manager.ControllerObjectManager, - ipRangeObjectClient manager.ControllerObjectManager, - providerIpRangeObjectClient manager.ControllerObjectManager, - certificateObjectClient manager.ControllerObjectManager) *mux.Router { - - router := mux.NewRouter() - ver := "v1" - mgrset := manager.GetManagerset() - - // router - verRouter := router.PathPrefix("/scc/" + ver).Subrouter() - providerRouter := router.PathPrefix("/scc/" + ver + "/provider").Subrouter() - olRouter := verRouter.PathPrefix("/" + manager.OverlayCollection + "/{" + manager.OverlayResource + "}").Subrouter() - hubRouter := olRouter.PathPrefix("/" + manager.HubCollection + "/{" + manager.HubResource + "}").Subrouter() - devRouter := olRouter.PathPrefix("/" + manager.DeviceCollection + "/{" + manager.DeviceResource + "}").Subrouter() - - // overlay API - if overlayObjectClient == nil { - overlayObjectClient = manager.NewOverlayObjectManager() - } - mgrset.Overlay = overlayObjectClient.(*manager.OverlayObjectManager) - createHandlerMapping(overlayObjectClient, verRouter, manager.OverlayCollection, manager.OverlayResource) - - // proposal API - if proposalObjectClient == nil { - proposalObjectClient = manager.NewProposalObjectManager() - } - mgrset.Proposal = proposalObjectClient.(*manager.ProposalObjectManager) - createHandlerMapping(proposalObjectClient, olRouter, manager.ProposalCollection, manager.ProposalResource) - - // hub API - if hubObjectClient == nil { - hubObjectClient = manager.NewHubObjectManager() - } - mgrset.Hub = hubObjectClient.(*manager.HubObjectManager) - createHandlerMapping(hubObjectClient, olRouter, manager.HubCollection, manager.HubResource) - - // hub-connection API - if hubConnObjectClient == nil { - hubConnObjectClient = manager.NewHubConnObjectManager() - } - mgrset.HubConn = hubConnObjectClient.(*manager.HubConnObjectManager) - createHandlerMapping(hubConnObjectClient, hubRouter, manager.ConnectionCollection, manager.ConnectionResource) - - // hub-cnf API - if hubCNFObjectClient == nil { - hubCNFObjectClient = manager.NewCNFObjectManager(true) - } - mgrset.HubCNF = hubCNFObjectClient.(*manager.CNFObjectManager) - createHandlerMapping(hubCNFObjectClient, hubRouter, manager.CNFCollection, manager.CNFResource) - - // hub-device API - if hubDeviceObjectClient == nil { - hubDeviceObjectClient = manager.NewHubDeviceObjectManager() - } - mgrset.HubDevice = hubDeviceObjectClient.(*manager.HubDeviceObjectManager) - createHandlerMapping(hubDeviceObjectClient, hubRouter, manager.DeviceCollection, manager.DeviceResource) - - // device API - if deviceObjectClient == nil { - deviceObjectClient = manager.NewDeviceObjectManager() - } - mgrset.Device = deviceObjectClient.(*manager.DeviceObjectManager) - createHandlerMapping(deviceObjectClient, olRouter, manager.DeviceCollection, manager.DeviceResource) - - // device-connection API - if deviceConnObjectClient == nil { - deviceConnObjectClient = manager.NewDeviceConnObjectManager() - } - mgrset.DeviceConn = deviceConnObjectClient.(*manager.DeviceConnObjectManager) - createHandlerMapping(deviceConnObjectClient, devRouter, manager.ConnectionCollection, manager.ConnectionResource) - - // device-cnf API - if deviceCNFObjectClient == nil { - deviceCNFObjectClient = manager.NewCNFObjectManager(false) - } - mgrset.DeviceCNF = deviceCNFObjectClient.(*manager.CNFObjectManager) - createHandlerMapping(deviceCNFObjectClient, devRouter, manager.CNFCollection, manager.CNFResource) - - // provider iprange API - if providerIpRangeObjectClient == nil { - providerIpRangeObjectClient = manager.NewIPRangeObjectManager(true) - } - mgrset.ProviderIPRange = providerIpRangeObjectClient.(*manager.IPRangeObjectManager) - createHandlerMapping(providerIpRangeObjectClient, providerRouter, manager.IPRangeCollection, manager.IPRangeResource) - - // iprange API - if ipRangeObjectClient == nil { - ipRangeObjectClient = manager.NewIPRangeObjectManager(false) - } - mgrset.IPRange = ipRangeObjectClient.(*manager.IPRangeObjectManager) - createHandlerMapping(ipRangeObjectClient, olRouter, manager.IPRangeCollection, manager.IPRangeResource) - - // certificate API - if certificateObjectClient == nil { - certificateObjectClient = manager.NewCertificateObjectManager() - } - mgrset.Cert = certificateObjectClient.(*manager.CertificateObjectManager) - createHandlerMapping(certificateObjectClient, olRouter, manager.CertCollection, manager.CertResource) - - // Add depedency - overlayObjectClient.AddOwnResManager(proposalObjectClient) - overlayObjectClient.AddOwnResManager(hubObjectClient) - overlayObjectClient.AddOwnResManager(deviceObjectClient) - overlayObjectClient.AddOwnResManager(ipRangeObjectClient) - overlayObjectClient.AddOwnResManager(certificateObjectClient) - hubObjectClient.AddOwnResManager(hubDeviceObjectClient) - deviceObjectClient.AddOwnResManager(hubDeviceObjectClient) - - proposalObjectClient.AddDepResManager(overlayObjectClient) - hubObjectClient.AddDepResManager(overlayObjectClient) - deviceObjectClient.AddDepResManager(overlayObjectClient) - ipRangeObjectClient.AddDepResManager(overlayObjectClient) - certificateObjectClient.AddDepResManager(overlayObjectClient) - hubDeviceObjectClient.AddDepResManager(hubObjectClient) - hubDeviceObjectClient.AddDepResManager(deviceObjectClient) - hubConnObjectClient.AddDepResManager(hubObjectClient) - deviceConnObjectClient.AddDepResManager(deviceObjectClient) - hubCNFObjectClient.AddDepResManager(hubObjectClient) -// deviceCNFObjectClient.AddDepResManager(deviceObjectClient) - - return router + overlayObjectClient manager.ControllerObjectManager, + proposalObjectClient manager.ControllerObjectManager, + hubObjectClient manager.ControllerObjectManager, + hubConnObjectClient manager.ControllerObjectManager, + hubDeviceObjectClient manager.ControllerObjectManager, + hubCNFObjectClient manager.ControllerObjectManager, + deviceObjectClient manager.ControllerObjectManager, + deviceConnObjectClient manager.ControllerObjectManager, + deviceCNFObjectClient manager.ControllerObjectManager, + ipRangeObjectClient manager.ControllerObjectManager, + providerIpRangeObjectClient manager.ControllerObjectManager, + certificateObjectClient manager.ControllerObjectManager) *mux.Router { + + router := mux.NewRouter() + ver := "v1" + mgrset := manager.GetManagerset() + + // router + verRouter := router.PathPrefix("/scc/" + ver).Subrouter() + providerRouter := router.PathPrefix("/scc/" + ver + "/provider").Subrouter() + olRouter := verRouter.PathPrefix("/" + manager.OverlayCollection + "/{" + manager.OverlayResource + "}").Subrouter() + hubRouter := olRouter.PathPrefix("/" + manager.HubCollection + "/{" + manager.HubResource + "}").Subrouter() + devRouter := olRouter.PathPrefix("/" + manager.DeviceCollection + "/{" + manager.DeviceResource + "}").Subrouter() + + // overlay API + if overlayObjectClient == nil { + overlayObjectClient = manager.NewOverlayObjectManager() + } + mgrset.Overlay = overlayObjectClient.(*manager.OverlayObjectManager) + createHandlerMapping(overlayObjectClient, verRouter, manager.OverlayCollection, manager.OverlayResource) + + // proposal API + if proposalObjectClient == nil { + proposalObjectClient = manager.NewProposalObjectManager() + } + mgrset.Proposal = proposalObjectClient.(*manager.ProposalObjectManager) + createHandlerMapping(proposalObjectClient, olRouter, manager.ProposalCollection, manager.ProposalResource) + + // hub API + if hubObjectClient == nil { + hubObjectClient = manager.NewHubObjectManager() + } + mgrset.Hub = hubObjectClient.(*manager.HubObjectManager) + createHandlerMapping(hubObjectClient, olRouter, manager.HubCollection, manager.HubResource) + + // hub-connection API + if hubConnObjectClient == nil { + hubConnObjectClient = manager.NewHubConnObjectManager() + } + mgrset.HubConn = hubConnObjectClient.(*manager.HubConnObjectManager) + createHandlerMapping(hubConnObjectClient, hubRouter, manager.ConnectionCollection, manager.ConnectionResource) + + // hub-cnf API + if hubCNFObjectClient == nil { + hubCNFObjectClient = manager.NewCNFObjectManager(true) + } + mgrset.HubCNF = hubCNFObjectClient.(*manager.CNFObjectManager) + createHandlerMapping(hubCNFObjectClient, hubRouter, manager.CNFCollection, manager.CNFResource) + + // hub-device API + if hubDeviceObjectClient == nil { + hubDeviceObjectClient = manager.NewHubDeviceObjectManager() + } + mgrset.HubDevice = hubDeviceObjectClient.(*manager.HubDeviceObjectManager) + createHandlerMapping(hubDeviceObjectClient, hubRouter, manager.DeviceCollection, manager.DeviceResource) + + // device API + if deviceObjectClient == nil { + deviceObjectClient = manager.NewDeviceObjectManager() + } + mgrset.Device = deviceObjectClient.(*manager.DeviceObjectManager) + createHandlerMapping(deviceObjectClient, olRouter, manager.DeviceCollection, manager.DeviceResource) + + // device-connection API + if deviceConnObjectClient == nil { + deviceConnObjectClient = manager.NewDeviceConnObjectManager() + } + mgrset.DeviceConn = deviceConnObjectClient.(*manager.DeviceConnObjectManager) + createHandlerMapping(deviceConnObjectClient, devRouter, manager.ConnectionCollection, manager.ConnectionResource) + + // device-cnf API + if deviceCNFObjectClient == nil { + deviceCNFObjectClient = manager.NewCNFObjectManager(false) + } + mgrset.DeviceCNF = deviceCNFObjectClient.(*manager.CNFObjectManager) + createHandlerMapping(deviceCNFObjectClient, devRouter, manager.CNFCollection, manager.CNFResource) + + // provider iprange API + if providerIpRangeObjectClient == nil { + providerIpRangeObjectClient = manager.NewIPRangeObjectManager(true) + } + mgrset.ProviderIPRange = providerIpRangeObjectClient.(*manager.IPRangeObjectManager) + createHandlerMapping(providerIpRangeObjectClient, providerRouter, manager.IPRangeCollection, manager.IPRangeResource) + + // iprange API + if ipRangeObjectClient == nil { + ipRangeObjectClient = manager.NewIPRangeObjectManager(false) + } + mgrset.IPRange = ipRangeObjectClient.(*manager.IPRangeObjectManager) + createHandlerMapping(ipRangeObjectClient, olRouter, manager.IPRangeCollection, manager.IPRangeResource) + + // certificate API + if certificateObjectClient == nil { + certificateObjectClient = manager.NewCertificateObjectManager() + } + mgrset.Cert = certificateObjectClient.(*manager.CertificateObjectManager) + createHandlerMapping(certificateObjectClient, olRouter, manager.CertCollection, manager.CertResource) + + // Add depedency + overlayObjectClient.AddOwnResManager(proposalObjectClient) + overlayObjectClient.AddOwnResManager(hubObjectClient) + overlayObjectClient.AddOwnResManager(deviceObjectClient) + overlayObjectClient.AddOwnResManager(ipRangeObjectClient) + overlayObjectClient.AddOwnResManager(certificateObjectClient) + hubObjectClient.AddOwnResManager(hubDeviceObjectClient) + deviceObjectClient.AddOwnResManager(hubDeviceObjectClient) + + proposalObjectClient.AddDepResManager(overlayObjectClient) + hubObjectClient.AddDepResManager(overlayObjectClient) + deviceObjectClient.AddDepResManager(overlayObjectClient) + ipRangeObjectClient.AddDepResManager(overlayObjectClient) + certificateObjectClient.AddDepResManager(overlayObjectClient) + hubDeviceObjectClient.AddDepResManager(hubObjectClient) + hubDeviceObjectClient.AddDepResManager(deviceObjectClient) + hubConnObjectClient.AddDepResManager(hubObjectClient) + deviceConnObjectClient.AddDepResManager(deviceObjectClient) + hubCNFObjectClient.AddDepResManager(hubObjectClient) + deviceCNFObjectClient.AddDepResManager(deviceObjectClient) + + return router } diff --git a/central-controller/src/scc/api/controller_handler.go b/central-controller/src/scc/api/controller_handler.go index c979e88..655acff 100644 --- a/central-controller/src/scc/api/controller_handler.go +++ b/central-controller/src/scc/api/controller_handler.go @@ -1,223 +1,221 @@ -/* -* 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" - "net/http" - "io" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation" - "github.com/gorilla/mux" -) - - -// ControllerHandler is used to store backend implementations objects -type ControllerHandler struct { - client manager.ControllerObjectManager -} - -// CreateHandler handles creation of the Controller Object entry in the database -func (h ControllerHandler) createHandler(w http.ResponseWriter, r *http.Request) { - var ret interface{} - var err error - var v module.ControllerObject - - vars := mux.Vars(r) - - v, err = h.client.ParseObject(r.Body) - switch { - case err == io.EOF: - http.Error(w, "Empty body", http.StatusBadRequest) - return - case err != nil: - http.Error(w, err.Error(), http.StatusUnprocessableEntity) - return - } - - validate := validation.GetValidator(h.client.GetStoreMeta()) - isValid, msg := validate.Validate(v) - if isValid == false { - http.Error(w, msg, http.StatusUnprocessableEntity) - return - } - - // Check resource depedency - err = manager.GetDBUtils().CheckDep(h.client, vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Check whether the resource is available - if h.client.IsOperationSupported("GET") { - vars[h.client.GetResourceName()] = v.GetMetadata().Name - ret, err = h.client.GetObject(vars) - if err == nil { - http.Error(w, "Resource " + v.GetMetadata().Name + " is available already", http.StatusConflict) - return - } - } - - ret, err = h.client.CreateObject(vars, v) - 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 - } -} - -// getsHandler handle GET All operations -func (h ControllerHandler) getsHandler(w http.ResponseWriter, r *http.Request) { - var err error - vars := mux.Vars(r) - - // Check resource depedency - err = manager.GetDBUtils().CheckDep(h.client, vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - ret, err := h.client.GetObjects(vars) - 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 - } -} - -// getHandler handle GET operations on a particular name -func (h ControllerHandler) getHandler(w http.ResponseWriter, r *http.Request) { - var err error - vars := mux.Vars(r) - - // Check resource depedency - err = manager.GetDBUtils().CheckDep(h.client, vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - ret, err := h.client.GetObject(vars) - 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 - } -} - -// UpdateHandler handles Update operations -func (h ControllerHandler) updateHandler(w http.ResponseWriter, r *http.Request) { - var ret interface{} - var err error - var v module.ControllerObject - - vars := mux.Vars(r) - - v, err = h.client.ParseObject(r.Body) - switch { - case err == io.EOF: - http.Error(w, "Empty body", http.StatusBadRequest) - return - case err != nil: - http.Error(w, err.Error(), http.StatusUnprocessableEntity) - return - } - - validate := validation.GetValidator(h.client.GetStoreName()) - isValid, msg := validate.Validate(v) - if isValid == false { - http.Error(w, msg, http.StatusUnprocessableEntity) - return - } - - // Check resource depedency - err = manager.GetDBUtils().CheckDep(h.client, vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - ret, err = h.client.UpdateObject(vars, v) - 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 - } -} - -//deleteHandler handles DELETE operations on a particular record -func (h ControllerHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - var err error - vars := mux.Vars(r) - - // Check resource depedency - err = manager.GetDBUtils().CheckDep(h.client, vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Check whether sub-resource available - err = manager.GetDBUtils().CheckOwn(h.client, vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - - err = h.client.DeleteObject(vars) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} +/* +* 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" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/gorilla/mux" + "io" + "net/http" +) + +// ControllerHandler is used to store backend implementations objects +type ControllerHandler struct { + client manager.ControllerObjectManager +} + +// CreateHandler handles creation of the Controller Object entry in the database +func (h ControllerHandler) createHandler(w http.ResponseWriter, r *http.Request) { + var ret interface{} + var err error + var v module.ControllerObject + + vars := mux.Vars(r) + + v, err = h.client.ParseObject(r.Body) + switch { + case err == io.EOF: + http.Error(w, "Empty body", http.StatusBadRequest) + return + case err != nil: + http.Error(w, err.Error(), http.StatusUnprocessableEntity) + return + } + + validate := validation.GetValidator(h.client.GetStoreMeta()) + isValid, msg := validate.Validate(v) + if isValid == false { + http.Error(w, msg, http.StatusUnprocessableEntity) + return + } + + // Check resource depedency + err = manager.GetDBUtils().CheckDep(h.client, vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Check whether the resource is available + if h.client.IsOperationSupported("GET") { + vars[h.client.GetResourceName()] = v.GetMetadata().Name + ret, err = h.client.GetObject(vars) + if err == nil { + http.Error(w, "Resource "+v.GetMetadata().Name+" is available already", http.StatusConflict) + return + } + } + + ret, err = h.client.CreateObject(vars, v) + 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 + } +} + +// getsHandler handle GET All operations +func (h ControllerHandler) getsHandler(w http.ResponseWriter, r *http.Request) { + var err error + vars := mux.Vars(r) + + // Check resource depedency + err = manager.GetDBUtils().CheckDep(h.client, vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + ret, err := h.client.GetObjects(vars) + 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 + } +} + +// getHandler handle GET operations on a particular name +func (h ControllerHandler) getHandler(w http.ResponseWriter, r *http.Request) { + var err error + vars := mux.Vars(r) + + // Check resource depedency + err = manager.GetDBUtils().CheckDep(h.client, vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + ret, err := h.client.GetObject(vars) + 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 + } +} + +// UpdateHandler handles Update operations +func (h ControllerHandler) updateHandler(w http.ResponseWriter, r *http.Request) { + var ret interface{} + var err error + var v module.ControllerObject + + vars := mux.Vars(r) + + v, err = h.client.ParseObject(r.Body) + switch { + case err == io.EOF: + http.Error(w, "Empty body", http.StatusBadRequest) + return + case err != nil: + http.Error(w, err.Error(), http.StatusUnprocessableEntity) + return + } + + validate := validation.GetValidator(h.client.GetStoreName()) + isValid, msg := validate.Validate(v) + if isValid == false { + http.Error(w, msg, http.StatusUnprocessableEntity) + return + } + + // Check resource depedency + err = manager.GetDBUtils().CheckDep(h.client, vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + ret, err = h.client.UpdateObject(vars, v) + 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 + } +} + +//deleteHandler handles DELETE operations on a particular record +func (h ControllerHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { + var err error + vars := mux.Vars(r) + + // Check resource depedency + err = manager.GetDBUtils().CheckDep(h.client, vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Check whether sub-resource available + err = manager.GetDBUtils().CheckOwn(h.client, vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + err = h.client.DeleteObject(vars) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusNoContent) +} diff --git a/central-controller/src/scc/cmd/main.go b/central-controller/src/scc/cmd/main.go index 861e5aa..0f4ca22 100644 --- a/central-controller/src/scc/cmd/main.go +++ b/central-controller/src/scc/cmd/main.go @@ -14,27 +14,27 @@ limitations under the License. package main import ( - "context" - "log" - "math/rand" - "net/http" - "os" - "os/signal" - "time" - "strconv" - - logs "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/api" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/auth" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" - contextDb "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb" - controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller" - "github.com/gorilla/handlers" - mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types" - - rconfig "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/config" + "context" + "log" + "math/rand" + "net/http" + "os" + "os/signal" + "strconv" + "time" + + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/api" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/gorilla/handlers" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/auth" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/config" + contextDb "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + logs "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils" + controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller" + mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types" + + rconfig "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/config" ) const default_rsync_name = "rsync" @@ -42,111 +42,111 @@ const ENV_RSYNC_NAME = "RSYNC_NAME" func main() { - rand.Seed(time.Now().UnixNano()) - - // create database and context database - err := db.InitializeDatabaseConnection("scc") - if err != nil { - log.Println("Unable to initialize database connection...") - log.Println(err) - log.Fatalln("Exiting...") - } - - err = contextDb.InitializeContextDatabase() - if err != nil { - log.Println("Unable to initialize database connection...") - log.Println(err) - log.Fatalln("Exiting...") - } - - // create sdewan namespace and root certificate - cu, err := manager.GetCertUtil() - if err == nil { - _, err = cu.CreateNamespace(manager.NameSpaceName) - if err == nil { - log.Println("Namespace is available : " + manager.NameSpaceName) - _, err = cu.CreateSelfSignedIssuer(manager.RootIssuerName, manager.NameSpaceName) - if err == nil { - log.Println("SDEWAN root issuer is available : " + manager.RootIssuerName) - _, err = cu.CreateCertificate(manager.RootCertName, manager.NameSpaceName, manager.RootIssuerName, true) - if err == nil { - log.Println("SDEWAN root certificate is available : " + manager.RootCertName) - _, err = cu.CreateCAIssuer(manager.RootCAIssuerName, manager.NameSpaceName, manager.RootCertName) - if err == nil { - log.Println("SDEWAN root ca issuer is available : " + manager.RootCAIssuerName) - } - _, err = cu.CreateCertificate(manager.SCCCertName, manager.NameSpaceName, manager.RootCAIssuerName, false) - if err == nil { - log.Println("SDEWAN central controller base certificates is available : " + manager.SCCCertName) - } - } - } - } - } - - if err != nil { - log.Println(err) - } - - //Register rsync client - serviceName := os.Getenv(ENV_RSYNC_NAME) - if serviceName == "" { - serviceName = default_rsync_name - logs.Info("Using default name for rsync service name", logs.Fields{ - "Name": serviceName, - }) - } - - client := controller.NewControllerClient() - - // Create or update the controller entry - rsync_port, _ := strconv.Atoi(rconfig.GetConfiguration().RsyncPort) - controller := controller.Controller{ - Metadata: mtypes.Metadata{ - Name: serviceName, - }, - Spec: controller.ControllerSpec{ - Host: rconfig.GetConfiguration().RsyncIP, - Port: rsync_port, - Type: controller.CONTROLLER_TYPE_ACTION, - Priority: controller.MinControllerPriority, - }, - } - _, err = client.CreateController(controller, true) - if err != nil { - logs.Error("Failed to create/update a gRPC controller", logs.Fields{ - "Error": err, - "Controller": serviceName, - }) - } - - // create http server - httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) - loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter) - log.Println("Starting SDEWAN Central Controller API") - - httpServer := &http.Server{ - Handler: loggedRouter, - Addr: ":" + config.GetConfiguration().ServicePort, - } - - connectionsClose := make(chan struct{}) - go func() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - <-c - httpServer.Shutdown(context.Background()) - close(connectionsClose) - }() - - tlsConfig, err := auth.GetTLSConfig("ca.cert", "server.cert", "server.key") - if err != nil { - log.Println("Error Getting TLS Configuration. Starting without TLS...") - log.Fatal(httpServer.ListenAndServe()) - } else { - httpServer.TLSConfig = tlsConfig - - err = httpServer.ListenAndServeTLS("", "") - } + rand.Seed(time.Now().UnixNano()) + + // create database and context database + err := db.InitializeDatabaseConnection("scc") + if err != nil { + log.Println("Unable to initialize database connection...") + log.Println(err) + log.Fatalln("Exiting...") + } + + err = contextDb.InitializeContextDatabase() + if err != nil { + log.Println("Unable to initialize database connection...") + log.Println(err) + log.Fatalln("Exiting...") + } + + // create sdewan namespace and root certificate + cu, err := manager.GetCertUtil() + if err == nil { + _, err = cu.CreateNamespace(manager.NameSpaceName) + if err == nil { + log.Println("Namespace is available : " + manager.NameSpaceName) + _, err = cu.CreateSelfSignedIssuer(manager.RootIssuerName, manager.NameSpaceName) + if err == nil { + log.Println("SDEWAN root issuer is available : " + manager.RootIssuerName) + _, err = cu.CreateCertificate(manager.RootCertName, manager.NameSpaceName, manager.RootIssuerName, true) + if err == nil { + log.Println("SDEWAN root certificate is available : " + manager.RootCertName) + _, err = cu.CreateCAIssuer(manager.RootCAIssuerName, manager.NameSpaceName, manager.RootCertName) + if err == nil { + log.Println("SDEWAN root ca issuer is available : " + manager.RootCAIssuerName) + } + _, err = cu.CreateCertificate(manager.SCCCertName, manager.NameSpaceName, manager.RootCAIssuerName, false) + if err == nil { + log.Println("SDEWAN central controller base certificates is available : " + manager.SCCCertName) + } + } + } + } + } + + if err != nil { + log.Println(err) + } + + //Register rsync client + serviceName := os.Getenv(ENV_RSYNC_NAME) + if serviceName == "" { + serviceName = default_rsync_name + logs.Info("Using default name for rsync service name", logs.Fields{ + "Name": serviceName, + }) + } + + client := controller.NewControllerClient() + + // Create or update the controller entry + rsync_port, _ := strconv.Atoi(rconfig.GetConfiguration().RsyncPort) + controller := controller.Controller{ + Metadata: mtypes.Metadata{ + Name: serviceName, + }, + Spec: controller.ControllerSpec{ + Host: rconfig.GetConfiguration().RsyncIP, + Port: rsync_port, + Type: controller.CONTROLLER_TYPE_ACTION, + Priority: controller.MinControllerPriority, + }, + } + _, err = client.CreateController(controller, true) + if err != nil { + logs.Error("Failed to create/update a gRPC controller", logs.Fields{ + "Error": err, + "Controller": serviceName, + }) + } + + // create http server + httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) + loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter) + log.Println("Starting SDEWAN Central Controller API") + + httpServer := &http.Server{ + Handler: loggedRouter, + Addr: ":" + config.GetConfiguration().ServicePort, + } + + connectionsClose := make(chan struct{}) + go func() { + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + <-c + httpServer.Shutdown(context.Background()) + close(connectionsClose) + }() + + tlsConfig, err := auth.GetTLSConfig("ca.cert", "server.cert", "server.key") + if err != nil { + log.Println("Error Getting TLS Configuration. Starting without TLS...") + log.Fatal(httpServer.ListenAndServe()) + } else { + httpServer.TLSConfig = tlsConfig + + err = httpServer.ListenAndServeTLS("", "") + } } diff --git a/central-controller/src/scc/pkg/client/kubernetesclient.go b/central-controller/src/scc/pkg/client/kubernetesclient.go index 5bbffaa..6054bcb 100644 --- a/central-controller/src/scc/pkg/client/kubernetesclient.go +++ b/central-controller/src/scc/pkg/client/kubernetesclient.go @@ -1,142 +1,141 @@ -/* - * 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. - */ -// Based on Code: https://github.com/johandry/klient - -package client - -import ( - "log" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/kubernetes" - corev1 "k8s.io/client-go/kubernetes/typed/core/v1" - certmanagerversioned "github.com/jetstack/cert-manager/pkg/client/clientset/versioned" - certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1" -) - -type KubernetesClient struct { - Context string - ConfigPath string - KubeConfig []byte -} - -func NewClient(context string, configPath string, kubeConfig []byte) *KubernetesClient { - return &KubernetesClient{ - Context: context, - ConfigPath: configPath, - KubeConfig: kubeConfig, - } -} - -func (c *KubernetesClient) ToRESTConfig() (*rest.Config, error) { - var config *rest.Config - var err error - if len(c.KubeConfig) == 0 { - // From: k8s.io/kubectl/pkg/cmd/util/kubectl_match_version.go > func setKubernetesDefaults() - config, err = c.toRawKubeConfigLoader().ClientConfig() - } else { - config, err = clientcmd.RESTConfigFromKubeConfig(c.KubeConfig) - } - - if err != nil { - return nil, err - } - - if config.GroupVersion == nil { - config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"} - } - if config.APIPath == "" { - config.APIPath = "/api" - } - if config.NegotiatedSerializer == nil { - // This codec config ensures the resources are not converted. Therefore, resources - // will not be round-tripped through internal versions. Defaulting does not happen - // on the client. - config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - } - - rest.SetKubernetesDefaults(config) - return config, nil -} - -// toRawKubeConfigLoader creates a client using the following rules: -// 1. builds from the given kubeconfig path, if not empty -// 2. use the in cluster factory if running in-cluster -// 3. gets the factory from KUBECONFIG env var -// 4. Uses $HOME/.kube/factory -// It's required to implement the interface genericclioptions.RESTClientGetter -func (c *KubernetesClient) toRawKubeConfigLoader() clientcmd.ClientConfig { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig - if len(c.ConfigPath) != 0 { - loadingRules.ExplicitPath = c.ConfigPath - } - configOverrides := &clientcmd.ConfigOverrides{ - ClusterDefaults: clientcmd.ClusterDefaults, - } - if len(c.Context) != 0 { - configOverrides.CurrentContext = c.Context - } - - return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) -} - -func (c *KubernetesClient) GetCMClients() (certmanagerv1beta1.CertmanagerV1beta1Interface, corev1.CoreV1Interface, error) { - config, err := c.ToRESTConfig() - if err != nil { - return nil, nil, err - } - - cmclientset, err := certmanagerversioned.NewForConfig(config) - if err != nil { - return nil, nil, err - } - - k8sclientset, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, nil, err - } - - return cmclientset.CertmanagerV1beta1(), k8sclientset.CoreV1(), nil -} - -func (c *KubernetesClient) KubernetesClientSet() (*kubernetes.Clientset, error) { - config, err := c.ToRESTConfig() - if err != nil { - return nil, err - } - - return kubernetes.NewForConfig(config) -} - -func (c *KubernetesClient) IsReachable() bool { - clientset, err := c.KubernetesClientSet() - if err != nil { - log.Println(err) - return false - } - - _, err = clientset.ServerVersion() - if err != nil { - log.Println(err) - return false - } - - return true -} - +/* + * 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. + */ +// Based on Code: https://github.com/johandry/klient + +package client + +import ( + certmanagerversioned "github.com/jetstack/cert-manager/pkg/client/clientset/versioned" + certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "log" +) + +type KubernetesClient struct { + Context string + ConfigPath string + KubeConfig []byte +} + +func NewClient(context string, configPath string, kubeConfig []byte) *KubernetesClient { + return &KubernetesClient{ + Context: context, + ConfigPath: configPath, + KubeConfig: kubeConfig, + } +} + +func (c *KubernetesClient) ToRESTConfig() (*rest.Config, error) { + var config *rest.Config + var err error + if len(c.KubeConfig) == 0 { + // From: k8s.io/kubectl/pkg/cmd/util/kubectl_match_version.go > func setKubernetesDefaults() + config, err = c.toRawKubeConfigLoader().ClientConfig() + } else { + config, err = clientcmd.RESTConfigFromKubeConfig(c.KubeConfig) + } + + if err != nil { + return nil, err + } + + if config.GroupVersion == nil { + config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"} + } + if config.APIPath == "" { + config.APIPath = "/api" + } + if config.NegotiatedSerializer == nil { + // This codec config ensures the resources are not converted. Therefore, resources + // will not be round-tripped through internal versions. Defaulting does not happen + // on the client. + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + } + + rest.SetKubernetesDefaults(config) + return config, nil +} + +// toRawKubeConfigLoader creates a client using the following rules: +// 1. builds from the given kubeconfig path, if not empty +// 2. use the in cluster factory if running in-cluster +// 3. gets the factory from KUBECONFIG env var +// 4. Uses $HOME/.kube/factory +// It's required to implement the interface genericclioptions.RESTClientGetter +func (c *KubernetesClient) toRawKubeConfigLoader() clientcmd.ClientConfig { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig + if len(c.ConfigPath) != 0 { + loadingRules.ExplicitPath = c.ConfigPath + } + configOverrides := &clientcmd.ConfigOverrides{ + ClusterDefaults: clientcmd.ClusterDefaults, + } + if len(c.Context) != 0 { + configOverrides.CurrentContext = c.Context + } + + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) +} + +func (c *KubernetesClient) GetCMClients() (certmanagerv1beta1.CertmanagerV1beta1Interface, corev1.CoreV1Interface, error) { + config, err := c.ToRESTConfig() + if err != nil { + return nil, nil, err + } + + cmclientset, err := certmanagerversioned.NewForConfig(config) + if err != nil { + return nil, nil, err + } + + k8sclientset, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, nil, err + } + + return cmclientset.CertmanagerV1beta1(), k8sclientset.CoreV1(), nil +} + +func (c *KubernetesClient) KubernetesClientSet() (*kubernetes.Clientset, error) { + config, err := c.ToRESTConfig() + if err != nil { + return nil, err + } + + return kubernetes.NewForConfig(config) +} + +func (c *KubernetesClient) IsReachable() bool { + clientset, err := c.KubernetesClientSet() + if err != nil { + log.Println(err) + return false + } + + _, err = clientset.ServerVersion() + if err != nil { + log.Println(err) + return false + } + + return true +} diff --git a/central-controller/src/scc/pkg/client/rsyncclient.go b/central-controller/src/scc/pkg/client/rsyncclient.go index 76e1dfd..d26bf15 100644 --- a/central-controller/src/scc/pkg/client/rsyncclient.go +++ b/central-controller/src/scc/pkg/client/rsyncclient.go @@ -1,199 +1,199 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) 2021 Intel Corporation - -package client - -import ( - "context" - "sync" - "time" - - log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc" - installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp" - pkgerrors "github.com/pkg/errors" -) - -const rsyncName = "rsync" - -/* -RsyncInfo consists of rsyncName, hostName and portNumber. -*/ -type RsyncInfo struct { - RsyncName string - hostName string - portNumber int -} - -var rsyncInfo RsyncInfo -var mutex = &sync.Mutex{} - -type _testvars struct { - UseGrpcMock bool - InstallClient installpb.InstallappClient -} - -var Testvars _testvars - -// InitRsyncClient initializes connctions to the Resource Synchronizer service -func initRsyncClient() bool { - if (RsyncInfo{}) == rsyncInfo { - mutex.Lock() - defer mutex.Unlock() - log.Error("RsyncInfo not set. InitRsyncClient failed", log.Fields{ - "Rsyncname": rsyncInfo.RsyncName, - "Hostname": rsyncInfo.hostName, - "PortNumber": rsyncInfo.portNumber, - }) - return false - } - rpc.UpdateRpcConn(rsyncInfo.RsyncName, rsyncInfo.hostName, rsyncInfo.portNumber) - return true -} - -// NewRsyncInfo shall return a newly created RsyncInfo object -func NewRsyncInfo(rName, h string, pN int) RsyncInfo { - mutex.Lock() - defer mutex.Unlock() - rsyncInfo = RsyncInfo{RsyncName: rName, hostName: h, portNumber: pN} - return rsyncInfo - -} - -// InvokeInstallApp will make the grpc call to the resource synchronizer -// or rsync controller. -// rsync will deploy the resources in the app context to the clusters as -// prepared in the app context. -func InvokeInstallApp(appContextId string) error { - var err error - var rpcClient installpb.InstallappClient - var installRes *installpb.InstallAppResponse - ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second) - defer cancel() - - // Unit test helper code - if Testvars.UseGrpcMock { - rpcClient = Testvars.InstallClient - installReq := new(installpb.InstallAppRequest) - installReq.AppContext = appContextId - installRes, err = rpcClient.InstallApp(ctx, installReq) - if err == nil { - log.Info("Response from InstappApp GRPC call", log.Fields{ - "Succeeded": installRes.AppContextInstalled, - "Message": installRes.AppContextInstallMessage, - }) - } - return nil - } - - conn := rpc.GetRpcConn(rsyncName) - if conn == nil { - initRsyncClient() - conn = rpc.GetRpcConn(rsyncName) - } - - if conn != nil { - rpcClient = installpb.NewInstallappClient(conn) - installReq := new(installpb.InstallAppRequest) - installReq.AppContext = appContextId - installRes, err = rpcClient.InstallApp(ctx, installReq) - if err == nil { - log.Info("Response from InstappApp GRPC call", log.Fields{ - "Succeeded": installRes.AppContextInstalled, - "Message": installRes.AppContextInstallMessage, - }) - } - } else { - return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", "rsync") - } - - if err == nil { - if installRes.AppContextInstalled { - log.Info("InstallApp Success", log.Fields{ - "AppContext": appContextId, - "Message": installRes.AppContextInstallMessage, - }) - return nil - } else { - return pkgerrors.Errorf("InstallApp Failed: %v", installRes.AppContextInstallMessage) - } - } - return err -} - -func InvokeUninstallApp(appContextId string) error { - var err error - var rpcClient installpb.InstallappClient - var uninstallRes *installpb.UninstallAppResponse - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - conn := rpc.GetRpcConn(rsyncName) - if conn == nil { - initRsyncClient() - conn = rpc.GetRpcConn(rsyncName) - } - - if conn != nil { - rpcClient = installpb.NewInstallappClient(conn) - uninstallReq := new(installpb.UninstallAppRequest) - uninstallReq.AppContext = appContextId - uninstallRes, err = rpcClient.UninstallApp(ctx, uninstallReq) - if err == nil { - log.Info("Response from UninstappApp GRPC call", log.Fields{ - "Succeeded": uninstallRes.AppContextUninstalled, - "Message": uninstallRes.AppContextUninstallMessage, - }) - } - } else { - return pkgerrors.Errorf("UninstallApp Failed - Could not get InstallAppClient: %v", "rsync") - } - - if err == nil { - if uninstallRes.AppContextUninstalled { - log.Info("UninstallApp Success", log.Fields{ - "AppContext": appContextId, - "Message": uninstallRes.AppContextUninstallMessage, - }) - return nil - } else { - return pkgerrors.Errorf("UninstallApp Failed: %v", uninstallRes.AppContextUninstallMessage) - } - } - return err -} - -func InvokeGetResource(appContextId string) error { - var err error - var rpcClient installpb.InstallappClient - var readAppContextRes *installpb.ReadAppContextResponse - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - conn := rpc.GetRpcConn(rsyncName) - if conn == nil { - initRsyncClient() - conn = rpc.GetRpcConn(rsyncName) - if conn == nil { - log.Error("[InvokeReadRq gRPC] connection error", log.Fields{"grpc-server": rsyncName}) - return pkgerrors.Errorf("[InvokeReadRq gRPC] connection error. grpc-server[%v]", rsyncName) - } - } - - if conn != nil { - rpcClient = installpb.NewInstallappClient(conn) - readReq := new(installpb.ReadAppContextRequest) - readReq.AppContext = appContextId - readAppContextRes, err = rpcClient.ReadAppContext(ctx, readReq) - if err == nil { - log.Info("Response from ReadAppContext GRPC call", log.Fields{ - "Succeeded": readAppContextRes.AppContextReadSuccessful, - "Message": readAppContextRes.AppContextReadMessage, - }) - } - } else { - return pkgerrors.Errorf("ReadAppContext Failed - Could not get ReadAppContext: %v", "rsync") - } - - return nil -} +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2021 Intel Corporation + +package client + +import ( + "context" + "sync" + "time" + + log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc" + installpb "github.com/open-ness/EMCO/src/rsync/pkg/grpc/installapp" + pkgerrors "github.com/pkg/errors" +) + +const rsyncName = "rsync" + +/* +RsyncInfo consists of rsyncName, hostName and portNumber. +*/ +type RsyncInfo struct { + RsyncName string + hostName string + portNumber int +} + +var rsyncInfo RsyncInfo +var mutex = &sync.Mutex{} + +type _testvars struct { + UseGrpcMock bool + InstallClient installpb.InstallappClient +} + +var Testvars _testvars + +// InitRsyncClient initializes connctions to the Resource Synchronizer service +func initRsyncClient() bool { + if (RsyncInfo{}) == rsyncInfo { + mutex.Lock() + defer mutex.Unlock() + log.Error("RsyncInfo not set. InitRsyncClient failed", log.Fields{ + "Rsyncname": rsyncInfo.RsyncName, + "Hostname": rsyncInfo.hostName, + "PortNumber": rsyncInfo.portNumber, + }) + return false + } + rpc.UpdateRpcConn(rsyncInfo.RsyncName, rsyncInfo.hostName, rsyncInfo.portNumber) + return true +} + +// NewRsyncInfo shall return a newly created RsyncInfo object +func NewRsyncInfo(rName, h string, pN int) RsyncInfo { + mutex.Lock() + defer mutex.Unlock() + rsyncInfo = RsyncInfo{RsyncName: rName, hostName: h, portNumber: pN} + return rsyncInfo + +} + +// InvokeInstallApp will make the grpc call to the resource synchronizer +// or rsync controller. +// rsync will deploy the resources in the app context to the clusters as +// prepared in the app context. +func InvokeInstallApp(appContextId string) error { + var err error + var rpcClient installpb.InstallappClient + var installRes *installpb.InstallAppResponse + ctx, cancel := context.WithTimeout(context.Background(), 600*time.Second) + defer cancel() + + // Unit test helper code + if Testvars.UseGrpcMock { + rpcClient = Testvars.InstallClient + installReq := new(installpb.InstallAppRequest) + installReq.AppContext = appContextId + installRes, err = rpcClient.InstallApp(ctx, installReq) + if err == nil { + log.Info("Response from InstappApp GRPC call", log.Fields{ + "Succeeded": installRes.AppContextInstalled, + "Message": installRes.AppContextInstallMessage, + }) + } + return nil + } + + conn := rpc.GetRpcConn(rsyncName) + if conn == nil { + initRsyncClient() + conn = rpc.GetRpcConn(rsyncName) + } + + if conn != nil { + rpcClient = installpb.NewInstallappClient(conn) + installReq := new(installpb.InstallAppRequest) + installReq.AppContext = appContextId + installRes, err = rpcClient.InstallApp(ctx, installReq) + if err == nil { + log.Info("Response from InstappApp GRPC call", log.Fields{ + "Succeeded": installRes.AppContextInstalled, + "Message": installRes.AppContextInstallMessage, + }) + } + } else { + return pkgerrors.Errorf("InstallApp Failed - Could not get InstallAppClient: %v", "rsync") + } + + if err == nil { + if installRes.AppContextInstalled { + log.Info("InstallApp Success", log.Fields{ + "AppContext": appContextId, + "Message": installRes.AppContextInstallMessage, + }) + return nil + } else { + return pkgerrors.Errorf("InstallApp Failed: %v", installRes.AppContextInstallMessage) + } + } + return err +} + +func InvokeUninstallApp(appContextId string) error { + var err error + var rpcClient installpb.InstallappClient + var uninstallRes *installpb.UninstallAppResponse + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + conn := rpc.GetRpcConn(rsyncName) + if conn == nil { + initRsyncClient() + conn = rpc.GetRpcConn(rsyncName) + } + + if conn != nil { + rpcClient = installpb.NewInstallappClient(conn) + uninstallReq := new(installpb.UninstallAppRequest) + uninstallReq.AppContext = appContextId + uninstallRes, err = rpcClient.UninstallApp(ctx, uninstallReq) + if err == nil { + log.Info("Response from UninstappApp GRPC call", log.Fields{ + "Succeeded": uninstallRes.AppContextUninstalled, + "Message": uninstallRes.AppContextUninstallMessage, + }) + } + } else { + return pkgerrors.Errorf("UninstallApp Failed - Could not get InstallAppClient: %v", "rsync") + } + + if err == nil { + if uninstallRes.AppContextUninstalled { + log.Info("UninstallApp Success", log.Fields{ + "AppContext": appContextId, + "Message": uninstallRes.AppContextUninstallMessage, + }) + return nil + } else { + return pkgerrors.Errorf("UninstallApp Failed: %v", uninstallRes.AppContextUninstallMessage) + } + } + return err +} + +func InvokeGetResource(appContextId string) error { + var err error + var rpcClient installpb.InstallappClient + var readAppContextRes *installpb.ReadAppContextResponse + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + conn := rpc.GetRpcConn(rsyncName) + if conn == nil { + initRsyncClient() + conn = rpc.GetRpcConn(rsyncName) + if conn == nil { + log.Error("[InvokeReadRq gRPC] connection error", log.Fields{"grpc-server": rsyncName}) + return pkgerrors.Errorf("[InvokeReadRq gRPC] connection error. grpc-server[%v]", rsyncName) + } + } + + if conn != nil { + rpcClient = installpb.NewInstallappClient(conn) + readReq := new(installpb.ReadAppContextRequest) + readReq.AppContext = appContextId + readAppContextRes, err = rpcClient.ReadAppContext(ctx, readReq) + if err == nil { + log.Info("Response from ReadAppContext GRPC call", log.Fields{ + "Succeeded": readAppContextRes.AppContextReadSuccessful, + "Message": readAppContextRes.AppContextReadMessage, + }) + } + } else { + return pkgerrors.Errorf("ReadAppContext Failed - Could not get ReadAppContext: %v", "rsync") + } + + return nil +} diff --git a/central-controller/src/scc/pkg/infra/config/config.go b/central-controller/src/scc/pkg/infra/config/config.go index acaf6f5..f13a2e5 100644 --- a/central-controller/src/scc/pkg/infra/config/config.go +++ b/central-controller/src/scc/pkg/infra/config/config.go @@ -1,102 +1,102 @@ -/* - * 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 config - -import ( - "encoding/json" - "log" - "os" - "reflect" -) - -// Configuration loads up all the values that are used to configure -// backend implementations -type Configuration struct { - RsyncIP string `json:"rsync-ip"` - RsyncPort string `json:"rsync-port"` -} - -// Config is the structure that stores the configuration -var gConfig *Configuration - -// readConfigFile reads the specified smsConfig file to setup some env variables -func readConfigFile(file string) (*Configuration, error) { - f, err := os.Open(file) - if err != nil { - return defaultConfiguration(), err - } - defer f.Close() - - // Setup some defaults here - // If the json file has values in it, the defaults will be overwritten - conf := defaultConfiguration() - - // Read the configuration from json file - decoder := json.NewDecoder(f) - decoder.DisallowUnknownFields() - err = decoder.Decode(conf) - if err != nil { - return conf, err - } - - return conf, nil -} - -func defaultConfiguration() *Configuration { - return &Configuration{ - RsyncIP: "localhost", - RsyncPort: "9031", - } -} - -// GetConfiguration returns the configuration for the app. -// It will try to load it if it is not already loaded. -func GetConfiguration() *Configuration { - if gConfig == nil { - conf, err := readConfigFile("rsync_config.json") - if err != nil { - log.Println("Error loading config file: ", err) - log.Println("Using defaults...") - } - gConfig = conf - } - - return gConfig -} - -// SetConfigValue sets a value in the configuration -// This is mostly used to customize the application and -// should be used carefully. -func SetConfigValue(key string, value string) *Configuration { - c := GetConfiguration() - if value == "" || key == "" { - return c - } - - v := reflect.ValueOf(c).Elem() - if v.Kind() == reflect.Struct { - f := v.FieldByName(key) - if f.IsValid() { - if f.CanSet() { - if f.Kind() == reflect.String { - f.SetString(value) - } - } - } - } - return c -} +/* + * 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 config + +import ( + "encoding/json" + "log" + "os" + "reflect" +) + +// Configuration loads up all the values that are used to configure +// backend implementations +type Configuration struct { + RsyncIP string `json:"rsync-ip"` + RsyncPort string `json:"rsync-port"` +} + +// Config is the structure that stores the configuration +var gConfig *Configuration + +// readConfigFile reads the specified smsConfig file to setup some env variables +func readConfigFile(file string) (*Configuration, error) { + f, err := os.Open(file) + if err != nil { + return defaultConfiguration(), err + } + defer f.Close() + + // Setup some defaults here + // If the json file has values in it, the defaults will be overwritten + conf := defaultConfiguration() + + // Read the configuration from json file + decoder := json.NewDecoder(f) + decoder.DisallowUnknownFields() + err = decoder.Decode(conf) + if err != nil { + return conf, err + } + + return conf, nil +} + +func defaultConfiguration() *Configuration { + return &Configuration{ + RsyncIP: "localhost", + RsyncPort: "9031", + } +} + +// GetConfiguration returns the configuration for the app. +// It will try to load it if it is not already loaded. +func GetConfiguration() *Configuration { + if gConfig == nil { + conf, err := readConfigFile("rsync_config.json") + if err != nil { + log.Println("Error loading config file: ", err) + log.Println("Using defaults...") + } + gConfig = conf + } + + return gConfig +} + +// SetConfigValue sets a value in the configuration +// This is mostly used to customize the application and +// should be used carefully. +func SetConfigValue(key string, value string) *Configuration { + c := GetConfiguration() + if value == "" || key == "" { + return c + } + + v := reflect.ValueOf(c).Elem() + if v.Kind() == reflect.Struct { + f := v.FieldByName(key) + if f.IsValid() { + if f.CanSet() { + if f.Kind() == reflect.String { + f.SetString(value) + } + } + } + } + return c +} diff --git a/central-controller/src/scc/pkg/infra/validation/validation.go b/central-controller/src/scc/pkg/infra/validation/validation.go index b466d07..cf55e45 100644 --- a/central-controller/src/scc/pkg/infra/validation/validation.go +++ b/central-controller/src/scc/pkg/infra/validation/validation.go @@ -1,91 +1,91 @@ -/* - * 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 validation - -import ( - "reflect" - "fmt" - "sync" - "github.com/go-playground/validator/v10" -) - -type SdewanValidator struct { - validate *validator.Validate -} - -type safeSdewanValidators struct { - validates map[string]*SdewanValidator - mux sync.Mutex -} - -var gvalidates = safeSdewanValidators{validates: make(map[string]*SdewanValidator)} - -func GetValidator(name string) *SdewanValidator { - return gvalidates.getValidate(name) -} - -// safeSdewanValidators -func (s *safeSdewanValidators) getValidate(name string) *SdewanValidator { - s.mux.Lock() - defer s.mux.Unlock() - - if s.validates[name] == nil { - s.validates[name] = &SdewanValidator{ - validate: validator.New(), - } - } - - return s.validates[name] -} - -// SdewanValidator -func(v *SdewanValidator) Validate(data interface{}) (bool, string) { - err := v.validate.Struct(data) - if err != nil { - if _, ok := err.(*validator.InvalidValidationError); ok { - return false, reflect.TypeOf(err).String() - } - - msg := "Input fields check error: [" - index := 1 - for _, err := range err.(validator.ValidationErrors) { - fieldMsg := fmt.Sprintf("%s(%s:%s)", err.Field(), err.Tag(), err.Param()) - if index == 1 { - msg = msg + fieldMsg - } else { - msg = msg + ", " + fieldMsg - } - - index = index + 1 - } - - msg = msg +"]" - - // from here you can create your own error messages in whatever language you wish - return false, msg - } - - return true, "" -} - -func(v *SdewanValidator) RegisterValidation(tag string, fn validator.Func) error { - return v.validate.RegisterValidation(tag, fn) -} - -func(v *SdewanValidator) RegisterStructValidation(fn validator.StructLevelFunc, types interface{}) { - v.validate.RegisterStructValidation(fn, types) -} \ No newline at end of file +/* + * 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 validation + +import ( + "fmt" + "github.com/go-playground/validator/v10" + "reflect" + "sync" +) + +type SdewanValidator struct { + validate *validator.Validate +} + +type safeSdewanValidators struct { + validates map[string]*SdewanValidator + mux sync.Mutex +} + +var gvalidates = safeSdewanValidators{validates: make(map[string]*SdewanValidator)} + +func GetValidator(name string) *SdewanValidator { + return gvalidates.getValidate(name) +} + +// safeSdewanValidators +func (s *safeSdewanValidators) getValidate(name string) *SdewanValidator { + s.mux.Lock() + defer s.mux.Unlock() + + if s.validates[name] == nil { + s.validates[name] = &SdewanValidator{ + validate: validator.New(), + } + } + + return s.validates[name] +} + +// SdewanValidator +func (v *SdewanValidator) Validate(data interface{}) (bool, string) { + err := v.validate.Struct(data) + if err != nil { + if _, ok := err.(*validator.InvalidValidationError); ok { + return false, reflect.TypeOf(err).String() + } + + msg := "Input fields check error: [" + index := 1 + for _, err := range err.(validator.ValidationErrors) { + fieldMsg := fmt.Sprintf("%s(%s:%s)", err.Field(), err.Tag(), err.Param()) + if index == 1 { + msg = msg + fieldMsg + } else { + msg = msg + ", " + fieldMsg + } + + index = index + 1 + } + + msg = msg + "]" + + // from here you can create your own error messages in whatever language you wish + return false, msg + } + + return true, "" +} + +func (v *SdewanValidator) RegisterValidation(tag string, fn validator.Func) error { + return v.validate.RegisterValidation(tag, fn) +} + +func (v *SdewanValidator) RegisterStructValidation(fn validator.StructLevelFunc, types interface{}) { + v.validate.RegisterStructValidation(fn, types) +} diff --git a/central-controller/src/scc/pkg/manager/certificate_objectmanager.go b/central-controller/src/scc/pkg/manager/certificate_objectmanager.go index 70cf22c..509f742 100644 --- a/central-controller/src/scc/pkg/manager/certificate_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/certificate_objectmanager.go @@ -1,245 +1,244 @@ -/* - * 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 manager - -import ( - "io" - "log" - "encoding/base64" - "encoding/json" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -type CertificateObjectKey struct { - OverlayName string `json:"overlay-name"` - CertificateName string `json:"certificate-name"` -} - -// IPRangeObjectManager implements the ControllerObjectManager -type CertificateObjectManager struct { - BaseObjectManager -} - -func NewCertificateObjectManager() *CertificateObjectManager { - return &CertificateObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "certificate", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *CertificateObjectManager) GetResourceName() string { - return CertResource -} - -func (c *CertificateObjectManager) IsOperationSupported(oper string) bool { - if oper == "PUT" { - // Not allowed for gets - return false - } - return true -} - -func (c *CertificateObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.CertificateObject{} -} - -func (c *CertificateObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - key := CertificateObjectKey{ - OverlayName: overlay_name, - CertificateName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.CertificateObject) - meta_name := to.Metadata.Name - res_name := m[CertResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.CertificateName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.CertificateName = meta_name - } - - return key, nil; -} - -func (c *CertificateObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.CertificateObject - err := json.NewDecoder(r).Decode(&v) - - v.Data = module.CertificateObjectData{ - RootCA: "", - Ca: "", - Key: "", - } - - return &v, err -} - -func (c *CertificateObjectManager) GetDeviceCertName(name string) string { - device := module.DeviceObject{ - Metadata: module.ObjectMetaData{name, "", "", ""}} - return device.GetCertName() -} - -func GetRootCA(overlay_name string) string { - overlay := GetManagerset().Overlay - cu, _ := GetCertUtil() - - root_ca := cu.GetSelfSignedCA() - interim_ca, _, _ := overlay.GetCertificate(overlay_name) - - root_ca += interim_ca - - return root_ca -} - -func GetRootBaseCA() string { - cu, _ := GetCertUtil() - - root_ca := cu.GetSelfSignedCA() - - return root_ca -} - - -func (c *CertificateObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // Create Certificate - overlay := GetManagerset().Overlay - overlay_name := m[OverlayResource] - cert_name := c.GetDeviceCertName(t.GetMetadata().Name) - - ca, key, err := overlay.CreateCertificate(overlay_name, cert_name) - if err != nil { - log.Println(err) - return c.CreateEmptyObject(), err - } - - // DB Operation - t, err = GetDBUtils().CreateObject(c, m, t) - - // Fill Certificate data - if err == nil { - to := t.(*module.CertificateObject) - to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name))) - to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca)) - to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key)) - - return t, nil - } else { - log.Println(err) - return c.CreateEmptyObject(), err - } -} - -func (c *CertificateObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObject(c, m) - - if err == nil { - overlay := GetManagerset().Overlay - overlay_name := m[OverlayResource] - cert_name := c.GetDeviceCertName(t.GetMetadata().Name) - - ca, key, err := overlay.CreateCertificate(overlay_name, cert_name) - if err != nil { - log.Println(err) - return c.CreateEmptyObject(), err - } - - to := t.(*module.CertificateObject) - to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name))) - to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca)) - to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key)) - - return t, nil - } else { - log.Println(err) - return c.CreateEmptyObject(), err - } -} - -func (c *CertificateObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObjects(c, m) - - return t, err -} - -func (c *CertificateObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *CertificateObjectManager) DeleteObject(m map[string]string) error { - t, err := c.GetObject(m) - if err != nil { - return pkgerrors.Wrap(err, "Certificate is not available") - } - - // Delete certificate - overlay := GetManagerset().Overlay - cert_name := c.GetDeviceCertName(t.GetMetadata().Name) - - log.Println("Delete Certificate: " + cert_name) - overlay.DeleteCertificate(cert_name) - - // DB Operation - err = GetDBUtils().DeleteObject(c, m) - - return err -} - -// Create or Get certificate for a device -func (c *CertificateObjectManager) GetOrCreateDC(overlay_name string, dev_name string) (string, string, string, error) { - m := make(map[string]string) - m[OverlayResource] = overlay_name - t := &module.CertificateObject{Metadata: module.ObjectMetaData{dev_name, "", "", ""}} - - _, err := c.CreateObject(m, t) - if err != nil { - return "", "", "", err - } - - return t.Data.RootCA, t.Data.Ca, t.Data.Key, nil -} - -// Delete certificate for a device -func (c *CertificateObjectManager) DeleteDC(overlay_name string, dev_name string) error { - m := make(map[string]string) - m[OverlayResource] = overlay_name - m[CertResource] = dev_name - - return c.DeleteObject(m) -} +/* + * 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 manager + +import ( + "encoding/base64" + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" + "log" +) + +type CertificateObjectKey struct { + OverlayName string `json:"overlay-name"` + CertificateName string `json:"certificate-name"` +} + +// IPRangeObjectManager implements the ControllerObjectManager +type CertificateObjectManager struct { + BaseObjectManager +} + +func NewCertificateObjectManager() *CertificateObjectManager { + return &CertificateObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "certificate", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *CertificateObjectManager) GetResourceName() string { + return CertResource +} + +func (c *CertificateObjectManager) IsOperationSupported(oper string) bool { + if oper == "PUT" { + // Not allowed for gets + return false + } + return true +} + +func (c *CertificateObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.CertificateObject{} +} + +func (c *CertificateObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + key := CertificateObjectKey{ + OverlayName: overlay_name, + CertificateName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.CertificateObject) + meta_name := to.Metadata.Name + res_name := m[CertResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.CertificateName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.CertificateName = meta_name + } + + return key, nil +} + +func (c *CertificateObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.CertificateObject + err := json.NewDecoder(r).Decode(&v) + + v.Data = module.CertificateObjectData{ + RootCA: "", + Ca: "", + Key: "", + } + + return &v, err +} + +func (c *CertificateObjectManager) GetDeviceCertName(name string) string { + device := module.DeviceObject{ + Metadata: module.ObjectMetaData{name, "", "", ""}} + return device.GetCertName() +} + +func GetRootCA(overlay_name string) string { + overlay := GetManagerset().Overlay + cu, _ := GetCertUtil() + + root_ca := cu.GetSelfSignedCA() + interim_ca, _, _ := overlay.GetCertificate(overlay_name) + + root_ca += interim_ca + + return root_ca +} + +func GetRootBaseCA() string { + cu, _ := GetCertUtil() + + root_ca := cu.GetSelfSignedCA() + + return root_ca +} + +func (c *CertificateObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // Create Certificate + overlay := GetManagerset().Overlay + overlay_name := m[OverlayResource] + cert_name := c.GetDeviceCertName(t.GetMetadata().Name) + + ca, key, err := overlay.CreateCertificate(overlay_name, cert_name) + if err != nil { + log.Println(err) + return c.CreateEmptyObject(), err + } + + // DB Operation + t, err = GetDBUtils().CreateObject(c, m, t) + + // Fill Certificate data + if err == nil { + to := t.(*module.CertificateObject) + to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name))) + to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca)) + to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key)) + + return t, nil + } else { + log.Println(err) + return c.CreateEmptyObject(), err + } +} + +func (c *CertificateObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObject(c, m) + + if err == nil { + overlay := GetManagerset().Overlay + overlay_name := m[OverlayResource] + cert_name := c.GetDeviceCertName(t.GetMetadata().Name) + + ca, key, err := overlay.CreateCertificate(overlay_name, cert_name) + if err != nil { + log.Println(err) + return c.CreateEmptyObject(), err + } + + to := t.(*module.CertificateObject) + to.Data.RootCA = base64.StdEncoding.EncodeToString([]byte(GetRootCA(overlay_name))) + to.Data.Ca = base64.StdEncoding.EncodeToString([]byte(ca)) + to.Data.Key = base64.StdEncoding.EncodeToString([]byte(key)) + + return t, nil + } else { + log.Println(err) + return c.CreateEmptyObject(), err + } +} + +func (c *CertificateObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObjects(c, m) + + return t, err +} + +func (c *CertificateObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *CertificateObjectManager) DeleteObject(m map[string]string) error { + t, err := c.GetObject(m) + if err != nil { + return pkgerrors.Wrap(err, "Certificate is not available") + } + + // Delete certificate + overlay := GetManagerset().Overlay + cert_name := c.GetDeviceCertName(t.GetMetadata().Name) + + log.Println("Delete Certificate: " + cert_name) + overlay.DeleteCertificate(cert_name) + + // DB Operation + err = GetDBUtils().DeleteObject(c, m) + + return err +} + +// Create or Get certificate for a device +func (c *CertificateObjectManager) GetOrCreateDC(overlay_name string, dev_name string) (string, string, string, error) { + m := make(map[string]string) + m[OverlayResource] = overlay_name + t := &module.CertificateObject{Metadata: module.ObjectMetaData{dev_name, "", "", ""}} + + _, err := c.CreateObject(m, t) + if err != nil { + return "", "", "", err + } + + return t.Data.RootCA, t.Data.Ca, t.Data.Key, nil +} + +// Delete certificate for a device +func (c *CertificateObjectManager) DeleteDC(overlay_name string, dev_name string) error { + m := make(map[string]string) + m[OverlayResource] = overlay_name + m[CertResource] = dev_name + + return c.DeleteObject(m) +} diff --git a/central-controller/src/scc/pkg/manager/certutil.go b/central-controller/src/scc/pkg/manager/certutil.go index c0be5b7..18757d1 100644 --- a/central-controller/src/scc/pkg/manager/certutil.go +++ b/central-controller/src/scc/pkg/manager/certutil.go @@ -1,213 +1,212 @@ -/* - * 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 manager - -import ( - "log" - "context" - "time" - pkgerrors "github.com/pkg/errors" - kclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" - cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" - v1 "k8s.io/api/core/v1" - corev1 "k8s.io/client-go/kubernetes/typed/core/v1" - certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1" - v1beta1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1beta1" -) - -const SELFSIGNEDCA = "sdewan-controller" - -type CertUtil struct { - client certmanagerv1beta1.CertmanagerV1beta1Interface - k8sclient corev1.CoreV1Interface -} - -var certutil = CertUtil{} - -func GetCertUtil() (*CertUtil, error) { - var err error - if certutil.client == nil || certutil.k8sclient == nil { - certutil.client, certutil.k8sclient, err = kclient.NewClient("", "", []byte{}).GetCMClients() - } - - return &certutil, err -} - -func (c *CertUtil) CreateNamespace(name string) (*v1.Namespace, error) { - ns, err := c.k8sclient.Namespaces().Get(context.TODO(), name, metav1.GetOptions{}) - if err == nil { - return ns, nil - } - - log.Println("Create Namespace: " + name) - return c.k8sclient.Namespaces().Create(context.TODO(), &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - }, metav1.CreateOptions{}) -} - -func (c *CertUtil) DeleteNamespace(name string) error { - return c.k8sclient.Namespaces().Delete(context.TODO(), name, metav1.DeleteOptions{}) -} - -func (c *CertUtil) GetIssuer(name string, namespace string) (*v1beta1.Issuer, error) { - return c.client.Issuers(namespace).Get(context.TODO(), name, metav1.GetOptions{}) -} - -func (c *CertUtil) DeleteIssuer(name string, namespace string) error { - return c.client.Issuers(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) -} - -func (c *CertUtil) CreateSelfSignedIssuer(name string, namespace string) (*v1beta1.Issuer, error) { - issuer, err := c.GetIssuer(name, namespace) - if err == nil { - return issuer, nil - } - - // Not existing issuer, create a new one - return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1beta1.IssuerSpec{ - IssuerConfig: v1beta1.IssuerConfig{ - SelfSigned: &v1beta1.SelfSignedIssuer{ - }, - }, - }, - }, metav1.CreateOptions{}) -} - -func (c *CertUtil) CreateCAIssuer(name string, namespace string, caname string) (*v1beta1.Issuer, error) { - issuer, err := c.GetIssuer(name, namespace) - if err == nil { - return issuer, nil - } - - // Not existing issuer, create a new one - return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1beta1.IssuerSpec{ - IssuerConfig: v1beta1.IssuerConfig{ - CA: &v1beta1.CAIssuer{ - SecretName: c.GetCertSecretName(caname), - }, - }, - }, - }, metav1.CreateOptions{}) -} - -func (c *CertUtil) GetCertSecretName(name string) string { - return name + "-cert-secret" -} - -func (c *CertUtil) GetCertificate(name string, namespace string) (*v1beta1.Certificate, error) { - return c.client.Certificates(namespace).Get(context.TODO(), name, metav1.GetOptions{}) -} - -func (c *CertUtil) DeleteCertificate(name string, namespace string) error { - return c.client.Certificates(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) -} - -func (c *CertUtil) CreateCertificate(name string, namespace string, issuer string, isCA bool) (*v1beta1.Certificate, error) { - cert, err := c.GetCertificate(name, namespace) - if err == nil { - return cert, nil - } - - // Not existing cert, create a new one - // Todo: add Duration, RenewBefore, DNSNames - cert, err = c.client.Certificates(namespace).Create(context.TODO(), &v1beta1.Certificate{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1beta1.CertificateSpec{ - CommonName: name, - // Duration: duration, - // RenewBefore: renewBefore, - // DNSNames: dnsNames, - SecretName: c.GetCertSecretName(name), - IssuerRef: cmmeta.ObjectReference { - Name: issuer, - Kind: "Issuer", - }, - IsCA: isCA, - }, - }, metav1.CreateOptions{}) - - if err == nil { - if c.IsCertReady(name, namespace) { - return cert, nil - } else { - return cert, pkgerrors.New("Failed to get certificate " + name) - } - } - - return cert, err -} - -func (c *CertUtil) IsCertReady(name string, namespace string) bool { - err := wait.PollImmediate(time.Second, time.Second*20, - func() (bool, error) { - var err error - var crt *v1beta1.Certificate - crt, err = c.GetCertificate(name, namespace) - if err != nil { - log.Println("Failed to find certificate " + name + ": " + err.Error()) - return false, err - } - curConditions := crt.Status.Conditions - for _, cond := range curConditions { - if v1beta1.CertificateConditionReady == cond.Type && cmmeta.ConditionTrue == cond.Status { - return true, nil - } - } - log.Println("Waiting for Certificate " + name + " to be ready.") - return false, nil - }, - ) - - if err != nil { - log.Println(err) - return false - } - - return true -} - -func (c *CertUtil) GetKeypair(certname string, namespace string) (string, string, error) { - secret, err := c.k8sclient.Secrets(namespace).Get( - context.TODO(), - c.GetCertSecretName(certname), - metav1.GetOptions{}) - if err != nil { - log.Println("Failed to get certificate's key pair: " + err.Error()) - return "", "", err - } - - return string(secret.Data["tls.crt"]), string(secret.Data["tls.key"]), nil -} - -func (c *CertUtil) GetSelfSignedCA() (string) { - ca, _, _ := c.GetKeypair(RootCertName, NameSpaceName) - return ca -} +/* + * 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 manager + +import ( + "context" + kclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" + v1beta1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1beta1" + cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1" + certmanagerv1beta1 "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/typed/certmanager/v1beta1" + pkgerrors "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" + "log" + "time" +) + +const SELFSIGNEDCA = "sdewan-controller" + +type CertUtil struct { + client certmanagerv1beta1.CertmanagerV1beta1Interface + k8sclient corev1.CoreV1Interface +} + +var certutil = CertUtil{} + +func GetCertUtil() (*CertUtil, error) { + var err error + if certutil.client == nil || certutil.k8sclient == nil { + certutil.client, certutil.k8sclient, err = kclient.NewClient("", "", []byte{}).GetCMClients() + } + + return &certutil, err +} + +func (c *CertUtil) CreateNamespace(name string) (*v1.Namespace, error) { + ns, err := c.k8sclient.Namespaces().Get(context.TODO(), name, metav1.GetOptions{}) + if err == nil { + return ns, nil + } + + log.Println("Create Namespace: " + name) + return c.k8sclient.Namespaces().Create(context.TODO(), &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }, metav1.CreateOptions{}) +} + +func (c *CertUtil) DeleteNamespace(name string) error { + return c.k8sclient.Namespaces().Delete(context.TODO(), name, metav1.DeleteOptions{}) +} + +func (c *CertUtil) GetIssuer(name string, namespace string) (*v1beta1.Issuer, error) { + return c.client.Issuers(namespace).Get(context.TODO(), name, metav1.GetOptions{}) +} + +func (c *CertUtil) DeleteIssuer(name string, namespace string) error { + return c.client.Issuers(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) +} + +func (c *CertUtil) CreateSelfSignedIssuer(name string, namespace string) (*v1beta1.Issuer, error) { + issuer, err := c.GetIssuer(name, namespace) + if err == nil { + return issuer, nil + } + + // Not existing issuer, create a new one + return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1beta1.IssuerSpec{ + IssuerConfig: v1beta1.IssuerConfig{ + SelfSigned: &v1beta1.SelfSignedIssuer{}, + }, + }, + }, metav1.CreateOptions{}) +} + +func (c *CertUtil) CreateCAIssuer(name string, namespace string, caname string) (*v1beta1.Issuer, error) { + issuer, err := c.GetIssuer(name, namespace) + if err == nil { + return issuer, nil + } + + // Not existing issuer, create a new one + return c.client.Issuers(namespace).Create(context.TODO(), &v1beta1.Issuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1beta1.IssuerSpec{ + IssuerConfig: v1beta1.IssuerConfig{ + CA: &v1beta1.CAIssuer{ + SecretName: c.GetCertSecretName(caname), + }, + }, + }, + }, metav1.CreateOptions{}) +} + +func (c *CertUtil) GetCertSecretName(name string) string { + return name + "-cert-secret" +} + +func (c *CertUtil) GetCertificate(name string, namespace string) (*v1beta1.Certificate, error) { + return c.client.Certificates(namespace).Get(context.TODO(), name, metav1.GetOptions{}) +} + +func (c *CertUtil) DeleteCertificate(name string, namespace string) error { + return c.client.Certificates(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) +} + +func (c *CertUtil) CreateCertificate(name string, namespace string, issuer string, isCA bool) (*v1beta1.Certificate, error) { + cert, err := c.GetCertificate(name, namespace) + if err == nil { + return cert, nil + } + + // Not existing cert, create a new one + // Todo: add Duration, RenewBefore, DNSNames + cert, err = c.client.Certificates(namespace).Create(context.TODO(), &v1beta1.Certificate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1beta1.CertificateSpec{ + CommonName: name, + // Duration: duration, + // RenewBefore: renewBefore, + // DNSNames: dnsNames, + SecretName: c.GetCertSecretName(name), + IssuerRef: cmmeta.ObjectReference{ + Name: issuer, + Kind: "Issuer", + }, + IsCA: isCA, + }, + }, metav1.CreateOptions{}) + + if err == nil { + if c.IsCertReady(name, namespace) { + return cert, nil + } else { + return cert, pkgerrors.New("Failed to get certificate " + name) + } + } + + return cert, err +} + +func (c *CertUtil) IsCertReady(name string, namespace string) bool { + err := wait.PollImmediate(time.Second, time.Second*20, + func() (bool, error) { + var err error + var crt *v1beta1.Certificate + crt, err = c.GetCertificate(name, namespace) + if err != nil { + log.Println("Failed to find certificate " + name + ": " + err.Error()) + return false, err + } + curConditions := crt.Status.Conditions + for _, cond := range curConditions { + if v1beta1.CertificateConditionReady == cond.Type && cmmeta.ConditionTrue == cond.Status { + return true, nil + } + } + log.Println("Waiting for Certificate " + name + " to be ready.") + return false, nil + }, + ) + + if err != nil { + log.Println(err) + return false + } + + return true +} + +func (c *CertUtil) GetKeypair(certname string, namespace string) (string, string, error) { + secret, err := c.k8sclient.Secrets(namespace).Get( + context.TODO(), + c.GetCertSecretName(certname), + metav1.GetOptions{}) + if err != nil { + log.Println("Failed to get certificate's key pair: " + err.Error()) + return "", "", err + } + + return string(secret.Data["tls.crt"]), string(secret.Data["tls.key"]), nil +} + +func (c *CertUtil) GetSelfSignedCA() string { + ca, _, _ := c.GetKeypair(RootCertName, NameSpaceName) + return ca +} diff --git a/central-controller/src/scc/pkg/manager/cnf_objectmanager.go b/central-controller/src/scc/pkg/manager/cnf_objectmanager.go index 3e44b27..408862d 100644 --- a/central-controller/src/scc/pkg/manager/cnf_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/cnf_objectmanager.go @@ -1,241 +1,218 @@ -/* - * 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 manager - -import ( - "io" - "encoding/json" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" - - "k8s.io/apimachinery/pkg/runtime/schema" - "log" -) - -type CNFObjectKey struct { - OverlayName string `json:"overlay-name"` - ClusterName string `json:"cluster-name"` - CNFName string `json:"cnf-name"` -} - -// CNFObjectManager implements the ControllerObjectManager -type CNFObjectManager struct { - BaseObjectManager - isHub bool -} - -func NewCNFObjectManager(isHub bool) *CNFObjectManager { - object_meta := "cnf" - if isHub { - object_meta = "hub-" + object_meta - } else { - object_meta = "device-" + object_meta - } - - return &CNFObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: object_meta, - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - isHub, - } -} - -func (c *CNFObjectManager) GetResourceName() string { - return CNFResource -} - -func (c *CNFObjectManager) IsOperationSupported(oper string) bool { - if oper == "GETS" { - return true - } - return false -} - -func (c *CNFObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.CNFObject{} -} - -func (c *CNFObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - cluster_name := "" - if c.isHub { - cluster_name = m[HubResource] - } else { - cluster_name = m[DeviceResource] - } - - key := CNFObjectKey{ - OverlayName: overlay_name, - ClusterName: cluster_name, - CNFName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.CNFObject) - meta_name := to.Metadata.Name - res_name := m[CNFResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.CNFName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.CNFName = meta_name - } - - return key, nil; -} - -func (c *CNFObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.CNFObject - err := json.NewDecoder(r).Decode(&v) - - return &v, err -} - -func (c *CNFObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *CNFObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *CNFObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - overlay_name := m[OverlayResource] - var cobj module.ControllerObject - var cluster_name string - var err error - - if c.isHub { - cluster_name = m[HubResource] - hub_name := m[HubResource] - hub_manager := GetManagerset().Hub - cobj, err = hub_manager.GetObject(m) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Hub " + hub_name + " is not defined") - } - } else { - cluster_name = m[DeviceResource] - device_name := m[DeviceResource] - dev_manager := GetManagerset().Device - cobj, err = dev_manager.GetObject(m) - if err != nil { - //return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " is not defined") - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Device " + device_name + " is not defined") - } - } - - // Query CNFStatus - resutil := NewResUtil() - -// cobj = &module.DeviceObject{ - // Metadata: module.ObjectMetaData{"local", "", "", ""}, - // Specification: module.DeviceObjectSpec{}} - - res := QueryResource{ - Resource: ReadResource { - Gvk: schema.GroupVersionKind{Group: "batch.sdewan.akraino.org", Version: "v1alpha1", Kind:"CNFStatus"}, - Name: "cnf-status", - Namespace: "sdewan-system", - }} -// res := QueryResource{ -// Resource: ReadResource { -// Gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind:"ConfigMap"}, -// Name: "mycm", -// Namespace: "default", -// }} - resutil.AddQueryResource(cobj, res) - ctx_id, err := resutil.Query("ewo-query-app") - - if err != nil { - log.Println(err) - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to Query CNFs") - } - - // Todo: save ctx_id in DB - log.Println(ctx_id) - // val, err := resutil.GetResourceData(&deviceObject, "default", "mycm") - val, err := resutil.GetResourceData(cobj, "sdewan-system", "cnf-status") - if err != nil { - log.Println(err) - return []module.ControllerObject{}, pkgerrors.Wrap(err, "CNF information is not available") - } - - log.Println(val) - status, err := c.ParseStatus(val) - if err != nil { - log.Println(err) - return []module.ControllerObject{}, pkgerrors.Wrap(err, "CNF information is not available") - } - - return []module.ControllerObject{&module.CNFObject{ - Metadata: module.ObjectMetaData{overlay_name+"."+cluster_name, "cnf informaiton", "", ""}, - Status: status, - }}, nil -} - -func (c *CNFObjectManager) ParseStatus(val string) (string, error) { -/* val = `{"apiVersion":"batch.sdewan.akraino.org/v1alpha1", -"kind":"CNFStatus", -"metadata":{"creationTimestamp":"2021-04-06T04:51:18Z","generation":1,"managedFields":[{"apiVersion":"batch.sdewan.akraino.org/v1alpha1","fieldsType":"FieldsV1","fieldsV1":{"f:spec":{},"f:status":{".":{},"f:appliedGeneration":{},"f:appliedTime":{},"f:information":{}}},"manager":"manager","operation":"Update","time":"2021-05-07T09:42:18Z"}],"name":"cnf-status","namespace":"sdewan-system","resourceVersion":"29161589","uid":"940de684-ca24-4686-9f3f-2bad0c099bc2"}, -"spec":{}, -"status":{"appliedGeneration":1,"appliedTime":"2021-05-28T06:43:48Z","information":[{"ip":"10.233.97.182","name":"sdewan-test-7bb68cd886-b7ntl","namespace":"default","node":"master","purpose":"sdewan-test","status":"Not Available"},{"ip":"10.233.97.155","name":"sdewan-raw-cnf-9fdcd875c-qkvhk","namespace":"default","node":"master","purpose":"sdewan-raw-cnf","status":"Not Available"},{"ip":"10.233.97.158","name":"sdewan-safe-6555988556-fhmvw","namespace":"default","node":"master","purpose":"sdewan-safe","status":"Not Available"},{"ip":"10.233.97.144","name":"sdewan-edge-a-7fb6b8bbf6-lvs5d","namespace":"default","node":"master","purpose":"sdewan-edge-a","status":"Not Available"}]}}` -*/ - var vi interface{} - err := json.Unmarshal([]byte(val), &vi) - if err != nil { - return "", err - } - - status := vi.(map[string]interface{})["status"] - status_val, err := json.Marshal(status) - - //status_val, err := status - if err != nil { - return "", err - } - - log.Println("_____________-----") - log.Println(string(status_val)) - return string(status_val), nil -/* - status := vi.(map[string]interface{})["metadata"].(map[string]interface{})["annotations"].(map[string]interface{})["kubectl.kubernetes.io/last-applied-configuration"] - return status.(string), nil - */ -} - -func (c *CNFObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *CNFObjectManager) DeleteObject(m map[string]string) error { - return pkgerrors.New("Not implemented") -} +/* + * 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 manager + +import ( + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" + + "k8s.io/apimachinery/pkg/runtime/schema" + "log" +) + +type CNFObjectKey struct { + OverlayName string `json:"overlay-name"` + ClusterName string `json:"cluster-name"` + CNFName string `json:"cnf-name"` +} + +// CNFObjectManager implements the ControllerObjectManager +type CNFObjectManager struct { + BaseObjectManager + isHub bool +} + +func NewCNFObjectManager(isHub bool) *CNFObjectManager { + object_meta := "cnf" + if isHub { + object_meta = "hub-" + object_meta + } else { + object_meta = "device-" + object_meta + } + + return &CNFObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: object_meta, + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + isHub, + } +} + +func (c *CNFObjectManager) GetResourceName() string { + return CNFResource +} + +func (c *CNFObjectManager) IsOperationSupported(oper string) bool { + if oper == "GETS" { + return true + } + return false +} + +func (c *CNFObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.CNFObject{} +} + +func (c *CNFObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + cluster_name := "" + if c.isHub { + cluster_name = m[HubResource] + } else { + cluster_name = m[DeviceResource] + } + + key := CNFObjectKey{ + OverlayName: overlay_name, + ClusterName: cluster_name, + CNFName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.CNFObject) + meta_name := to.Metadata.Name + res_name := m[CNFResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.CNFName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.CNFName = meta_name + } + + return key, nil +} + +func (c *CNFObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.CNFObject + err := json.NewDecoder(r).Decode(&v) + + return &v, err +} + +func (c *CNFObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *CNFObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *CNFObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + overlay_name := m[OverlayResource] + var cobj module.ControllerObject + var cluster_name string + var err error + + if c.isHub { + cluster_name = m[HubResource] + hub_name := m[HubResource] + hub_manager := GetManagerset().Hub + cobj, err = hub_manager.GetObject(m) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Hub "+hub_name+" is not defined") + } + } else { + cluster_name = m[DeviceResource] + device_name := m[DeviceResource] + dev_manager := GetManagerset().Device + cobj, err = dev_manager.GetObject(m) + if err != nil { + //return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " is not defined") + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Device "+device_name+" is not defined") + } + } + + // Query CNFStatus + resutil := NewResUtil() + + res := QueryResource{ + Resource: ReadResource{ + Gvk: schema.GroupVersionKind{Group: "batch.sdewan.akraino.org", Version: "v1alpha1", Kind: "CNFStatus"}, + Name: "cnf-status", + Namespace: "sdewan-system", + }, + } + + resutil.AddQueryResource(cobj, res) + ctx_id, err := resutil.Query("ewo-query-app") + + if err != nil { + log.Println(err) + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to Query CNFs") + } + + // Todo: save ctx_id in DB + log.Println(ctx_id) + val, err := resutil.GetResourceData(cobj, "sdewan-system", "cnf-status") + if err != nil { + log.Println(err) + return []module.ControllerObject{}, pkgerrors.Wrap(err, "CNF information is not available") + } + + status, err := c.ParseStatus(val) + if err != nil { + log.Println(err) + return []module.ControllerObject{}, pkgerrors.Wrap(err, "CNF information is not available") + } + + return []module.ControllerObject{&module.CNFObject{ + Metadata: module.ObjectMetaData{overlay_name + "." + cluster_name, "cnf informaiton", "", ""}, + Status: status, + }}, nil +} + +func (c *CNFObjectManager) ParseStatus(val string) (string, error) { + var vi interface{} + err := json.Unmarshal([]byte(val), &vi) + if err != nil { + return "", err + } + + status := vi.(map[string]interface{})["status"] + status_val, err := json.Marshal(status) + + if err != nil { + return "", err + } + + return string(status_val), nil +} + +func (c *CNFObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *CNFObjectManager) DeleteObject(m map[string]string) error { + return pkgerrors.New("Not implemented") +} diff --git a/central-controller/src/scc/pkg/manager/connection_manager.go b/central-controller/src/scc/pkg/manager/connection_manager.go index 82b788c..cfccc4b 100644 --- a/central-controller/src/scc/pkg/manager/connection_manager.go +++ b/central-controller/src/scc/pkg/manager/connection_manager.go @@ -1,255 +1,254 @@ -/* - * 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 manager - -import ( - "log" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" - pkgerrors "github.com/pkg/errors" -) - -type ConnectionManager struct { - storeName string - tagMeta string -} - -type ConnectionKey struct { - OverlayName string `json:"overlay-name"` - End1 string `json:"end1-name"` - End2 string `json:"end2-name"` -} - -var connutil = ConnectionManager{ - storeName: StoreName, - tagMeta: "connection", - } - -func GetConnectionManager() *ConnectionManager { - return &connutil -} - -func (c *ConnectionManager) CreateEmptyObject() module.ControllerObject { - return &module.ConnectionObject{} -} - -func (c *ConnectionManager) GetStoreName() string { - return c.storeName -} - -func (c *ConnectionManager) GetStoreMeta() string { - return c.tagMeta -} - - -func (c *ConnectionManager) Deploy(overlay string, cm module.ConnectionObject) error { - resutil := NewResUtil() - - // add resource for End1 - co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject) - for _, r_str := range cm.Info.End1.Resources { - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutil.AddResource(co1, "create", r) - } - for _, r_str := range cm.Info.End1.ReservedRes { - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutil.AddResource(co1, "create", r) - } - - // add resource for End2 - co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject) - for _, r_str := range cm.Info.End2.Resources { - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutil.AddResource(co2, "create", r) - } - for _, r_str := range cm.Info.End2.ReservedRes { - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutil.AddResource(co2, "create", r) - } - - // Deploy resources - cid, err := resutil.Deploy(cm.Metadata.Name, "YAML") - if cm.Info.ContextId == "" { - cm.Info.ContextId = cid - } else { - cm.Info.ContextId = cm.Info.ContextId + "," + cid - } - - if err != nil { - log.Println(err) - cm.Info.State = module.StateEnum.Error - cm.Info.ErrorMessage = err.Error() - } else { - cm.Info.State = module.StateEnum.Deployed - } - - // Save to DB - _, err = c.UpdateObject(overlay, cm) - - return err -} - -func (c *ConnectionManager) Undeploy(overlay string, cm module.ConnectionObject) error { - resutil := NewResUtil() - - // add resource for End1 (reservedRes will be kept) - co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject) - for _, r_str := range cm.Info.End1.Resources { - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutil.AddResource(co1, "create", r) - } - - // add resource for End2 (reservedRes will be kept) - co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject) - for _, r_str := range cm.Info.End2.Resources { - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutil.AddResource(co2, "create", r) - } - - // Undeploy resources - cid, err := resutil.Undeploy(cm.Metadata.Name, "YAML") - if cm.Info.ContextId == "" { - cm.Info.ContextId = cid - } else { - cm.Info.ContextId = cm.Info.ContextId + "," + cid - } - - if err != nil { - log.Println(err) - cm.Info.State = module.StateEnum.Error - cm.Info.ErrorMessage = err.Error() - } else { - cm.Info.State = module.StateEnum.Undeployed - } - - // Delete connection object - err = c.DeleteObject(overlay, cm.Info.End1.Name, cm.Info.End2.Name) - - return err -} - -func (c *ConnectionManager) UpdateObject(overlay string, cm module.ConnectionObject) (module.ControllerObject, error) { - key := ConnectionKey{ - OverlayName: overlay, - End1: cm.Info.End1.Name, - End2: cm.Info.End2.Name, - } - - err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), cm) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unable to create the object") - } - return &cm, err -} - -func (c *ConnectionManager) GetObject(overlay string, key1 string, key2 string) (module.ControllerObject, error) { - key := ConnectionKey{ - OverlayName: overlay, - End1: key1, - End2: key2, - } - value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) - if err != nil { - return c.CreateEmptyObject(), err - } - - if value == nil { - key = ConnectionKey{ - OverlayName: overlay, - End1: key2, - End2: key1, - } - value, err = db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) - if err != nil { - return c.CreateEmptyObject(), err - } - } - - if value != nil { - r := c.CreateEmptyObject() - err = db.DBconn.Unmarshal(value[0], r) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value") - } - return r, nil - } - - return c.CreateEmptyObject(), pkgerrors.New("No Object") -} - -func (c *ConnectionManager) GetObjects(overlay string, key string) ([]module.ControllerObject, error) { - key1 := ConnectionKey{ - OverlayName: overlay, - End1: key, - End2: "", - } - key2 := ConnectionKey{ - OverlayName: overlay, - End1: "", - End2: key, - } - - var resp []module.ControllerObject - - // find objects with end1=key - values, err := db.DBconn.Find(c.GetStoreName(), key1, c.GetStoreMeta()) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects") - } - - for _, value := range values { - t := c.CreateEmptyObject() - err = db.DBconn.Unmarshal(value, t) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values") - } - resp = append(resp, t) - } - - // find objects with end2=key - values, err = db.DBconn.Find(c.GetStoreName(), key2, c.GetStoreMeta()) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects") - } - - for _, value := range values { - t := c.CreateEmptyObject() - err = db.DBconn.Unmarshal(value, t) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values") - } - resp = append(resp, t) - } - - return resp, nil -} - -func (c *ConnectionManager) DeleteObject(overlay string, key1 string, key2 string) error { - key := ConnectionKey{ - OverlayName: overlay, - End1: key1, - End2: key2, - } - - err := db.DBconn.Remove(c.GetStoreName(), key) - if err != nil { - return pkgerrors.Wrap(err, "Delete Object") - } - - return err -} +/* + * 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 manager + +import ( + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "log" +) + +type ConnectionManager struct { + storeName string + tagMeta string +} + +type ConnectionKey struct { + OverlayName string `json:"overlay-name"` + End1 string `json:"end1-name"` + End2 string `json:"end2-name"` +} + +var connutil = ConnectionManager{ + storeName: StoreName, + tagMeta: "connection", +} + +func GetConnectionManager() *ConnectionManager { + return &connutil +} + +func (c *ConnectionManager) CreateEmptyObject() module.ControllerObject { + return &module.ConnectionObject{} +} + +func (c *ConnectionManager) GetStoreName() string { + return c.storeName +} + +func (c *ConnectionManager) GetStoreMeta() string { + return c.tagMeta +} + +func (c *ConnectionManager) Deploy(overlay string, cm module.ConnectionObject) error { + resutil := NewResUtil() + + // add resource for End1 + co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject) + for _, r_str := range cm.Info.End1.Resources { + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutil.AddResource(co1, "create", r) + } + for _, r_str := range cm.Info.End1.ReservedRes { + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutil.AddResource(co1, "create", r) + } + + // add resource for End2 + co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject) + for _, r_str := range cm.Info.End2.Resources { + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutil.AddResource(co2, "create", r) + } + for _, r_str := range cm.Info.End2.ReservedRes { + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutil.AddResource(co2, "create", r) + } + + // Deploy resources + cid, err := resutil.Deploy(cm.Metadata.Name, "YAML") + if cm.Info.ContextId == "" { + cm.Info.ContextId = cid + } else { + cm.Info.ContextId = cm.Info.ContextId + "," + cid + } + + if err != nil { + log.Println(err) + cm.Info.State = module.StateEnum.Error + cm.Info.ErrorMessage = err.Error() + } else { + cm.Info.State = module.StateEnum.Deployed + } + + // Save to DB + _, err = c.UpdateObject(overlay, cm) + + return err +} + +func (c *ConnectionManager) Undeploy(overlay string, cm module.ConnectionObject) error { + resutil := NewResUtil() + + // add resource for End1 (reservedRes will be kept) + co1, _ := module.GetObjectBuilder().ToObject(cm.Info.End1.ConnObject) + for _, r_str := range cm.Info.End1.Resources { + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutil.AddResource(co1, "create", r) + } + + // add resource for End2 (reservedRes will be kept) + co2, _ := module.GetObjectBuilder().ToObject(cm.Info.End2.ConnObject) + for _, r_str := range cm.Info.End2.Resources { + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutil.AddResource(co2, "create", r) + } + + // Undeploy resources + cid, err := resutil.Undeploy(cm.Metadata.Name, "YAML") + if cm.Info.ContextId == "" { + cm.Info.ContextId = cid + } else { + cm.Info.ContextId = cm.Info.ContextId + "," + cid + } + + if err != nil { + log.Println(err) + cm.Info.State = module.StateEnum.Error + cm.Info.ErrorMessage = err.Error() + } else { + cm.Info.State = module.StateEnum.Undeployed + } + + // Delete connection object + err = c.DeleteObject(overlay, cm.Info.End1.Name, cm.Info.End2.Name) + + return err +} + +func (c *ConnectionManager) UpdateObject(overlay string, cm module.ConnectionObject) (module.ControllerObject, error) { + key := ConnectionKey{ + OverlayName: overlay, + End1: cm.Info.End1.Name, + End2: cm.Info.End2.Name, + } + + err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), cm) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unable to create the object") + } + return &cm, err +} + +func (c *ConnectionManager) GetObject(overlay string, key1 string, key2 string) (module.ControllerObject, error) { + key := ConnectionKey{ + OverlayName: overlay, + End1: key1, + End2: key2, + } + value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) + if err != nil { + return c.CreateEmptyObject(), err + } + + if value == nil { + key = ConnectionKey{ + OverlayName: overlay, + End1: key2, + End2: key1, + } + value, err = db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) + if err != nil { + return c.CreateEmptyObject(), err + } + } + + if value != nil { + r := c.CreateEmptyObject() + err = db.DBconn.Unmarshal(value[0], r) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value") + } + return r, nil + } + + return c.CreateEmptyObject(), pkgerrors.New("No Object") +} + +func (c *ConnectionManager) GetObjects(overlay string, key string) ([]module.ControllerObject, error) { + key1 := ConnectionKey{ + OverlayName: overlay, + End1: key, + End2: "", + } + key2 := ConnectionKey{ + OverlayName: overlay, + End1: "", + End2: key, + } + + var resp []module.ControllerObject + + // find objects with end1=key + values, err := db.DBconn.Find(c.GetStoreName(), key1, c.GetStoreMeta()) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects") + } + + for _, value := range values { + t := c.CreateEmptyObject() + err = db.DBconn.Unmarshal(value, t) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values") + } + resp = append(resp, t) + } + + // find objects with end2=key + values, err = db.DBconn.Find(c.GetStoreName(), key2, c.GetStoreMeta()) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects") + } + + for _, value := range values { + t := c.CreateEmptyObject() + err = db.DBconn.Unmarshal(value, t) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values") + } + resp = append(resp, t) + } + + return resp, nil +} + +func (c *ConnectionManager) DeleteObject(overlay string, key1 string, key2 string) error { + key := ConnectionKey{ + OverlayName: overlay, + End1: key1, + End2: key2, + } + + err := db.DBconn.Remove(c.GetStoreName(), key) + if err != nil { + return pkgerrors.Wrap(err, "Delete Object") + } + + return err +} diff --git a/central-controller/src/scc/pkg/manager/constants.go b/central-controller/src/scc/pkg/manager/constants.go index 9c65b4b..230fc72 100644 --- a/central-controller/src/scc/pkg/manager/constants.go +++ b/central-controller/src/scc/pkg/manager/constants.go @@ -1,42 +1,42 @@ -/* - * 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 manager - -const ( - NameSpaceName = "sdewan-system" - RootIssuerName = "sdewan-controller" - RootCAIssuerName = "sdewan-controller-ca" - RootCertName = "sdewan-controller" - SCCCertName = "sdewan-controller-base" - StoreName = "centralcontroller" - OverlayCollection = "overlays" - OverlayResource = "overlay-name" - ProposalCollection = "proposals" - ProposalResource = "proposal-name" - HubCollection = "hubs" - HubResource = "hub-name" - ConnectionCollection = "connections" - ConnectionResource = "connection-name" - CNFCollection = "cnfs" - CNFResource = "cnf-name" - DeviceCollection = "devices" - DeviceResource = "device-name" - IPRangeCollection = "ipranges" - IPRangeResource = "iprange-name" - CertCollection = "certificates" - CertResource = "certificate-name" -) \ No newline at end of file +/* + * 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 manager + +const ( + NameSpaceName = "sdewan-system" + RootIssuerName = "sdewan-controller" + RootCAIssuerName = "sdewan-controller-ca" + RootCertName = "sdewan-controller" + SCCCertName = "sdewan-controller-base" + StoreName = "centralcontroller" + OverlayCollection = "overlays" + OverlayResource = "overlay-name" + ProposalCollection = "proposals" + ProposalResource = "proposal-name" + HubCollection = "hubs" + HubResource = "hub-name" + ConnectionCollection = "connections" + ConnectionResource = "connection-name" + CNFCollection = "cnfs" + CNFResource = "cnf-name" + DeviceCollection = "devices" + DeviceResource = "device-name" + IPRangeCollection = "ipranges" + IPRangeResource = "iprange-name" + CertCollection = "certificates" + CertResource = "certificate-name" +) diff --git a/central-controller/src/scc/pkg/manager/controller_objectmanager.go b/central-controller/src/scc/pkg/manager/controller_objectmanager.go index 47ef43b..5802ab2 100644 --- a/central-controller/src/scc/pkg/manager/controller_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/controller_objectmanager.go @@ -1,75 +1,75 @@ -/* - * 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 manager - -import ( - "io" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" -) - -// ControllerManager is an interface exposes the ControllerObject functionality -type ControllerObjectManager interface { - GetStoreName() string - GetStoreMeta() string - GetDepResManagers() []ControllerObjectManager - AddDepResManager(mgr ControllerObjectManager) - GetOwnResManagers() []ControllerObjectManager - AddOwnResManager(mgr ControllerObjectManager) - - GetResourceName() string - IsOperationSupported(oper string) bool - GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) - CreateEmptyObject() module.ControllerObject - ParseObject(r io.Reader) (module.ControllerObject, error) - CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) - GetObject(m map[string]string) (module.ControllerObject, error) - GetObjects(m map[string]string) ([]module.ControllerObject, error) - UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) - DeleteObject(m map[string]string) error -} - -type BaseObjectManager struct { - storeName string - tagMeta string - depResManagers []ControllerObjectManager - ownResManagers []ControllerObjectManager -} - -func (c *BaseObjectManager) GetStoreName() string { - return c.storeName -} - -func (c *BaseObjectManager) GetStoreMeta() string { - return c.tagMeta -} - -func (c *BaseObjectManager) GetDepResManagers() []ControllerObjectManager { - return c.depResManagers -} - -func (c *BaseObjectManager) AddDepResManager(mgr ControllerObjectManager) { - c.depResManagers = append(c.depResManagers, mgr) -} - -func (c *BaseObjectManager) GetOwnResManagers() []ControllerObjectManager { - return c.ownResManagers -} - -func (c *BaseObjectManager) AddOwnResManager(mgr ControllerObjectManager) { - c.ownResManagers = append(c.ownResManagers, mgr) -} \ No newline at end of file +/* + * 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 manager + +import ( + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + "io" +) + +// ControllerManager is an interface exposes the ControllerObject functionality +type ControllerObjectManager interface { + GetStoreName() string + GetStoreMeta() string + GetDepResManagers() []ControllerObjectManager + AddDepResManager(mgr ControllerObjectManager) + GetOwnResManagers() []ControllerObjectManager + AddOwnResManager(mgr ControllerObjectManager) + + GetResourceName() string + IsOperationSupported(oper string) bool + GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) + CreateEmptyObject() module.ControllerObject + ParseObject(r io.Reader) (module.ControllerObject, error) + CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) + GetObject(m map[string]string) (module.ControllerObject, error) + GetObjects(m map[string]string) ([]module.ControllerObject, error) + UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) + DeleteObject(m map[string]string) error +} + +type BaseObjectManager struct { + storeName string + tagMeta string + depResManagers []ControllerObjectManager + ownResManagers []ControllerObjectManager +} + +func (c *BaseObjectManager) GetStoreName() string { + return c.storeName +} + +func (c *BaseObjectManager) GetStoreMeta() string { + return c.tagMeta +} + +func (c *BaseObjectManager) GetDepResManagers() []ControllerObjectManager { + return c.depResManagers +} + +func (c *BaseObjectManager) AddDepResManager(mgr ControllerObjectManager) { + c.depResManagers = append(c.depResManagers, mgr) +} + +func (c *BaseObjectManager) GetOwnResManagers() []ControllerObjectManager { + return c.ownResManagers +} + +func (c *BaseObjectManager) AddOwnResManager(mgr ControllerObjectManager) { + c.ownResManagers = append(c.ownResManagers, mgr) +} diff --git a/central-controller/src/scc/pkg/manager/dbutils.go b/central-controller/src/scc/pkg/manager/dbutils.go index 005c130..6e1c008 100644 --- a/central-controller/src/scc/pkg/manager/dbutils.go +++ b/central-controller/src/scc/pkg/manager/dbutils.go @@ -1,198 +1,191 @@ -/* - * 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 manager - -import ( - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - rsync "github.com/open-ness/EMCO/src/rsync/pkg/db" - pkgerrors "github.com/pkg/errors" - mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types" -) - -const PROVIDERNAME = "akraino_scc" - -type Cluster struct { - Metadata mtypes.Metadata `json:"metadata"` -} - -type ClusterContent struct { - Kubeconfig string `json:"kubeconfig"` -} - -type ClusterKey struct { - ClusterProviderName string `json:"provider"` - ClusterName string `json:"cluster"` -} - -type DBUtils struct { -} - -var dbutils = DBUtils{} - -func GetDBUtils() *DBUtils { - return &dbutils -} - -func (d *DBUtils) CheckDep(c ControllerObjectManager, m map[string]string) error { - depsResManagers := c.GetDepResManagers() - for _, mgr := range depsResManagers { - _, err := d.GetObject(mgr, m) - if err != nil { - return pkgerrors.New("Fail to find " + mgr.GetStoreMeta()) - } - } - - return nil -} - -func (d *DBUtils) CheckOwn(c ControllerObjectManager, m map[string]string) error { - depsOwnManagers := c.GetOwnResManagers() - for _, mgr := range depsOwnManagers { - objs, err := d.GetObjects(mgr, m) - if err == nil && len(objs) > 0 { - return pkgerrors.New("Sub-resource found : " + mgr.GetStoreMeta()) - } - } - return nil -} - - -func (d *DBUtils) CreateObject(c ControllerObjectManager, m map[string]string, - t module.ControllerObject) (module.ControllerObject, error) { - - key, _ := c.GetStoreKey(m, t, false) - err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.New("Unable to create the object") - } - - return t, nil -} - -func (d *DBUtils) GetObject(c ControllerObjectManager, - m map[string]string) (module.ControllerObject, error) { - - key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false) - if err != nil { - return c.CreateEmptyObject(), err - } - - - value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Get Resource") - } - - - if value != nil { - r := c.CreateEmptyObject() - err = db.DBconn.Unmarshal(value[0], r) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value") - } - return r, nil - } - - return c.CreateEmptyObject(), pkgerrors.New("No Object") -} - -func (d *DBUtils) GetObjects(c ControllerObjectManager, - m map[string]string) ([]module.ControllerObject, error) { - - - key, err := c.GetStoreKey(m, c.CreateEmptyObject(), true) - if err != nil { - return []module.ControllerObject{}, err - } - - - values, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects") - } - - - var resp []module.ControllerObject - for _, value := range values { - t := c.CreateEmptyObject() - err = db.DBconn.Unmarshal(value, t) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values") - } - resp = append(resp, t) - } - - return resp, nil -} - -func (d *DBUtils) UpdateObject(c ControllerObjectManager, - m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - - key, err := c.GetStoreKey(m, t, false) - if err != nil { - return c.CreateEmptyObject(), err - } - - err = db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Updating DB Entry") - } - return t, nil -} - -func (d *DBUtils) DeleteObject(c ControllerObjectManager, m map[string]string) error { - key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false) - if err != nil { - return err - } - - err = db.DBconn.Remove(c.GetStoreName(), key) - if err != nil { - return pkgerrors.Wrap(err, "Delete Object") - } - - return nil -} - -func (d *DBUtils) RegisterDevice(cluster_name string, kubeconfig string) error { - ccc := rsync.NewCloudConfigClient() - - config, _ := ccc.GetCloudConfig(PROVIDERNAME, cluster_name, "0", "default") - if config.Config != "" { - ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "default") - } - - _, err := ccc.CreateCloudConfig(PROVIDERNAME, cluster_name, "0", "default", kubeconfig) - if err != nil { - return pkgerrors.Wrap(err, "Error creating cloud config") - } - - return nil -} - -func (d *DBUtils) UnregisterDevice(cluster_name string) error { - ccc := rsync.NewCloudConfigClient() - - err := ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "default") - if err != nil { - return pkgerrors.Wrap(err, "Error deleting cloud config") - } - - return nil -} - +/* + * 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 manager + +import ( + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types" + rsync "github.com/open-ness/EMCO/src/rsync/pkg/db" + pkgerrors "github.com/pkg/errors" +) + +const PROVIDERNAME = "akraino_scc" + +type Cluster struct { + Metadata mtypes.Metadata `json:"metadata"` +} + +type ClusterContent struct { + Kubeconfig string `json:"kubeconfig"` +} + +type ClusterKey struct { + ClusterProviderName string `json:"provider"` + ClusterName string `json:"cluster"` +} + +type DBUtils struct { +} + +var dbutils = DBUtils{} + +func GetDBUtils() *DBUtils { + return &dbutils +} + +func (d *DBUtils) CheckDep(c ControllerObjectManager, m map[string]string) error { + depsResManagers := c.GetDepResManagers() + for _, mgr := range depsResManagers { + _, err := d.GetObject(mgr, m) + if err != nil { + return pkgerrors.New("Fail to find " + mgr.GetStoreMeta()) + } + } + + return nil +} + +func (d *DBUtils) CheckOwn(c ControllerObjectManager, m map[string]string) error { + depsOwnManagers := c.GetOwnResManagers() + for _, mgr := range depsOwnManagers { + objs, err := d.GetObjects(mgr, m) + if err == nil && len(objs) > 0 { + return pkgerrors.New("Sub-resource found : " + mgr.GetStoreMeta()) + } + } + return nil +} + +func (d *DBUtils) CreateObject(c ControllerObjectManager, m map[string]string, + t module.ControllerObject) (module.ControllerObject, error) { + + key, _ := c.GetStoreKey(m, t, false) + err := db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.New("Unable to create the object") + } + + return t, nil +} + +func (d *DBUtils) GetObject(c ControllerObjectManager, + m map[string]string) (module.ControllerObject, error) { + + key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false) + if err != nil { + return c.CreateEmptyObject(), err + } + + value, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Get Resource") + } + + if value != nil { + r := c.CreateEmptyObject() + err = db.DBconn.Unmarshal(value[0], r) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Unmarshaling value") + } + return r, nil + } + + return c.CreateEmptyObject(), pkgerrors.New("No Object") +} + +func (d *DBUtils) GetObjects(c ControllerObjectManager, + m map[string]string) ([]module.ControllerObject, error) { + + key, err := c.GetStoreKey(m, c.CreateEmptyObject(), true) + if err != nil { + return []module.ControllerObject{}, err + } + + values, err := db.DBconn.Find(c.GetStoreName(), key, c.GetStoreMeta()) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Get Overlay Objects") + } + + var resp []module.ControllerObject + for _, value := range values { + t := c.CreateEmptyObject() + err = db.DBconn.Unmarshal(value, t) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Unmarshaling values") + } + resp = append(resp, t) + } + + return resp, nil +} + +func (d *DBUtils) UpdateObject(c ControllerObjectManager, + m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + + key, err := c.GetStoreKey(m, t, false) + if err != nil { + return c.CreateEmptyObject(), err + } + + err = db.DBconn.Insert(c.GetStoreName(), key, nil, c.GetStoreMeta(), t) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Updating DB Entry") + } + return t, nil +} + +func (d *DBUtils) DeleteObject(c ControllerObjectManager, m map[string]string) error { + key, err := c.GetStoreKey(m, c.CreateEmptyObject(), false) + if err != nil { + return err + } + + err = db.DBconn.Remove(c.GetStoreName(), key) + if err != nil { + return pkgerrors.Wrap(err, "Delete Object") + } + + return nil +} + +func (d *DBUtils) RegisterDevice(cluster_name string, kubeconfig string) error { + ccc := rsync.NewCloudConfigClient() + + config, _ := ccc.GetCloudConfig(PROVIDERNAME, cluster_name, "0", "default") + if config.Config != "" { + ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "default") + } + + _, err := ccc.CreateCloudConfig(PROVIDERNAME, cluster_name, "0", "default", kubeconfig) + if err != nil { + return pkgerrors.Wrap(err, "Error creating cloud config") + } + + return nil +} + +func (d *DBUtils) UnregisterDevice(cluster_name string) error { + ccc := rsync.NewCloudConfigClient() + + err := ccc.DeleteCloudConfig(PROVIDERNAME, cluster_name, "0", "default") + if err != nil { + return pkgerrors.Wrap(err, "Error deleting cloud config") + } + + return nil +} diff --git a/central-controller/src/scc/pkg/manager/device_objectmanager.go b/central-controller/src/scc/pkg/manager/device_objectmanager.go index 3a043e5..8587a7e 100644 --- a/central-controller/src/scc/pkg/manager/device_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/device_objectmanager.go @@ -1,398 +1,396 @@ -/* -* 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 manager - -import ( - "io" - "log" - //"strconv" - "encoding/json" - "encoding/base64" - "strings" - "time" - "github.com/matryer/runner" - - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - //"github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" - pkgerrors "github.com/pkg/errors" -) - -const SCC_RESOURCE = "scc_ipsec_resource" -const RegStatus = "RegStatus" - -var ips []string -var task *runner.Task - -type DeviceObjectKey struct { - OverlayName string `json:"overlay-name"` - DeviceName string `json:"device-name"` -} - -// DeviceObjectManager implements the ControllerObjectManager -type DeviceObjectManager struct { - BaseObjectManager -} - -func NewDeviceObjectManager() *DeviceObjectManager { - return &DeviceObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "device", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *DeviceObjectManager) GetResourceName() string { - return DeviceResource -} - -func (c *DeviceObjectManager) IsOperationSupported(oper string) bool { - return true -} - -func (c *DeviceObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.DeviceObject{} -} - -func (c *DeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - key := DeviceObjectKey{ - OverlayName: overlay_name, - DeviceName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.DeviceObject) - meta_name := to.Metadata.Name - res_name := m[DeviceResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.DeviceName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.DeviceName = meta_name - } - - return key, nil; -} - -func (c *DeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.DeviceObject - err := json.NewDecoder(r).Decode(&v) - - // initial Status - v.Status.Data = make(map[string]string) - return &v, err -} - -func (c *DeviceObjectManager) PreProcessing(m map[string]string, t module.ControllerObject) error { - to := t.(*module.DeviceObject) - - ipr_manager := GetManagerset().IPRange - kubeutil := GetKubeConfigUtil() - - local_public_ips := to.Specification.PublicIps - kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig) - if err != nil { - return pkgerrors.Wrap(err, "Fail to decode kubeconfig") - } - - // Set the Register status to pending - to.Status.Data[RegStatus] = "pending" - - if len(local_public_ips) > 0{ - // Use public IP as external connection - to.Status.Mode = 1 - - kube_config, local_public_ip, err := kubeutil.checkKubeConfigAvail(kube_config, local_public_ips, "6443") - if err != nil { - return pkgerrors.Wrap(err, "Fail to verify public ip") - } - - // Set IP in device - log.Println("Use public ip " + local_public_ip) - to.Status.Ip = local_public_ip - - // Set new kubeconfig in device - to.Specification.KubeConfig = base64.StdEncoding.EncodeToString([]byte(kube_config)) - } else { - // Use scc as external connection - to.Status.Mode = 2 - - // allocate OIP for device - overlay_name := m[OverlayResource] - oip, err := ipr_manager.Allocate(overlay_name, to.Metadata.Name) - if err != nil { - return pkgerrors.Wrap(err, "Fail to allocate overlay ip for " + to.Metadata.Name) - } - - // Set OIP in Device - log.Println("Using overlay ip " + oip) - to.Status.Ip = oip - - // Get all proposal resources - proposal := GetManagerset().Proposal - proposals, err := proposal.GetObjects(m) - if len(proposals) == 0 || err != nil { - log.Println("Missing Proposal in the overlay\n") - return pkgerrors.New("Error in getting proposals") - } - - var all_proposal []string - var proposalresource []*resource.ProposalResource - for i:= 0 ; i < len(proposals); i++ { - proposal_obj := proposals[i].(*module.ProposalObject) - all_proposal = append(all_proposal, proposal_obj.Metadata.Name) - pr := proposal_obj.ToResource() - proposalresource = append(proposalresource, pr) - } - - //Extract SCC cert/key - cu, err := GetCertUtil() - if err != nil { - log.Println("Getting certutil error") - } - crts, key, err := cu.GetKeypair(SCCCertName, NameSpaceName) - crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] - - root_ca := GetRootCA(overlay_name) - - // Build up ipsec resource - scc_conn := resource.Connection{ - Name: DEFAULT_CONN, - ConnectionType: CONN_TYPE, - Mode: MODE, - Mark: DEFAULT_MARK, - RemoteSourceIp: oip, - LocalUpDown: DEFAULT_UPDOWN, - CryptoProposal: all_proposal, - } - - scc_ipsec_resource := resource.IpsecResource{ - Name: "localto" + format_resource_name(to.Metadata.Name, ""), - Type: VTI_MODE, - Remote: ANY, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: base64.StdEncoding.EncodeToString([]byte(crt)), - PrivateCert: base64.StdEncoding.EncodeToString([]byte(key)), - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+ SCCCertName, - RemoteIdentifier: "CN=" + to.GetCertName(), - CryptoProposal: all_proposal, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: scc_conn, - } - - scc := module.EmptyObject{ - Metadata: module.ObjectMetaData{"local", "", "", ""}} - - // Add and deploy resource - resutil := NewResUtil() - resutil.AddResource(&scc, "create", &scc_ipsec_resource) - for i :=0; i < len(proposalresource); i++ { - resutil.AddResource(&scc, "create", proposalresource[i]) - } - - resutil.Deploy("localto" + to.Metadata.Name, "YAML") - - //Reserve ipsec resource to device object - res_str, err := resource.GetResourceBuilder().ToString(&scc_ipsec_resource) - to.Status.Data[SCC_RESOURCE] = res_str - - ips = append(ips, oip) - - } - return nil - -} - -func (c *DeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - err := c.PreProcessing(m, t) - if err != nil { - return c.CreateEmptyObject(), err - } - - to := t.(*module.DeviceObject) - task = runner.Go(func(ShouldStop runner.S) error { - for to.Status.Data[RegStatus] != "success" { - err = c.PostRegister(m, t) - if err != nil { - log.Println(err) - } - time.Sleep(5 * time.Second) - if ShouldStop() { - break - } - } - return nil - }) - - // DB Operation - t, err = GetDBUtils().CreateObject(c, m, t) - return t, err -} - -func (c *DeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObject(c, m) - - return t, err -} - -func (c *DeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObjects(c, m) - - return t, err -} - -func (c *DeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().UpdateObject(c, m, t) - - return t, err -} - -func (c *DeviceObjectManager) DeleteObject(m map[string]string) error { - t, err := c.GetObject(m) - if err != nil { - return nil - } - - if ( task != nil && task.Running() ) { - task.Stop() - select { - case <-task.StopChan(): - case <-time.After(2 * time.Second): - log.Println("Goroutine register device stopped") - } - } - - //overlay_manager := GetManagerset().Overlay - ipr_manager := GetManagerset().IPRange - - overlay_name := m[OverlayResource] - device_name := m[DeviceResource] - - to := t.(*module.DeviceObject) - - //If the device is in mode 2: - // * Free OIP assigned - // * Remove ipsec configuration on SCC - if to.Status.Mode == 2 { - // Free OIP - ipr_manager.Free(overlay_name, to.Status.Ip) - - scc := module.EmptyObject{ - Metadata: module.ObjectMetaData{"local", "", "", ""}} - - resutils := NewResUtil() - r_str := to.Status.Data["scc_ipsec_resource"] - r, _ := resource.GetResourceBuilder().ToObject(r_str) - resutils.AddResource(&scc, "create", r) - resutils.Undeploy("localto" + device_name, "YAML") - } - - - // DB Operation - err = GetDBUtils().DeleteObject(c, m) - - return err -} - -func GetDeviceCertificate(overlay_name string, device_name string)(string, string, error){ - cert := GetManagerset().Cert - _, crts, key, err := cert.GetOrCreateDC(overlay_name, device_name) - if err != nil { - log.Println("Error in getting cert for device ...") - return "", "", err - } - - crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] - return crt, key, nil -} - -func (c *DeviceObjectManager) PostRegister(m map[string]string, t module.ControllerObject) error { - - overlay_manager := GetManagerset().Overlay - - to := t.(*module.DeviceObject) - log.Println("Registering device " + to.Metadata.Name + " ... ") - - - if to.Status.Mode == 2 { - kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig) - if err != nil { - to.Status.Data[RegStatus] = "failed" - } - - kube_config, _, err = kubeutil.checkKubeConfigAvail(kube_config, ips, DEFAULT_K8S_API_SERVER_PORT) - if err != nil { - //TODO: check the error type, and if is unauthorized then switch the status to failed. - return err - } - - to.Status.Data[RegStatus] = "success" - to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(kube_config) - err = GetDBUtils().RegisterDevice(to.Metadata.Name, to.Specification.KubeConfig) - if err != nil { - log.Println(err) - return err - } - log.Println("scc connection is verified.") - - } else { - to.Status.Data[RegStatus] = "success" - } - - if to.Status.Data[RegStatus] == "success" { - devices, err := c.GetObjects(m) - if err != nil { - log.Println(err) - return err - } - - //TODO: Need to add funcs to re-create connections if some of the connections are not ready - //Maybe because of cert not ready or other reasons. - for i := 0; i < len(devices); i++ { - dev := devices[i].(*module.DeviceObject) - if to.Status.Mode == 1 || dev.Status.Mode == 1 { - err = overlay_manager.SetupConnection(m, to, dev, DEVICETODEVICE, NameSpaceName) - if err != nil { - return err - } - } - } - } - - c.UpdateObject(m, t) - return nil -} +/* +* 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 manager + +import ( + "io" + "log" + //"strconv" + "encoding/base64" + "encoding/json" + "github.com/matryer/runner" + "strings" + "time" + + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + //"github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" + pkgerrors "github.com/pkg/errors" +) + +const SCC_RESOURCE = "scc_ipsec_resource" +const RegStatus = "RegStatus" + +var ips []string +var task *runner.Task + +type DeviceObjectKey struct { + OverlayName string `json:"overlay-name"` + DeviceName string `json:"device-name"` +} + +// DeviceObjectManager implements the ControllerObjectManager +type DeviceObjectManager struct { + BaseObjectManager +} + +func NewDeviceObjectManager() *DeviceObjectManager { + return &DeviceObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "device", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *DeviceObjectManager) GetResourceName() string { + return DeviceResource +} + +func (c *DeviceObjectManager) IsOperationSupported(oper string) bool { + return true +} + +func (c *DeviceObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.DeviceObject{} +} + +func (c *DeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + key := DeviceObjectKey{ + OverlayName: overlay_name, + DeviceName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.DeviceObject) + meta_name := to.Metadata.Name + res_name := m[DeviceResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.DeviceName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.DeviceName = meta_name + } + + return key, nil +} + +func (c *DeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.DeviceObject + err := json.NewDecoder(r).Decode(&v) + + // initial Status + v.Status.Data = make(map[string]string) + return &v, err +} + +func (c *DeviceObjectManager) PreProcessing(m map[string]string, t module.ControllerObject) error { + to := t.(*module.DeviceObject) + + ipr_manager := GetManagerset().IPRange + kubeutil := GetKubeConfigUtil() + + local_public_ips := to.Specification.PublicIps + kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig) + if err != nil { + return pkgerrors.Wrap(err, "Fail to decode kubeconfig") + } + + // Set the Register status to pending + to.Status.Data[RegStatus] = "pending" + + if len(local_public_ips) > 0 { + // Use public IP as external connection + to.Status.Mode = 1 + + kube_config, local_public_ip, err := kubeutil.checkKubeConfigAvail(kube_config, local_public_ips, "6443") + if err != nil { + return pkgerrors.Wrap(err, "Fail to verify public ip") + } + + // Set IP in device + log.Println("Use public ip " + local_public_ip) + to.Status.Ip = local_public_ip + + // Set new kubeconfig in device + to.Specification.KubeConfig = base64.StdEncoding.EncodeToString([]byte(kube_config)) + } else { + // Use scc as external connection + to.Status.Mode = 2 + + // allocate OIP for device + overlay_name := m[OverlayResource] + oip, err := ipr_manager.Allocate(overlay_name, to.Metadata.Name) + if err != nil { + return pkgerrors.Wrap(err, "Fail to allocate overlay ip for "+to.Metadata.Name) + } + + // Set OIP in Device + log.Println("Using overlay ip " + oip) + to.Status.Ip = oip + + // Get all proposal resources + proposal := GetManagerset().Proposal + proposals, err := proposal.GetObjects(m) + if len(proposals) == 0 || err != nil { + log.Println("Missing Proposal in the overlay\n") + return pkgerrors.New("Error in getting proposals") + } + + var all_proposal []string + var proposalresource []*resource.ProposalResource + for i := 0; i < len(proposals); i++ { + proposal_obj := proposals[i].(*module.ProposalObject) + all_proposal = append(all_proposal, proposal_obj.Metadata.Name) + pr := proposal_obj.ToResource() + proposalresource = append(proposalresource, pr) + } + + //Extract SCC cert/key + cu, err := GetCertUtil() + if err != nil { + log.Println("Getting certutil error") + } + crts, key, err := cu.GetKeypair(SCCCertName, NameSpaceName) + crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] + + root_ca := GetRootCA(overlay_name) + + // Build up ipsec resource + scc_conn := resource.Connection{ + Name: DEFAULT_CONN, + ConnectionType: CONN_TYPE, + Mode: MODE, + Mark: DEFAULT_MARK, + RemoteSourceIp: oip, + LocalUpDown: DEFAULT_UPDOWN, + CryptoProposal: all_proposal, + } + + scc_ipsec_resource := resource.IpsecResource{ + Name: "localto" + format_resource_name(to.Metadata.Name, ""), + Type: VTI_MODE, + Remote: ANY, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: base64.StdEncoding.EncodeToString([]byte(crt)), + PrivateCert: base64.StdEncoding.EncodeToString([]byte(key)), + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + SCCCertName, + RemoteIdentifier: "CN=" + to.GetCertName(), + CryptoProposal: all_proposal, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: scc_conn, + } + + scc := module.EmptyObject{ + Metadata: module.ObjectMetaData{"local", "", "", ""}} + + // Add and deploy resource + resutil := NewResUtil() + resutil.AddResource(&scc, "create", &scc_ipsec_resource) + for i := 0; i < len(proposalresource); i++ { + resutil.AddResource(&scc, "create", proposalresource[i]) + } + + resutil.Deploy("localto"+to.Metadata.Name, "YAML") + + //Reserve ipsec resource to device object + res_str, err := resource.GetResourceBuilder().ToString(&scc_ipsec_resource) + to.Status.Data[SCC_RESOURCE] = res_str + + ips = append(ips, oip) + + } + return nil + +} + +func (c *DeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + err := c.PreProcessing(m, t) + if err != nil { + return c.CreateEmptyObject(), err + } + + to := t.(*module.DeviceObject) + task = runner.Go(func(ShouldStop runner.S) error { + for to.Status.Data[RegStatus] != "success" { + err = c.PostRegister(m, t) + if err != nil { + log.Println(err) + } + time.Sleep(5 * time.Second) + if ShouldStop() { + break + } + } + return nil + }) + + // DB Operation + t, err = GetDBUtils().CreateObject(c, m, t) + return t, err +} + +func (c *DeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObject(c, m) + + return t, err +} + +func (c *DeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObjects(c, m) + + return t, err +} + +func (c *DeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().UpdateObject(c, m, t) + + return t, err +} + +func (c *DeviceObjectManager) DeleteObject(m map[string]string) error { + t, err := c.GetObject(m) + if err != nil { + return nil + } + + if task != nil && task.Running() { + task.Stop() + select { + case <-task.StopChan(): + case <-time.After(2 * time.Second): + log.Println("Goroutine register device stopped") + } + } + + //overlay_manager := GetManagerset().Overlay + ipr_manager := GetManagerset().IPRange + + overlay_name := m[OverlayResource] + device_name := m[DeviceResource] + + to := t.(*module.DeviceObject) + + //If the device is in mode 2: + // * Free OIP assigned + // * Remove ipsec configuration on SCC + if to.Status.Mode == 2 { + // Free OIP + ipr_manager.Free(overlay_name, to.Status.Ip) + + scc := module.EmptyObject{ + Metadata: module.ObjectMetaData{"local", "", "", ""}} + + resutils := NewResUtil() + r_str := to.Status.Data["scc_ipsec_resource"] + r, _ := resource.GetResourceBuilder().ToObject(r_str) + resutils.AddResource(&scc, "create", r) + resutils.Undeploy("localto"+device_name, "YAML") + } + + // DB Operation + err = GetDBUtils().DeleteObject(c, m) + + return err +} + +func GetDeviceCertificate(overlay_name string, device_name string) (string, string, error) { + cert := GetManagerset().Cert + _, crts, key, err := cert.GetOrCreateDC(overlay_name, device_name) + if err != nil { + log.Println("Error in getting cert for device ...") + return "", "", err + } + + crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] + return crt, key, nil +} + +func (c *DeviceObjectManager) PostRegister(m map[string]string, t module.ControllerObject) error { + + overlay_manager := GetManagerset().Overlay + + to := t.(*module.DeviceObject) + log.Println("Registering device " + to.Metadata.Name + " ... ") + + if to.Status.Mode == 2 { + kube_config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig) + if err != nil { + to.Status.Data[RegStatus] = "failed" + } + + kube_config, _, err = kubeutil.checkKubeConfigAvail(kube_config, ips, DEFAULT_K8S_API_SERVER_PORT) + if err != nil { + //TODO: check the error type, and if is unauthorized then switch the status to failed. + return err + } + + to.Status.Data[RegStatus] = "success" + to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(kube_config) + err = GetDBUtils().RegisterDevice(to.Metadata.Name, to.Specification.KubeConfig) + if err != nil { + log.Println(err) + return err + } + log.Println("scc connection is verified.") + + } else { + to.Status.Data[RegStatus] = "success" + } + + if to.Status.Data[RegStatus] == "success" { + devices, err := c.GetObjects(m) + if err != nil { + log.Println(err) + return err + } + + //TODO: Need to add funcs to re-create connections if some of the connections are not ready + //Maybe because of cert not ready or other reasons. + for i := 0; i < len(devices); i++ { + dev := devices[i].(*module.DeviceObject) + if to.Status.Mode == 1 || dev.Status.Mode == 1 { + err = overlay_manager.SetupConnection(m, to, dev, DEVICETODEVICE, NameSpaceName) + if err != nil { + return err + } + } + } + } + + c.UpdateObject(m, t) + return nil +} diff --git a/central-controller/src/scc/pkg/manager/deviceconnection_objectmanager.go b/central-controller/src/scc/pkg/manager/deviceconnection_objectmanager.go index a591b4c..8b7387d 100644 --- a/central-controller/src/scc/pkg/manager/deviceconnection_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/deviceconnection_objectmanager.go @@ -1,126 +1,126 @@ -/* - * 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 manager - -import ( - "io" - "encoding/json" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -type DeviceConnObjectKey struct { - OverlayName string `json:"overlay-name"` - DeviceName string `json:"device-name"` - ConnName string `json:"connection-name"` -} - -// DeviceConnObjectManager implements the ControllerObjectManager -type DeviceConnObjectManager struct { - BaseObjectManager -} - -func NewDeviceConnObjectManager() *DeviceConnObjectManager { - return &DeviceConnObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "deviceconn", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *DeviceConnObjectManager) GetResourceName() string { - return ConnectionResource -} - -func (c *DeviceConnObjectManager) IsOperationSupported(oper string) bool { - if oper == "GETS" { - return true - } - return false -} - -func (c *DeviceConnObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.ConnectionObject{} -} - -func (c *DeviceConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - device_name := m[DeviceResource] - key := DeviceConnObjectKey{ - OverlayName: overlay_name, - DeviceName: device_name, - ConnName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.ConnectionObject) - meta_name := to.Metadata.Name - res_name := m[ConnectionResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.ConnName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.ConnName = meta_name - } - - return key, nil; -} - -func (c *DeviceConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.ConnectionObject - err := json.NewDecoder(r).Decode(&v) - - return &v, err -} - -func (c *DeviceConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *DeviceConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *DeviceConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - overlay_name := m[OverlayResource] - device_name := m[DeviceResource] - - return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Device", device_name)) -} - -func (c *DeviceConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *DeviceConnObjectManager) DeleteObject(m map[string]string) error { - return pkgerrors.New("Not implemented") -} +/* + * 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 manager + +import ( + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" +) + +type DeviceConnObjectKey struct { + OverlayName string `json:"overlay-name"` + DeviceName string `json:"device-name"` + ConnName string `json:"connection-name"` +} + +// DeviceConnObjectManager implements the ControllerObjectManager +type DeviceConnObjectManager struct { + BaseObjectManager +} + +func NewDeviceConnObjectManager() *DeviceConnObjectManager { + return &DeviceConnObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "deviceconn", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *DeviceConnObjectManager) GetResourceName() string { + return ConnectionResource +} + +func (c *DeviceConnObjectManager) IsOperationSupported(oper string) bool { + if oper == "GETS" { + return true + } + return false +} + +func (c *DeviceConnObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.ConnectionObject{} +} + +func (c *DeviceConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + device_name := m[DeviceResource] + key := DeviceConnObjectKey{ + OverlayName: overlay_name, + DeviceName: device_name, + ConnName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.ConnectionObject) + meta_name := to.Metadata.Name + res_name := m[ConnectionResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.ConnName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.ConnName = meta_name + } + + return key, nil +} + +func (c *DeviceConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.ConnectionObject + err := json.NewDecoder(r).Decode(&v) + + return &v, err +} + +func (c *DeviceConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *DeviceConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *DeviceConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + overlay_name := m[OverlayResource] + device_name := m[DeviceResource] + + return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Device", device_name)) +} + +func (c *DeviceConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *DeviceConnObjectManager) DeleteObject(m map[string]string) error { + return pkgerrors.New("Not implemented") +} diff --git a/central-controller/src/scc/pkg/manager/hub_objectmanager.go b/central-controller/src/scc/pkg/manager/hub_objectmanager.go index 556edf8..466041b 100644 --- a/central-controller/src/scc/pkg/manager/hub_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/hub_objectmanager.go @@ -1,249 +1,248 @@ -/* - * 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 manager - -import ( - "io" - "log" - "strings" - "encoding/json" - "encoding/base64" - - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -const DEFAULTPORT = "6443" - -type HubObjectKey struct { - OverlayName string `json:"overlay-name"` - HubName string `json:"hub-name"` -} - -// HubObjectManager implements the ControllerObjectManager -type HubObjectManager struct { - BaseObjectManager -} - -func NewHubObjectManager() *HubObjectManager { - return &HubObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "hub", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *HubObjectManager) GetResourceName() string { - return HubResource -} - -func (c *HubObjectManager) IsOperationSupported(oper string) bool { - return true -} - -func (c *HubObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.HubObject{} -} - -func (c *HubObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - key := HubObjectKey{ - OverlayName: overlay_name, - HubName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.HubObject) - meta_name := to.Metadata.Name - res_name := m[HubResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.HubName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.HubName = meta_name - } - - return key, nil; -} - -func (c *HubObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.HubObject - err := json.NewDecoder(r).Decode(&v) - - // initial Status - v.Status.Data = make(map[string]string) - v.Status.ProxyPort = make(map[string]string) - return &v, err -} - -func (c *HubObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - overlay := GetManagerset().Overlay - overlay_name := m[OverlayResource] - to := t.(*module.HubObject) - hub_name := to.Metadata.Name - - //Todo: Check if public ip can be used. - var local_public_ip string - var config []byte - config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig) - if err != nil { - log.Println(err) - return t, err - } - - local_public_ips := to.Specification.PublicIps - - kubeutil := GetKubeConfigUtil() - config, local_public_ip, err = kubeutil.checkKubeConfigAvail(config, local_public_ips, DEFAULTPORT) - if err == nil { - log.Println("Public IP address verified: " + local_public_ip) - to.Status.Ip = local_public_ip - to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(config) - err := GetDBUtils().RegisterDevice(hub_name, to.Specification.KubeConfig) - if err != nil { - log.Println(err) - } - } else { - return t, err - } - - //Create cert for ipsec connection - log.Println("Create Certificate: " + to.GetCertName()) - _, _, err = overlay.CreateCertificate(overlay_name, to.GetCertName()) - if err != nil { - return t, err - } - - //Get all available hub objects - hubs, err := c.GetObjects(m) - if err != nil { - log.Println(err) - } - - //TODO: Need to add funcs to re-create connections if some of the connections are not ready - //Maybe because of cert not ready or other reasons. - if len(hubs) > 0 && err == nil { - for i := 0; i < len(hubs); i++ { - err := overlay.SetupConnection(m, t, hubs[i], HUBTOHUB, NameSpaceName) - if err != nil { - log.Println("Setup connection with " + hubs[i].(*module.HubObject).Metadata.Name + " failed.") - } - } - t, err = GetDBUtils().CreateObject(c, m, t) - } else { - - t, err = GetDBUtils().CreateObject(c, m, t) - } - - return t, err -} - -func (c *HubObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObject(c, m) - - return t, err -} - -func (c *HubObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObjects(c, m) - - return t, err -} - -func (c *HubObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().UpdateObject(c, m, t) - - return t, err -} - -func (c *HubObjectManager) DeleteObject(m map[string]string) error { - //Check resource exists - - t, err := c.GetObject(m) - if err != nil { - return nil - } - - overlay_manager := GetManagerset().Overlay - conn_manager := GetConnectionManager() - - overlay_name := m[OverlayResource] - hub_name := m[HubResource] - -// Reset all IpSec connection setup by this device - conns, err := conn_manager.GetObjects(overlay_name, module.CreateEndName(t.GetType(), hub_name)) - if err != nil { - log.Println(err) - } else { - for i := 0; i < len(conns); i++ { - conn := conns[i].(*module.ConnectionObject) - err = conn_manager.Undeploy(overlay_name, *conn) - if err != nil { - log.Println(err) - } - } - } - - to := t.(*module.HubObject) - log.Println("Delete Certificate: " + to.GetCertName()) - overlay_manager.DeleteCertificate(to.GetCertName()) - - - // DB Operation - err = GetDBUtils().DeleteObject(c, m) - - return err -} - -func GetHubCertificate(cert_name string, namespace string)(string, string, error){ - cu, err := GetCertUtil() - if err != nil { - log.Println(err) - return "", "", err - } else { - ready := cu.IsCertReady(cert_name, namespace) - if ready != true { - return "", "", pkgerrors.New("Cert for hub is not ready") - } else { - crts, key, err := cu.GetKeypair(cert_name, namespace) - crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] - if err != nil { - log.Println(err) - return "", "", err - } - return crt, key, nil - } - } -} +/* + * 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 manager + +import ( + "encoding/base64" + "encoding/json" + "io" + "log" + "strings" + + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" +) + +const DEFAULTPORT = "6443" + +type HubObjectKey struct { + OverlayName string `json:"overlay-name"` + HubName string `json:"hub-name"` +} + +// HubObjectManager implements the ControllerObjectManager +type HubObjectManager struct { + BaseObjectManager +} + +func NewHubObjectManager() *HubObjectManager { + return &HubObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "hub", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *HubObjectManager) GetResourceName() string { + return HubResource +} + +func (c *HubObjectManager) IsOperationSupported(oper string) bool { + return true +} + +func (c *HubObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.HubObject{} +} + +func (c *HubObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + key := HubObjectKey{ + OverlayName: overlay_name, + HubName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.HubObject) + meta_name := to.Metadata.Name + res_name := m[HubResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.HubName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.HubName = meta_name + } + + return key, nil +} + +func (c *HubObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.HubObject + err := json.NewDecoder(r).Decode(&v) + + // initial Status + v.Status.Data = make(map[string]string) + v.Status.ProxyPort = make(map[string]string) + return &v, err +} + +func (c *HubObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + overlay := GetManagerset().Overlay + overlay_name := m[OverlayResource] + to := t.(*module.HubObject) + hub_name := to.Metadata.Name + + //Todo: Check if public ip can be used. + var local_public_ip string + var config []byte + config, err := base64.StdEncoding.DecodeString(to.Specification.KubeConfig) + if err != nil { + log.Println(err) + return t, err + } + + local_public_ips := to.Specification.PublicIps + + kubeutil := GetKubeConfigUtil() + config, local_public_ip, err = kubeutil.checkKubeConfigAvail(config, local_public_ips, DEFAULTPORT) + if err == nil { + log.Println("Public IP address verified: " + local_public_ip) + to.Status.Ip = local_public_ip + to.Specification.KubeConfig = base64.StdEncoding.EncodeToString(config) + err := GetDBUtils().RegisterDevice(hub_name, to.Specification.KubeConfig) + if err != nil { + log.Println(err) + } + } else { + return t, err + } + + //Create cert for ipsec connection + log.Println("Create Certificate: " + to.GetCertName()) + _, _, err = overlay.CreateCertificate(overlay_name, to.GetCertName()) + if err != nil { + return t, err + } + + //Get all available hub objects + hubs, err := c.GetObjects(m) + if err != nil { + log.Println(err) + } + + //TODO: Need to add funcs to re-create connections if some of the connections are not ready + //Maybe because of cert not ready or other reasons. + if len(hubs) > 0 && err == nil { + for i := 0; i < len(hubs); i++ { + err := overlay.SetupConnection(m, t, hubs[i], HUBTOHUB, NameSpaceName) + if err != nil { + log.Println("Setup connection with " + hubs[i].(*module.HubObject).Metadata.Name + " failed.") + } + } + t, err = GetDBUtils().CreateObject(c, m, t) + } else { + + t, err = GetDBUtils().CreateObject(c, m, t) + } + + return t, err +} + +func (c *HubObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObject(c, m) + + return t, err +} + +func (c *HubObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObjects(c, m) + + return t, err +} + +func (c *HubObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().UpdateObject(c, m, t) + + return t, err +} + +func (c *HubObjectManager) DeleteObject(m map[string]string) error { + //Check resource exists + + t, err := c.GetObject(m) + if err != nil { + return nil + } + + overlay_manager := GetManagerset().Overlay + conn_manager := GetConnectionManager() + + overlay_name := m[OverlayResource] + hub_name := m[HubResource] + + // Reset all IpSec connection setup by this device + conns, err := conn_manager.GetObjects(overlay_name, module.CreateEndName(t.GetType(), hub_name)) + if err != nil { + log.Println(err) + } else { + for i := 0; i < len(conns); i++ { + conn := conns[i].(*module.ConnectionObject) + err = conn_manager.Undeploy(overlay_name, *conn) + if err != nil { + log.Println(err) + } + } + } + + to := t.(*module.HubObject) + log.Println("Delete Certificate: " + to.GetCertName()) + overlay_manager.DeleteCertificate(to.GetCertName()) + + // DB Operation + err = GetDBUtils().DeleteObject(c, m) + + return err +} + +func GetHubCertificate(cert_name string, namespace string) (string, string, error) { + cu, err := GetCertUtil() + if err != nil { + log.Println(err) + return "", "", err + } else { + ready := cu.IsCertReady(cert_name, namespace) + if ready != true { + return "", "", pkgerrors.New("Cert for hub is not ready") + } else { + crts, key, err := cu.GetKeypair(cert_name, namespace) + crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] + if err != nil { + log.Println(err) + return "", "", err + } + return crt, key, nil + } + } +} diff --git a/central-controller/src/scc/pkg/manager/hubconnection_objectmanager.go b/central-controller/src/scc/pkg/manager/hubconnection_objectmanager.go index 797c968..e858d7b 100644 --- a/central-controller/src/scc/pkg/manager/hubconnection_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/hubconnection_objectmanager.go @@ -1,126 +1,126 @@ -/* - * 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 manager - -import ( - "io" - "encoding/json" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -type HubConnObjectKey struct { - OverlayName string `json:"overlay-name"` - HubName string `json:"hub-name"` - ConnName string `json:"connection-name"` -} - -// HubConnObjectManager implements the ControllerObjectManager -type HubConnObjectManager struct { - BaseObjectManager -} - -func NewHubConnObjectManager() *HubConnObjectManager { - return &HubConnObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "hubconn", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *HubConnObjectManager) GetResourceName() string { - return ConnectionResource -} - -func (c *HubConnObjectManager) IsOperationSupported(oper string) bool { - if oper == "GETS" { - return true - } - return false -} - -func (c *HubConnObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.ConnectionObject{} -} - -func (c *HubConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - hub_name := m[HubResource] - key := HubConnObjectKey{ - OverlayName: overlay_name, - HubName: hub_name, - ConnName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.ConnectionObject) - meta_name := to.Metadata.Name - res_name := m[ConnectionResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.ConnName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.ConnName = meta_name - } - - return key, nil; -} - -func (c *HubConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.ConnectionObject - err := json.NewDecoder(r).Decode(&v) - - return &v, err -} - -func (c *HubConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *HubConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *HubConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - overlay_name := m[OverlayResource] - hub_name := m[HubResource] - - return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Hub", hub_name)) -} - -func (c *HubConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *HubConnObjectManager) DeleteObject(m map[string]string) error { - return pkgerrors.New("Not implemented") -} +/* + * 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 manager + +import ( + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" +) + +type HubConnObjectKey struct { + OverlayName string `json:"overlay-name"` + HubName string `json:"hub-name"` + ConnName string `json:"connection-name"` +} + +// HubConnObjectManager implements the ControllerObjectManager +type HubConnObjectManager struct { + BaseObjectManager +} + +func NewHubConnObjectManager() *HubConnObjectManager { + return &HubConnObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "hubconn", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *HubConnObjectManager) GetResourceName() string { + return ConnectionResource +} + +func (c *HubConnObjectManager) IsOperationSupported(oper string) bool { + if oper == "GETS" { + return true + } + return false +} + +func (c *HubConnObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.ConnectionObject{} +} + +func (c *HubConnObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + hub_name := m[HubResource] + key := HubConnObjectKey{ + OverlayName: overlay_name, + HubName: hub_name, + ConnName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.ConnectionObject) + meta_name := to.Metadata.Name + res_name := m[ConnectionResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.ConnName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.ConnName = meta_name + } + + return key, nil +} + +func (c *HubConnObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.ConnectionObject + err := json.NewDecoder(r).Decode(&v) + + return &v, err +} + +func (c *HubConnObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *HubConnObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *HubConnObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + overlay_name := m[OverlayResource] + hub_name := m[HubResource] + + return GetConnectionManager().GetObjects(overlay_name, module.CreateEndName("Hub", hub_name)) +} + +func (c *HubConnObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *HubConnObjectManager) DeleteObject(m map[string]string) error { + return pkgerrors.New("Not implemented") +} diff --git a/central-controller/src/scc/pkg/manager/hubdevice_objectmanager.go b/central-controller/src/scc/pkg/manager/hubdevice_objectmanager.go index 5c44810..a9776bf 100644 --- a/central-controller/src/scc/pkg/manager/hubdevice_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/hubdevice_objectmanager.go @@ -1,177 +1,177 @@ -/* - * 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 manager - -import ( - "io" - "log" - "encoding/json" - - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -type HubDeviceObjectKey struct { - OverlayName string `json:"overlay-name"` - HubName string `json:"hub-name"` - DeviceName string `json:"device-name"` -} - -// HubDeviceObjectManager implements the ControllerObjectManager -type HubDeviceObjectManager struct { - BaseObjectManager -} - -func NewHubDeviceObjectManager() *HubDeviceObjectManager { - return &HubDeviceObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "hubdevice", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *HubDeviceObjectManager) GetResourceName() string { - return DeviceResource -} - -func (c *HubDeviceObjectManager) IsOperationSupported(oper string) bool { - if oper == "POST" || oper == "DELETE" { - return true - } - return false -} - -func (c *HubDeviceObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.HubDeviceObject{} -} - -func (c *HubDeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - hub_name := m[HubResource] - device_name := m[DeviceResource] - key := HubDeviceObjectKey{ - OverlayName: overlay_name, - HubName: hub_name, - DeviceName: device_name, - } - - return key, nil; -} - -func (c *HubDeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.HubDeviceObject - err := json.NewDecoder(r).Decode(&v) - - return &v, err -} - -func (c *HubDeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // Setup hub-device connection - overlay_name := m[OverlayResource] - hub_name := m[HubResource] - //device_name :=m[DeviceResource] - to := t.(*module.HubDeviceObject) - device_name := to.Specification.Device - m[DeviceResource] = device_name - - hub_manager := GetManagerset().Hub - dev_manager := GetManagerset().Device - overlay_namager := GetManagerset().Overlay - conn_manager := GetConnectionManager() - - hub, err := hub_manager.GetObject(m) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Hub " + hub_name + " is not defined") - } - - dev, err := dev_manager.GetObject(m) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " is not defined") - } - - device := dev.(*module.DeviceObject) - if device.Status.Data[RegStatus] != "success" { - log.Println("Device registration not ready") - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device " + device_name + " registration is not ready") - } - - _, err = conn_manager.GetObject(overlay_name, - module.CreateEndName(hub.GetType(), hub.GetMetadata().Name), - module.CreateEndName(dev.GetType(), dev.GetMetadata().Name)) - if err == nil { - return c.CreateEmptyObject(), pkgerrors.New("The connection between Hub " + hub_name + " and Device " + device_name + " is already created") - } - - err = overlay_namager.SetupConnection(m, hub, dev, HUBTODEVICE, NameSpaceName) - if err != nil { - return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Fail to setup connection between " + hub_name + " and " + device_name) - } - - return c.CreateEmptyObject(), nil -} - -func (c *HubDeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *HubDeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - return []module.ControllerObject{}, pkgerrors.New("Not implemented") -} - -func (c *HubDeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - return c.CreateEmptyObject(), pkgerrors.New("Not implemented") -} - -func (c *HubDeviceObjectManager) DeleteObject(m map[string]string) error { - // Delete hub-device connection - overlay_name := m[OverlayResource] - hub_name := m[HubResource] - device_name := m[DeviceResource] - - hub_manager := GetManagerset().Hub - dev_manager := GetManagerset().Device - conn_manager := GetConnectionManager() - - hub, err := hub_manager.GetObject(m) - if err != nil { - return pkgerrors.Wrap(err, "Hub " + hub_name + " is not defined") - } - - dev, err := dev_manager.GetObject(m) - if err != nil { - return pkgerrors.Wrap(err, "Device " + device_name + " is not defined") - } - - conn, err := conn_manager.GetObject(overlay_name, - module.CreateEndName(hub.GetType(), hub.GetMetadata().Name), - module.CreateEndName(dev.GetType(), dev.GetMetadata().Name)) - if err != nil { - log.Println(err) - } else { - conn_obj := conn.(*module.ConnectionObject) - err = conn_manager.Undeploy(overlay_name, *conn_obj) - if err != nil { - log.Println(err) - } - } - - return nil -} +/* + * 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 manager + +import ( + "encoding/json" + "io" + "log" + + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" +) + +type HubDeviceObjectKey struct { + OverlayName string `json:"overlay-name"` + HubName string `json:"hub-name"` + DeviceName string `json:"device-name"` +} + +// HubDeviceObjectManager implements the ControllerObjectManager +type HubDeviceObjectManager struct { + BaseObjectManager +} + +func NewHubDeviceObjectManager() *HubDeviceObjectManager { + return &HubDeviceObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "hubdevice", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *HubDeviceObjectManager) GetResourceName() string { + return DeviceResource +} + +func (c *HubDeviceObjectManager) IsOperationSupported(oper string) bool { + if oper == "POST" || oper == "DELETE" { + return true + } + return false +} + +func (c *HubDeviceObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.HubDeviceObject{} +} + +func (c *HubDeviceObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + hub_name := m[HubResource] + device_name := m[DeviceResource] + key := HubDeviceObjectKey{ + OverlayName: overlay_name, + HubName: hub_name, + DeviceName: device_name, + } + + return key, nil +} + +func (c *HubDeviceObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.HubDeviceObject + err := json.NewDecoder(r).Decode(&v) + + return &v, err +} + +func (c *HubDeviceObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // Setup hub-device connection + overlay_name := m[OverlayResource] + hub_name := m[HubResource] + //device_name :=m[DeviceResource] + to := t.(*module.HubDeviceObject) + device_name := to.Specification.Device + m[DeviceResource] = device_name + + hub_manager := GetManagerset().Hub + dev_manager := GetManagerset().Device + overlay_namager := GetManagerset().Overlay + conn_manager := GetConnectionManager() + + hub, err := hub_manager.GetObject(m) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Hub "+hub_name+" is not defined") + } + + dev, err := dev_manager.GetObject(m) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device "+device_name+" is not defined") + } + + device := dev.(*module.DeviceObject) + if device.Status.Data[RegStatus] != "success" { + log.Println("Device registration not ready") + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Device "+device_name+" registration is not ready") + } + + _, err = conn_manager.GetObject(overlay_name, + module.CreateEndName(hub.GetType(), hub.GetMetadata().Name), + module.CreateEndName(dev.GetType(), dev.GetMetadata().Name)) + if err == nil { + return c.CreateEmptyObject(), pkgerrors.New("The connection between Hub " + hub_name + " and Device " + device_name + " is already created") + } + + err = overlay_namager.SetupConnection(m, hub, dev, HUBTODEVICE, NameSpaceName) + if err != nil { + return c.CreateEmptyObject(), pkgerrors.Wrap(err, "Fail to setup connection between "+hub_name+" and "+device_name) + } + + return c.CreateEmptyObject(), nil +} + +func (c *HubDeviceObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *HubDeviceObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + return []module.ControllerObject{}, pkgerrors.New("Not implemented") +} + +func (c *HubDeviceObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + return c.CreateEmptyObject(), pkgerrors.New("Not implemented") +} + +func (c *HubDeviceObjectManager) DeleteObject(m map[string]string) error { + // Delete hub-device connection + overlay_name := m[OverlayResource] + hub_name := m[HubResource] + device_name := m[DeviceResource] + + hub_manager := GetManagerset().Hub + dev_manager := GetManagerset().Device + conn_manager := GetConnectionManager() + + hub, err := hub_manager.GetObject(m) + if err != nil { + return pkgerrors.Wrap(err, "Hub "+hub_name+" is not defined") + } + + dev, err := dev_manager.GetObject(m) + if err != nil { + return pkgerrors.Wrap(err, "Device "+device_name+" is not defined") + } + + conn, err := conn_manager.GetObject(overlay_name, + module.CreateEndName(hub.GetType(), hub.GetMetadata().Name), + module.CreateEndName(dev.GetType(), dev.GetMetadata().Name)) + if err != nil { + log.Println(err) + } else { + conn_obj := conn.(*module.ConnectionObject) + err = conn_manager.Undeploy(overlay_name, *conn_obj) + if err != nil { + log.Println(err) + } + } + + return nil +} diff --git a/central-controller/src/scc/pkg/manager/iprange_objectmanager.go b/central-controller/src/scc/pkg/manager/iprange_objectmanager.go index 3a703b8..398cbc2 100644 --- a/central-controller/src/scc/pkg/manager/iprange_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/iprange_objectmanager.go @@ -1,322 +1,322 @@ -/* - * 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 manager - -import ( - "io" - "encoding/json" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation" - "github.com/go-playground/validator/v10" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -type IPRangeObjectKey struct { - OverlayName string `json:"overlay-name"` - IPRangeName string `json:"iprange-name"` -} - -type ProviderIPRangeObjectKey struct { - IPRangeName string `json:"iprange-name"` -} - -// IPRangeObjectManager implements the ControllerObjectManager -type IPRangeObjectManager struct { - BaseObjectManager - provider bool -} - -func NewIPRangeObjectManager(provider bool) *IPRangeObjectManager { - object_meta := "iprange" - if provider { - object_meta = "provider-" + object_meta - } - - validate := validation.GetValidator(object_meta) - validate.RegisterStructValidation(ValidateIPRangeObject, module.IPRangeObject{}) - - return &IPRangeObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: object_meta, - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - provider, - } -} - -func ValidateIPRangeObject(sl validator.StructLevel) { - obj := sl.Current().Interface().(module.IPRangeObject) - - if obj.Specification.MinIp != 0 && obj.Specification.MaxIp != 0 { - if obj.Specification.MinIp > obj.Specification.MaxIp { - sl.ReportError(obj.Specification.MinIp, "Range", "Range", "InValidateIPRange", "") - } - } -} - -func (c *IPRangeObjectManager) GetResourceName() string { - return IPRangeResource -} - -func (c *IPRangeObjectManager) IsOperationSupported(oper string) bool { - if oper == "PUT" { - // Not allowed for update - return false - } - return true -} - -func (c *IPRangeObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.IPRangeObject{} -} - -func (c *IPRangeObjectManager) SetIPRangeName(k db.Key, name string) { - if c.provider { - ko := k.(*ProviderIPRangeObjectKey) - ko.IPRangeName = name - } else { - ko := k.(*IPRangeObjectKey) - ko.IPRangeName = name - } -} - -func (c *IPRangeObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - var key db.Key - - if c.provider { - key = ProviderIPRangeObjectKey{ - IPRangeName: "", - } - } else { - overlay_name := m[OverlayResource] - key = IPRangeObjectKey{ - OverlayName: overlay_name, - IPRangeName: "", - } - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.IPRangeObject) - meta_name := to.Metadata.Name - res_name := m[IPRangeResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - c.SetIPRangeName(key, res_name) - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - c.SetIPRangeName(key, meta_name) - } - - return key, nil; -} - -func (c *IPRangeObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.IPRangeObject - err := json.NewDecoder(r).Decode(&v) - - // initial Status - for i:=0; i<32; i++ { - v.Status.Masks[i] = 0 - } - v.Status.Data = make(map[string]string) - return &v, err -} - -func (c *IPRangeObjectManager) GetDefinedObjects(m map[string]string) ([]module.ControllerObject, error) { - objs, err := c.GetObjects(m) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get available IPRange objects") - } - - if c.provider { - ipr_manager := GetManagerset().IPRange - overlay_manager := GetManagerset().Overlay - - // concact ip ranges defined in all overlays - ol_objs, err := overlay_manager.GetObjects(m) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get overlays") - } - - for _, ol_obj := range ol_objs { - o_m := make(map[string]string) - o_m[OverlayResource] = ol_obj.GetMetadata().Name - // get ip range for the overlay - ip_objs, err := ipr_manager.GetObjects(o_m) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get ip ranges for overlay") - } - objs = append(objs, ip_objs...) - } - } else { - // concact ip ranges defined in provider - providerIP_manager := GetManagerset().ProviderIPRange - p_objs, err := providerIP_manager.GetObjects(m) - if err != nil { - return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get provider IPRange objects") - } - - objs = append(objs, p_objs...) - } - - return objs, nil -} - -func (c *IPRangeObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // Check whether conflict with other IPRange object - objs, err := c.GetDefinedObjects(m) - if err != nil { - return t, pkgerrors.Wrap(err, "Failed to get available IPRange objects") - } - - ot := t.(*module.IPRangeObject) - for _, obj := range objs { - if ot.IsConflict(obj.(*module.IPRangeObject)) { - return c.CreateEmptyObject(), pkgerrors.New("Conflicted with IPRange object: " + obj.(*module.IPRangeObject).Metadata.Name) - } - } - - // DB Operation - t, err = GetDBUtils().CreateObject(c, m, t) - - return t, err -} - -func (c *IPRangeObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObject(c, m) - - return t, err -} - -func (c *IPRangeObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObjects(c, m) - - return t, err -} - -func (c *IPRangeObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().UpdateObject(c, m, t) - - return t, err -} - -func (c *IPRangeObjectManager) DeleteObject(m map[string]string) error { - // Check whether in used - obj, err := c.GetObject(m) - if err != nil { - return pkgerrors.Wrap(err, "Failed to get IPRange object") - } - - if obj.(*module.IPRangeObject).InUsed() { - return pkgerrors.New("The IPRange object is in used") - } - - // DB Operation - err = GetDBUtils().DeleteObject(c, m) - - return err -} - -func (c *IPRangeObjectManager) Allocate(oname string, name string) (string, error) { - m := make(map[string]string) - - if !c.provider { - m[OverlayResource] = oname - } - - objs, err := c.GetObjects(m) - if err != nil { - return "", pkgerrors.Wrap(err, "Failed to get available IPRange objects") - } - - for _, obj := range objs { - tobj := obj.(*module.IPRangeObject) - aip, err := tobj.Allocate(name) - if err == nil { - // save update object in DB - c.UpdateObject(m, tobj) - return aip, nil - } - } - - return "", pkgerrors.New("No available ip") -} - -func (c *IPRangeObjectManager) Free(oname string, ip string) error { - m := make(map[string]string) - - if !c.provider { - m[OverlayResource] = oname - } - - objs, err := c.GetObjects(m) - if err != nil { - return pkgerrors.Wrap(err, "Failed to get available IPRange objects") - } - - for _, obj := range objs { - tobj := obj.(*module.IPRangeObject) - err := tobj.Free(ip) - if err == nil { - // save update object in DB - c.UpdateObject(m, tobj) - return nil - } - } - - return pkgerrors.New("ip " + ip + " is not allocated") -} - -func (c *IPRangeObjectManager) FreeAll(oname string) error { - m := make(map[string]string) - - if !c.provider { - m[OverlayResource] = oname - } - - objs, err := c.GetObjects(m) - if err != nil { - return pkgerrors.Wrap(err, "Failed to get available IPRange objects") - } - - for _, obj := range objs { - tobj := obj.(*module.IPRangeObject) - err := tobj.FreeAll() - if err == nil { - // save update object in DB - c.UpdateObject(m, tobj) - } - } - - return nil -} +/* + * 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 manager + +import ( + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/infra/validation" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/go-playground/validator/v10" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" +) + +type IPRangeObjectKey struct { + OverlayName string `json:"overlay-name"` + IPRangeName string `json:"iprange-name"` +} + +type ProviderIPRangeObjectKey struct { + IPRangeName string `json:"iprange-name"` +} + +// IPRangeObjectManager implements the ControllerObjectManager +type IPRangeObjectManager struct { + BaseObjectManager + provider bool +} + +func NewIPRangeObjectManager(provider bool) *IPRangeObjectManager { + object_meta := "iprange" + if provider { + object_meta = "provider-" + object_meta + } + + validate := validation.GetValidator(object_meta) + validate.RegisterStructValidation(ValidateIPRangeObject, module.IPRangeObject{}) + + return &IPRangeObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: object_meta, + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + provider, + } +} + +func ValidateIPRangeObject(sl validator.StructLevel) { + obj := sl.Current().Interface().(module.IPRangeObject) + + if obj.Specification.MinIp != 0 && obj.Specification.MaxIp != 0 { + if obj.Specification.MinIp > obj.Specification.MaxIp { + sl.ReportError(obj.Specification.MinIp, "Range", "Range", "InValidateIPRange", "") + } + } +} + +func (c *IPRangeObjectManager) GetResourceName() string { + return IPRangeResource +} + +func (c *IPRangeObjectManager) IsOperationSupported(oper string) bool { + if oper == "PUT" { + // Not allowed for update + return false + } + return true +} + +func (c *IPRangeObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.IPRangeObject{} +} + +func (c *IPRangeObjectManager) SetIPRangeName(k db.Key, name string) { + if c.provider { + ko := k.(*ProviderIPRangeObjectKey) + ko.IPRangeName = name + } else { + ko := k.(*IPRangeObjectKey) + ko.IPRangeName = name + } +} + +func (c *IPRangeObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + var key db.Key + + if c.provider { + key = ProviderIPRangeObjectKey{ + IPRangeName: "", + } + } else { + overlay_name := m[OverlayResource] + key = IPRangeObjectKey{ + OverlayName: overlay_name, + IPRangeName: "", + } + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.IPRangeObject) + meta_name := to.Metadata.Name + res_name := m[IPRangeResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + c.SetIPRangeName(key, res_name) + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + c.SetIPRangeName(key, meta_name) + } + + return key, nil +} + +func (c *IPRangeObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.IPRangeObject + err := json.NewDecoder(r).Decode(&v) + + // initial Status + for i := 0; i < 32; i++ { + v.Status.Masks[i] = 0 + } + v.Status.Data = make(map[string]string) + return &v, err +} + +func (c *IPRangeObjectManager) GetDefinedObjects(m map[string]string) ([]module.ControllerObject, error) { + objs, err := c.GetObjects(m) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get available IPRange objects") + } + + if c.provider { + ipr_manager := GetManagerset().IPRange + overlay_manager := GetManagerset().Overlay + + // concact ip ranges defined in all overlays + ol_objs, err := overlay_manager.GetObjects(m) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get overlays") + } + + for _, ol_obj := range ol_objs { + o_m := make(map[string]string) + o_m[OverlayResource] = ol_obj.GetMetadata().Name + // get ip range for the overlay + ip_objs, err := ipr_manager.GetObjects(o_m) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get ip ranges for overlay") + } + objs = append(objs, ip_objs...) + } + } else { + // concact ip ranges defined in provider + providerIP_manager := GetManagerset().ProviderIPRange + p_objs, err := providerIP_manager.GetObjects(m) + if err != nil { + return []module.ControllerObject{}, pkgerrors.Wrap(err, "Failed to get provider IPRange objects") + } + + objs = append(objs, p_objs...) + } + + return objs, nil +} + +func (c *IPRangeObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // Check whether conflict with other IPRange object + objs, err := c.GetDefinedObjects(m) + if err != nil { + return t, pkgerrors.Wrap(err, "Failed to get available IPRange objects") + } + + ot := t.(*module.IPRangeObject) + for _, obj := range objs { + if ot.IsConflict(obj.(*module.IPRangeObject)) { + return c.CreateEmptyObject(), pkgerrors.New("Conflicted with IPRange object: " + obj.(*module.IPRangeObject).Metadata.Name) + } + } + + // DB Operation + t, err = GetDBUtils().CreateObject(c, m, t) + + return t, err +} + +func (c *IPRangeObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObject(c, m) + + return t, err +} + +func (c *IPRangeObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObjects(c, m) + + return t, err +} + +func (c *IPRangeObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().UpdateObject(c, m, t) + + return t, err +} + +func (c *IPRangeObjectManager) DeleteObject(m map[string]string) error { + // Check whether in used + obj, err := c.GetObject(m) + if err != nil { + return pkgerrors.Wrap(err, "Failed to get IPRange object") + } + + if obj.(*module.IPRangeObject).InUsed() { + return pkgerrors.New("The IPRange object is in used") + } + + // DB Operation + err = GetDBUtils().DeleteObject(c, m) + + return err +} + +func (c *IPRangeObjectManager) Allocate(oname string, name string) (string, error) { + m := make(map[string]string) + + if !c.provider { + m[OverlayResource] = oname + } + + objs, err := c.GetObjects(m) + if err != nil { + return "", pkgerrors.Wrap(err, "Failed to get available IPRange objects") + } + + for _, obj := range objs { + tobj := obj.(*module.IPRangeObject) + aip, err := tobj.Allocate(name) + if err == nil { + // save update object in DB + c.UpdateObject(m, tobj) + return aip, nil + } + } + + return "", pkgerrors.New("No available ip") +} + +func (c *IPRangeObjectManager) Free(oname string, ip string) error { + m := make(map[string]string) + + if !c.provider { + m[OverlayResource] = oname + } + + objs, err := c.GetObjects(m) + if err != nil { + return pkgerrors.Wrap(err, "Failed to get available IPRange objects") + } + + for _, obj := range objs { + tobj := obj.(*module.IPRangeObject) + err := tobj.Free(ip) + if err == nil { + // save update object in DB + c.UpdateObject(m, tobj) + return nil + } + } + + return pkgerrors.New("ip " + ip + " is not allocated") +} + +func (c *IPRangeObjectManager) FreeAll(oname string) error { + m := make(map[string]string) + + if !c.provider { + m[OverlayResource] = oname + } + + objs, err := c.GetObjects(m) + if err != nil { + return pkgerrors.Wrap(err, "Failed to get available IPRange objects") + } + + for _, obj := range objs { + tobj := obj.(*module.IPRangeObject) + err := tobj.FreeAll() + if err == nil { + // save update object in DB + c.UpdateObject(m, tobj) + } + } + + return nil +} diff --git a/central-controller/src/scc/pkg/manager/kubeconfigutil.go b/central-controller/src/scc/pkg/manager/kubeconfigutil.go index b4487c9..54ebc8b 100644 --- a/central-controller/src/scc/pkg/manager/kubeconfigutil.go +++ b/central-controller/src/scc/pkg/manager/kubeconfigutil.go @@ -1,140 +1,140 @@ -/* - * 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 manager - -import ( - "os" - "log" - "io/ioutil" - "sigs.k8s.io/yaml" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" - pkgerrors "github.com/pkg/errors" -) - -func DecodeYAMLFromFile(path string, into runtime.Object) (runtime.Object, error) { - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - return nil, pkgerrors.New("File " + path + " not found") - } else { - return nil, pkgerrors.Wrap(err, "Stat file error") - } - } - - rawBytes, err := ioutil.ReadFile(path) - if err != nil { - return nil, pkgerrors.Wrap(err, "Read YAML file error") - } - - decode := scheme.Codecs.UniversalDeserializer().Decode - obj, _, err := decode(rawBytes, nil, into) - if err != nil { - return nil, pkgerrors.Wrap(err, "Deserialize YAML error") - } - - return obj, nil -} - -func DecodeYAMLFromData(data []byte, into runtime.Object) (runtime.Object, error) { - decode := scheme.Codecs.UniversalDeserializer().Decode - obj, _, err := decode(data, nil, into) - if err != nil { - return nil, pkgerrors.Wrap(err, "Deserialize YAML error") - } - - return obj, nil -} - -type KubeConfigUtil struct { -} - -var kubeutil = KubeConfigUtil{} - -func GetKubeConfigUtil() *KubeConfigUtil { - return &kubeutil -} - -func (c *KubeConfigUtil) toYaml(data *unstructured.Unstructured) ([]byte, error) { - byte_json, err := data.MarshalJSON() - if err != nil { - return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml") - } - - byte_yaml, err := yaml.JSONToYAML(byte_json) - if err != nil { - return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml") - } - - return byte_yaml, nil -} - -func (c *KubeConfigUtil) UpdateK8sConfig(conf []byte, server string, insecure bool) ([]byte, error) { - conf_us_obj := &unstructured.Unstructured{} - _, err := DecodeYAMLFromData(conf, conf_us_obj) - if err == nil { - conf_obj := conf_us_obj.UnstructuredContent() - cluster_objs, _, err := unstructured.NestedSlice(conf_obj, "clusters") - if err == nil { - if len(cluster_objs) > 0 { - cluster_obj := cluster_objs[0].(map[string]interface{}) - if insecure { - // remove certificate-authority-data - unstructured.RemoveNestedField(cluster_obj, "cluster", "certificate-authority-data") - // add insecure-skip-tls-verify - err = unstructured.SetNestedField(cluster_obj, true, "cluster", "insecure-skip-tls-verify") - } - - if err == nil { - // set server - err = unstructured.SetNestedField(cluster_obj, server, "cluster", "server") - if err == nil { - err = unstructured.SetNestedSlice(conf_obj, cluster_objs, "clusters") - if err == nil { - return c.toYaml(conf_us_obj) - } - } - } - } else { - return []byte(""), pkgerrors.New("UpdateK8sConfig: No cluster") - } - } - } - - return []byte(""), pkgerrors.Wrap(err, "UpdateK8sConfig") -} - -func (c *KubeConfigUtil)checkKubeConfigAvail(conf []byte, ips []string, port string) ([]byte, string, error){ - kubeclient := client.NewClient("", "", conf) - for i := 0 ; i < len(ips); i++ { - ip := ips[i] - //UpdateConfig - new_url := "https://" + ips[i] + ":" + port - conf, err := kubeutil.UpdateK8sConfig(conf, new_url, true) - if err != nil { - log.Println(err) - return []byte(""), "", pkgerrors.New("Error in updating kubeconfig") - } - kubeclient = client.NewClient("", "", []byte(conf)) - is_reachable := kubeclient.IsReachable() - if is_reachable == true { - return conf, ip, nil - } - } - return []byte(""), "", pkgerrors.New("No public ip found workable for the cluster") -} +/* + * 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 manager + +import ( + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" + pkgerrors "github.com/pkg/errors" + "io/ioutil" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "log" + "os" + "sigs.k8s.io/yaml" +) + +func DecodeYAMLFromFile(path string, into runtime.Object) (runtime.Object, error) { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return nil, pkgerrors.New("File " + path + " not found") + } else { + return nil, pkgerrors.Wrap(err, "Stat file error") + } + } + + rawBytes, err := ioutil.ReadFile(path) + if err != nil { + return nil, pkgerrors.Wrap(err, "Read YAML file error") + } + + decode := scheme.Codecs.UniversalDeserializer().Decode + obj, _, err := decode(rawBytes, nil, into) + if err != nil { + return nil, pkgerrors.Wrap(err, "Deserialize YAML error") + } + + return obj, nil +} + +func DecodeYAMLFromData(data []byte, into runtime.Object) (runtime.Object, error) { + decode := scheme.Codecs.UniversalDeserializer().Decode + obj, _, err := decode(data, nil, into) + if err != nil { + return nil, pkgerrors.Wrap(err, "Deserialize YAML error") + } + + return obj, nil +} + +type KubeConfigUtil struct { +} + +var kubeutil = KubeConfigUtil{} + +func GetKubeConfigUtil() *KubeConfigUtil { + return &kubeutil +} + +func (c *KubeConfigUtil) toYaml(data *unstructured.Unstructured) ([]byte, error) { + byte_json, err := data.MarshalJSON() + if err != nil { + return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml") + } + + byte_yaml, err := yaml.JSONToYAML(byte_json) + if err != nil { + return []byte(""), pkgerrors.Wrap(err, "Fail to generate yaml") + } + + return byte_yaml, nil +} + +func (c *KubeConfigUtil) UpdateK8sConfig(conf []byte, server string, insecure bool) ([]byte, error) { + conf_us_obj := &unstructured.Unstructured{} + _, err := DecodeYAMLFromData(conf, conf_us_obj) + if err == nil { + conf_obj := conf_us_obj.UnstructuredContent() + cluster_objs, _, err := unstructured.NestedSlice(conf_obj, "clusters") + if err == nil { + if len(cluster_objs) > 0 { + cluster_obj := cluster_objs[0].(map[string]interface{}) + if insecure { + // remove certificate-authority-data + unstructured.RemoveNestedField(cluster_obj, "cluster", "certificate-authority-data") + // add insecure-skip-tls-verify + err = unstructured.SetNestedField(cluster_obj, true, "cluster", "insecure-skip-tls-verify") + } + + if err == nil { + // set server + err = unstructured.SetNestedField(cluster_obj, server, "cluster", "server") + if err == nil { + err = unstructured.SetNestedSlice(conf_obj, cluster_objs, "clusters") + if err == nil { + return c.toYaml(conf_us_obj) + } + } + } + } else { + return []byte(""), pkgerrors.New("UpdateK8sConfig: No cluster") + } + } + } + + return []byte(""), pkgerrors.Wrap(err, "UpdateK8sConfig") +} + +func (c *KubeConfigUtil) checkKubeConfigAvail(conf []byte, ips []string, port string) ([]byte, string, error) { + kubeclient := client.NewClient("", "", conf) + for i := 0; i < len(ips); i++ { + ip := ips[i] + //UpdateConfig + new_url := "https://" + ips[i] + ":" + port + conf, err := kubeutil.UpdateK8sConfig(conf, new_url, true) + if err != nil { + log.Println(err) + return []byte(""), "", pkgerrors.New("Error in updating kubeconfig") + } + kubeclient = client.NewClient("", "", []byte(conf)) + is_reachable := kubeclient.IsReachable() + if is_reachable == true { + return conf, ip, nil + } + } + return []byte(""), "", pkgerrors.New("No public ip found workable for the cluster") +} diff --git a/central-controller/src/scc/pkg/manager/managerset.go b/central-controller/src/scc/pkg/manager/managerset.go index 4ed0ac4..afbbb6e 100644 --- a/central-controller/src/scc/pkg/manager/managerset.go +++ b/central-controller/src/scc/pkg/manager/managerset.go @@ -1,38 +1,38 @@ -/* - * 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 manager - -type Managerset struct { - Overlay *OverlayObjectManager - Proposal *ProposalObjectManager - Hub *HubObjectManager - HubConn *HubConnObjectManager - HubDevice *HubDeviceObjectManager - HubCNF *CNFObjectManager - Device *DeviceObjectManager - DeviceConn *DeviceConnObjectManager - DeviceCNF *CNFObjectManager - ProviderIPRange *IPRangeObjectManager - IPRange *IPRangeObjectManager - Cert *CertificateObjectManager -} - -var mgrset = Managerset{} - -func GetManagerset() *Managerset { - return &mgrset -} +/* + * 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 manager + +type Managerset struct { + Overlay *OverlayObjectManager + Proposal *ProposalObjectManager + Hub *HubObjectManager + HubConn *HubConnObjectManager + HubDevice *HubDeviceObjectManager + HubCNF *CNFObjectManager + Device *DeviceObjectManager + DeviceConn *DeviceConnObjectManager + DeviceCNF *CNFObjectManager + ProviderIPRange *IPRangeObjectManager + IPRange *IPRangeObjectManager + Cert *CertificateObjectManager +} + +var mgrset = Managerset{} + +func GetManagerset() *Managerset { + return &mgrset +} diff --git a/central-controller/src/scc/pkg/manager/overlay_objectmanager.go b/central-controller/src/scc/pkg/manager/overlay_objectmanager.go index 0c94cbf..f0aada0 100644 --- a/central-controller/src/scc/pkg/manager/overlay_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/overlay_objectmanager.go @@ -1,478 +1,476 @@ -/* -* 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 manager - -import ( - "io" - "log" - "strings" -// "time" - //"strconv" - "encoding/json" - "encoding/base64" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" - pkgerrors "github.com/pkg/errors" -) - -const DEFAULT_MARK = "30" -const VTI_MODE = "VTI-based" -const POLICY_MODE = "policy-based" -const PUBKEY_AUTH = "pubkey" -const FORCECRYPTOPROPOSAL = "0" -const DEFAULT_CONN = "Conn" -const DEFAULT_UPDOWN = "/etc/updown" -const IPTABLES_UPDOWN = "/usr/lib/ipsec/_updown iptables" -const OIP_UPDOWN = "/etc/updown_oip" -const CONN_TYPE = "tunnel" -const MODE = "start" -const OVERLAYIP = "overlayip" -const HUBTOHUB = "hub-to-hub" -const HUBTODEVICE = "hub-to-device" -const DEVICETODEVICE = "device-to-device" -const BYCONFIG = "%config" -const ANY = "%any" -const BASE_PROTOCOL = "TCP" -const DEFAULT_K8S_API_SERVER_PORT = "6443" -const ACCEPT="ACCEPT" - -type OverlayObjectKey struct { - OverlayName string `json:"overlay-name"` -} - -// OverlayObjectManager implements the ControllerObjectManager -type OverlayObjectManager struct { - BaseObjectManager -} - -func NewOverlayObjectManager() *OverlayObjectManager { - return &OverlayObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "overlay", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *OverlayObjectManager) GetResourceName() string { - return OverlayResource -} - -func (c *OverlayObjectManager) IsOperationSupported(oper string) bool { - return true -} - -func (c *OverlayObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.OverlayObject{} -} - -func (c *OverlayObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - key := OverlayObjectKey{""} - - if isCollection == true { - return key, nil - } - - to := t.(*module.OverlayObject) - meta_name := to.Metadata.Name - res_name := m[OverlayResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.OverlayName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.OverlayName = meta_name - } - - return key, nil; -} - -func (c *OverlayObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.OverlayObject - err := json.NewDecoder(r).Decode(&v) - - return &v, err -} - -func (c *OverlayObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // Create a issuer each overlay - to := t.(*module.OverlayObject) - overlay_name := to.Metadata.Name - cu, err := GetCertUtil() - if err != nil { - log.Println(err) - } else { - // create overlay ca - _, err := cu.CreateCertificate(c.CertName(overlay_name), NameSpaceName, RootCAIssuerName, true) - if err == nil { - // create overlay issuer - _, err := cu.CreateCAIssuer(c.IssuerName(overlay_name), NameSpaceName, c.CertName(overlay_name)) - if err != nil { - log.Println("Failed to create overlay[" + overlay_name +"] issuer: " + err.Error()) - } - } else { - log.Println("Failed to create overlay[" + overlay_name +"] certificate: " + err.Error()) - } - } - - // DB Operation - t, err = GetDBUtils().CreateObject(c, m, t) - - return t, err -} - -func (c *OverlayObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObject(c, m) - - return t, err -} - -func (c *OverlayObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObjects(c, m) - - return t, err -} - -func (c *OverlayObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().UpdateObject(c, m, t) - - return t, err -} - -func (c *OverlayObjectManager) DeleteObject(m map[string]string) error { - overlay_name := m[OverlayResource] - - // DB Operation - err := GetDBUtils().DeleteObject(c, m) - if err == nil { - cu, err := GetCertUtil() - if err != nil { - log.Println(err) - } else { - err = cu.DeleteIssuer(c.IssuerName(overlay_name), NameSpaceName) - if err != nil { - log.Println("Failed to delete overlay[" + overlay_name +"] issuer: " + err.Error()) - } - err = cu.DeleteCertificate(c.CertName(overlay_name), NameSpaceName) - if err != nil { - log.Println("Failed to delete overlay[" + overlay_name +"] certificate: " + err.Error()) - } - } - } - - return err -} - -func (c *OverlayObjectManager) IssuerName(name string) string { - return name + "-issuer" -} - -func (c *OverlayObjectManager) CertName(name string) string { - return name + "-cert" -} - -func (c *OverlayObjectManager) CreateCertificate(oname string, cname string) (string, string, error) { - cu, err := GetCertUtil() - if err != nil { - log.Println(err) - } else { - _, err := cu.CreateCertificate(cname, NameSpaceName, c.IssuerName(oname), false) - if err != nil { - log.Println("Failed to create overlay[" + oname +"] certificate: " + err.Error()) - } else { - crts, key, err := cu.GetKeypair(cname, NameSpaceName) - if err != nil { - log.Println(err) - return "", "", err - } else { - crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] - return crt, key, nil - } - } - } - - return "", "", nil -} - -func (c *OverlayObjectManager) DeleteCertificate(cname string) (string, string, error) { - cu, err := GetCertUtil() - if err != nil { - log.Println(err) - } else { - err = cu.DeleteCertificate(cname, NameSpaceName) - if err != nil { - log.Println("Failed to delete " + cname +" certificate: " + err.Error()) - } - } - - return "", "", nil -} - -func (c *OverlayObjectManager) GetCertificate(oname string) (string, string, error) { - cu, err := GetCertUtil() - if err != nil { - log.Println(err) - } else { - cname := c.CertName(oname) - return cu.GetKeypair(cname, NameSpaceName) - } - return "", "", nil -} - -//Set up Connection between objects -//Passing the original map resource, the two objects, connection type("hub-to-hub", "hub-to-device", "device-to-device") and namespace name. -func (c *OverlayObjectManager) SetupConnection(m map[string]string, m1 module.ControllerObject, m2 module.ControllerObject, conntype string, namespace string) error { - //Get all proposals available in the overlay - proposal := GetManagerset().Proposal - proposals, err := proposal.GetObjects(m) - if len(proposals) == 0 || err != nil { - log.Println("Missing Proposal in the overlay\n") - return pkgerrors.New("Error in getting proposals") - } - var all_proposals []string - var proposalresources []*resource.ProposalResource - for i:= 0 ; i < len(proposals); i++ { - proposal_obj := proposals[i].(*module.ProposalObject) - all_proposals = append(all_proposals, proposal_obj.Metadata.Name) - pr := proposal_obj.ToResource() - proposalresources = append(proposalresources, pr) - } - - //Get the overlay cert - var root_ca string - root_ca = GetRootCA(m[OverlayResource]) - - var obj1_ipsec_resource resource.IpsecResource - var obj2_ipsec_resource resource.IpsecResource - var obj1_ip string - var obj2_ip string - - switch conntype { - case HUBTOHUB: - obj1 := m1.(*module.HubObject) - obj2 := m2.(*module.HubObject) - - obj1_ip = obj1.Status.Ip - obj2_ip = obj2.Status.Ip - - //Keypair - obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(),namespace) - if err != nil { - return err - } - obj2_crt, obj2_key, err := GetHubCertificate(obj2.GetCertName(),namespace) - if err != nil { - return err - } - - //IpsecResources - conn := resource.Connection{ - Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), - ConnectionType: CONN_TYPE, - Mode: MODE, - Mark: DEFAULT_MARK, - LocalUpDown: DEFAULT_UPDOWN, - CryptoProposal: all_proposals, - } - obj1_ipsec_resource = resource.IpsecResource{ - Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), - Type: VTI_MODE, - Remote: obj2_ip, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)), - PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)), - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+obj1.GetCertName(), - RemoteIdentifier: "CN="+obj2.GetCertName(), - CryptoProposal: all_proposals, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: conn, - } - obj2_ipsec_resource = resource.IpsecResource{ - Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name), - Type: VTI_MODE, - Remote: obj1_ip, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)), - PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)), - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+obj2.GetCertName(), - RemoteIdentifier: "CN="+obj1.GetCertName(), - CryptoProposal: all_proposals, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: conn, - } - // Todo: Hub-to-device connection - case HUBTODEVICE: - obj1 := m1.(*module.HubObject) - obj2 := m2.(*module.DeviceObject) - - obj1_ip := obj1.Status.Ip - obj2_ip := obj2.Status.Ip - - //Keypair - obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(),namespace) - if err != nil { - return err - } - - obj1_conn := resource.Connection{ - Name: DEFAULT_CONN + format_resource_name(obj2.Metadata.Name, ""), - ConnectionType: CONN_TYPE, - Mode: MODE, - Mark: DEFAULT_MARK, - RemoteSourceIp: obj2_ip, - LocalUpDown: DEFAULT_UPDOWN, - CryptoProposal: all_proposals, - } - - obj1_ipsec_resource = resource.IpsecResource{ - Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), - Type: VTI_MODE, - Remote: ANY, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)), - PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)), - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+obj1.GetCertName(), - RemoteIdentifier: "CN="+obj2.GetCertName(), - CryptoProposal: all_proposals, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: obj1_conn, - } - - obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name) - if err != nil { - return err - } - - //IpsecResources - obj2_conn := resource.Connection{ - Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, ""), - Mode: MODE, - LocalUpDown: IPTABLES_UPDOWN, - ConnectionType: CONN_TYPE, - LocalSourceIp: BYCONFIG, - CryptoProposal: all_proposals, - } - obj2_ipsec_resource = resource.IpsecResource{ - Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name), - Type: POLICY_MODE, - Remote: obj1_ip, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: obj2_crt, - PrivateCert: obj2_key, - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+obj2.GetCertName(), - RemoteIdentifier: "CN="+obj1.GetCertName(), - CryptoProposal: all_proposals, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: obj2_conn, - } - - //Todo: Device-to-device connection - case DEVICETODEVICE: - obj1 := m1.(*module.DeviceObject) - obj2 := m2.(*module.DeviceObject) - - obj1_ip := obj1.Status.Ip - obj2_ip := obj2.Status.Ip - - //Keypair - obj1_crt, obj1_key, err := GetDeviceCertificate(m[OverlayResource], obj1.Metadata.Name) - if err != nil { - return err - } - obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name) - if err != nil { - return err - } - - conn := resource.Connection{ - Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), - ConnectionType: CONN_TYPE, - Mode: MODE, - Mark: DEFAULT_MARK, - LocalUpDown: DEFAULT_UPDOWN, - CryptoProposal: all_proposals, - } - obj1_ipsec_resource = resource.IpsecResource{ - Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), - Type: POLICY_MODE, - Remote: obj2_ip, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)), - PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)), - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+obj1.GetCertName(), - RemoteIdentifier: "CN="+obj2.GetCertName(), - CryptoProposal: all_proposals, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: conn, - } - obj2_ipsec_resource = resource.IpsecResource{ - Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name), - Type: POLICY_MODE, - Remote: obj1_ip, - AuthenticationMethod: PUBKEY_AUTH, - PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)), - PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)), - SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), - LocalIdentifier: "CN="+obj2.GetCertName(), - RemoteIdentifier: "CN="+obj1.GetCertName(), - CryptoProposal: all_proposals, - ForceCryptoProposal: FORCECRYPTOPROPOSAL, - Connections: conn, - } - default: - return pkgerrors.New("Unknown connection type") - } - - cend1 := module.NewConnectionEnd(m1, obj1_ip) - cend2 := module.NewConnectionEnd(m2, obj2_ip) - - cend1.AddResource(&obj1_ipsec_resource, false) - cend2.AddResource(&obj2_ipsec_resource, false) - - for i :=0; i < len(proposalresources); i++ { - cend1.AddResource(proposalresources[i], true) - cend2.AddResource(proposalresources[i], true) - } - - co := module.NewConnectionObject(cend1, cend2) - - cm := GetConnectionManager() - err = cm.Deploy(m[OverlayResource], co) - if err != nil { - return pkgerrors.Wrap(err, "Unable to create the object: fail to deploy resource") - } - - return nil -} +/* +* 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 manager + +import ( + "encoding/base64" + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" + "log" + "strings" +) + +const DEFAULT_MARK = "30" +const VTI_MODE = "VTI-based" +const POLICY_MODE = "policy-based" +const PUBKEY_AUTH = "pubkey" +const FORCECRYPTOPROPOSAL = "0" +const DEFAULT_CONN = "Conn" +const DEFAULT_UPDOWN = "/etc/updown" +const IPTABLES_UPDOWN = "/usr/lib/ipsec/_updown iptables" +const OIP_UPDOWN = "/etc/updown_oip" +const CONN_TYPE = "tunnel" +const MODE = "start" +const OVERLAYIP = "overlayip" +const HUBTOHUB = "hub-to-hub" +const HUBTODEVICE = "hub-to-device" +const DEVICETODEVICE = "device-to-device" +const BYCONFIG = "%config" +const ANY = "%any" +const BASE_PROTOCOL = "TCP" +const DEFAULT_K8S_API_SERVER_PORT = "6443" +const ACCEPT = "ACCEPT" + +type OverlayObjectKey struct { + OverlayName string `json:"overlay-name"` +} + +// OverlayObjectManager implements the ControllerObjectManager +type OverlayObjectManager struct { + BaseObjectManager +} + +func NewOverlayObjectManager() *OverlayObjectManager { + return &OverlayObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "overlay", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *OverlayObjectManager) GetResourceName() string { + return OverlayResource +} + +func (c *OverlayObjectManager) IsOperationSupported(oper string) bool { + return true +} + +func (c *OverlayObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.OverlayObject{} +} + +func (c *OverlayObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + key := OverlayObjectKey{""} + + if isCollection == true { + return key, nil + } + + to := t.(*module.OverlayObject) + meta_name := to.Metadata.Name + res_name := m[OverlayResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.OverlayName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.OverlayName = meta_name + } + + return key, nil +} + +func (c *OverlayObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.OverlayObject + err := json.NewDecoder(r).Decode(&v) + + return &v, err +} + +func (c *OverlayObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // Create a issuer each overlay + to := t.(*module.OverlayObject) + overlay_name := to.Metadata.Name + cu, err := GetCertUtil() + if err != nil { + log.Println(err) + } else { + // create overlay ca + _, err := cu.CreateCertificate(c.CertName(overlay_name), NameSpaceName, RootCAIssuerName, true) + if err == nil { + // create overlay issuer + _, err := cu.CreateCAIssuer(c.IssuerName(overlay_name), NameSpaceName, c.CertName(overlay_name)) + if err != nil { + log.Println("Failed to create overlay[" + overlay_name + "] issuer: " + err.Error()) + } + } else { + log.Println("Failed to create overlay[" + overlay_name + "] certificate: " + err.Error()) + } + } + + // DB Operation + t, err = GetDBUtils().CreateObject(c, m, t) + + return t, err +} + +func (c *OverlayObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObject(c, m) + + return t, err +} + +func (c *OverlayObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObjects(c, m) + + return t, err +} + +func (c *OverlayObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().UpdateObject(c, m, t) + + return t, err +} + +func (c *OverlayObjectManager) DeleteObject(m map[string]string) error { + overlay_name := m[OverlayResource] + + // DB Operation + err := GetDBUtils().DeleteObject(c, m) + if err == nil { + cu, err := GetCertUtil() + if err != nil { + log.Println(err) + } else { + err = cu.DeleteIssuer(c.IssuerName(overlay_name), NameSpaceName) + if err != nil { + log.Println("Failed to delete overlay[" + overlay_name + "] issuer: " + err.Error()) + } + err = cu.DeleteCertificate(c.CertName(overlay_name), NameSpaceName) + if err != nil { + log.Println("Failed to delete overlay[" + overlay_name + "] certificate: " + err.Error()) + } + } + } + + return err +} + +func (c *OverlayObjectManager) IssuerName(name string) string { + return name + "-issuer" +} + +func (c *OverlayObjectManager) CertName(name string) string { + return name + "-cert" +} + +func (c *OverlayObjectManager) CreateCertificate(oname string, cname string) (string, string, error) { + cu, err := GetCertUtil() + if err != nil { + log.Println(err) + } else { + _, err := cu.CreateCertificate(cname, NameSpaceName, c.IssuerName(oname), false) + if err != nil { + log.Println("Failed to create overlay[" + oname + "] certificate: " + err.Error()) + } else { + crts, key, err := cu.GetKeypair(cname, NameSpaceName) + if err != nil { + log.Println(err) + return "", "", err + } else { + crt := strings.SplitAfter(crts, "-----END CERTIFICATE-----")[0] + return crt, key, nil + } + } + } + + return "", "", nil +} + +func (c *OverlayObjectManager) DeleteCertificate(cname string) (string, string, error) { + cu, err := GetCertUtil() + if err != nil { + log.Println(err) + } else { + err = cu.DeleteCertificate(cname, NameSpaceName) + if err != nil { + log.Println("Failed to delete " + cname + " certificate: " + err.Error()) + } + } + + return "", "", nil +} + +func (c *OverlayObjectManager) GetCertificate(oname string) (string, string, error) { + cu, err := GetCertUtil() + if err != nil { + log.Println(err) + } else { + cname := c.CertName(oname) + return cu.GetKeypair(cname, NameSpaceName) + } + return "", "", nil +} + +//Set up Connection between objects +//Passing the original map resource, the two objects, connection type("hub-to-hub", "hub-to-device", "device-to-device") and namespace name. +func (c *OverlayObjectManager) SetupConnection(m map[string]string, m1 module.ControllerObject, m2 module.ControllerObject, conntype string, namespace string) error { + //Get all proposals available in the overlay + proposal := GetManagerset().Proposal + proposals, err := proposal.GetObjects(m) + if len(proposals) == 0 || err != nil { + log.Println("Missing Proposal in the overlay\n") + return pkgerrors.New("Error in getting proposals") + } + var all_proposals []string + var proposalresources []*resource.ProposalResource + for i := 0; i < len(proposals); i++ { + proposal_obj := proposals[i].(*module.ProposalObject) + all_proposals = append(all_proposals, proposal_obj.Metadata.Name) + pr := proposal_obj.ToResource() + proposalresources = append(proposalresources, pr) + } + + //Get the overlay cert + var root_ca string + root_ca = GetRootCA(m[OverlayResource]) + + var obj1_ipsec_resource resource.IpsecResource + var obj2_ipsec_resource resource.IpsecResource + var obj1_ip string + var obj2_ip string + + switch conntype { + case HUBTOHUB: + obj1 := m1.(*module.HubObject) + obj2 := m2.(*module.HubObject) + + obj1_ip = obj1.Status.Ip + obj2_ip = obj2.Status.Ip + + //Keypair + obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(), namespace) + if err != nil { + return err + } + obj2_crt, obj2_key, err := GetHubCertificate(obj2.GetCertName(), namespace) + if err != nil { + return err + } + + //IpsecResources + conn := resource.Connection{ + Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), + ConnectionType: CONN_TYPE, + Mode: MODE, + Mark: DEFAULT_MARK, + LocalUpDown: DEFAULT_UPDOWN, + CryptoProposal: all_proposals, + } + obj1_ipsec_resource = resource.IpsecResource{ + Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), + Type: VTI_MODE, + Remote: obj2_ip, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)), + PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)), + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + obj1.GetCertName(), + RemoteIdentifier: "CN=" + obj2.GetCertName(), + CryptoProposal: all_proposals, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: conn, + } + obj2_ipsec_resource = resource.IpsecResource{ + Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name), + Type: VTI_MODE, + Remote: obj1_ip, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)), + PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)), + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + obj2.GetCertName(), + RemoteIdentifier: "CN=" + obj1.GetCertName(), + CryptoProposal: all_proposals, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: conn, + } + // Todo: Hub-to-device connection + case HUBTODEVICE: + obj1 := m1.(*module.HubObject) + obj2 := m2.(*module.DeviceObject) + + obj1_ip := obj1.Status.Ip + obj2_ip := obj2.Status.Ip + + //Keypair + obj1_crt, obj1_key, err := GetHubCertificate(obj1.GetCertName(), namespace) + if err != nil { + return err + } + + obj1_conn := resource.Connection{ + Name: DEFAULT_CONN + format_resource_name(obj2.Metadata.Name, ""), + ConnectionType: CONN_TYPE, + Mode: MODE, + Mark: DEFAULT_MARK, + RemoteSourceIp: obj2_ip, + LocalUpDown: DEFAULT_UPDOWN, + CryptoProposal: all_proposals, + } + + obj1_ipsec_resource = resource.IpsecResource{ + Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), + Type: VTI_MODE, + Remote: ANY, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)), + PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)), + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + obj1.GetCertName(), + RemoteIdentifier: "CN=" + obj2.GetCertName(), + CryptoProposal: all_proposals, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: obj1_conn, + } + + obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name) + if err != nil { + return err + } + + //IpsecResources + obj2_conn := resource.Connection{ + Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, ""), + Mode: MODE, + LocalUpDown: IPTABLES_UPDOWN, + ConnectionType: CONN_TYPE, + LocalSourceIp: BYCONFIG, + CryptoProposal: all_proposals, + } + obj2_ipsec_resource = resource.IpsecResource{ + Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name), + Type: POLICY_MODE, + Remote: obj1_ip, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: obj2_crt, + PrivateCert: obj2_key, + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + obj2.GetCertName(), + RemoteIdentifier: "CN=" + obj1.GetCertName(), + CryptoProposal: all_proposals, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: obj2_conn, + } + + //Todo: Device-to-device connection + case DEVICETODEVICE: + obj1 := m1.(*module.DeviceObject) + obj2 := m2.(*module.DeviceObject) + + obj1_ip := obj1.Status.Ip + obj2_ip := obj2.Status.Ip + + //Keypair + obj1_crt, obj1_key, err := GetDeviceCertificate(m[OverlayResource], obj1.Metadata.Name) + if err != nil { + return err + } + obj2_crt, obj2_key, err := GetDeviceCertificate(m[OverlayResource], obj2.Metadata.Name) + if err != nil { + return err + } + + conn := resource.Connection{ + Name: DEFAULT_CONN + format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), + ConnectionType: CONN_TYPE, + Mode: MODE, + Mark: DEFAULT_MARK, + LocalUpDown: DEFAULT_UPDOWN, + CryptoProposal: all_proposals, + } + obj1_ipsec_resource = resource.IpsecResource{ + Name: format_resource_name(obj1.Metadata.Name, obj2.Metadata.Name), + Type: POLICY_MODE, + Remote: obj2_ip, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: base64.StdEncoding.EncodeToString([]byte(obj1_crt)), + PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj1_key)), + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + obj1.GetCertName(), + RemoteIdentifier: "CN=" + obj2.GetCertName(), + CryptoProposal: all_proposals, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: conn, + } + obj2_ipsec_resource = resource.IpsecResource{ + Name: format_resource_name(obj2.Metadata.Name, obj1.Metadata.Name), + Type: POLICY_MODE, + Remote: obj1_ip, + AuthenticationMethod: PUBKEY_AUTH, + PublicCert: base64.StdEncoding.EncodeToString([]byte(obj2_crt)), + PrivateCert: base64.StdEncoding.EncodeToString([]byte(obj2_key)), + SharedCA: base64.StdEncoding.EncodeToString([]byte(root_ca)), + LocalIdentifier: "CN=" + obj2.GetCertName(), + RemoteIdentifier: "CN=" + obj1.GetCertName(), + CryptoProposal: all_proposals, + ForceCryptoProposal: FORCECRYPTOPROPOSAL, + Connections: conn, + } + default: + return pkgerrors.New("Unknown connection type") + } + + cend1 := module.NewConnectionEnd(m1, obj1_ip) + cend2 := module.NewConnectionEnd(m2, obj2_ip) + + cend1.AddResource(&obj1_ipsec_resource, false) + cend2.AddResource(&obj2_ipsec_resource, false) + + for i := 0; i < len(proposalresources); i++ { + cend1.AddResource(proposalresources[i], true) + cend2.AddResource(proposalresources[i], true) + } + + co := module.NewConnectionObject(cend1, cend2) + + cm := GetConnectionManager() + err = cm.Deploy(m[OverlayResource], co) + if err != nil { + return pkgerrors.Wrap(err, "Unable to create the object: fail to deploy resource") + } + + return nil +} diff --git a/central-controller/src/scc/pkg/manager/proposal_objectmanager.go b/central-controller/src/scc/pkg/manager/proposal_objectmanager.go index c1f93d5..8104ea7 100644 --- a/central-controller/src/scc/pkg/manager/proposal_objectmanager.go +++ b/central-controller/src/scc/pkg/manager/proposal_objectmanager.go @@ -1,132 +1,132 @@ -/* - * 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 manager - -import ( - "io" - "encoding/json" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - pkgerrors "github.com/pkg/errors" -) - -type ProposalObjectKey struct { - OverlayName string `json:"overlay-name"` - ProposalName string `json:"proposal-name"` -} - -// ProposalObjectManager implements the ControllerObjectManager -type ProposalObjectManager struct { - BaseObjectManager -} - -func NewProposalObjectManager() *ProposalObjectManager { - return &ProposalObjectManager{ - BaseObjectManager { - storeName: StoreName, - tagMeta: "proposal", - depResManagers: []ControllerObjectManager {}, - ownResManagers: []ControllerObjectManager {}, - }, - } -} - -func (c *ProposalObjectManager) GetResourceName() string { - return ProposalResource -} - -func (c *ProposalObjectManager) IsOperationSupported(oper string) bool { - return true -} - -func (c *ProposalObjectManager) CreateEmptyObject() module.ControllerObject { - return &module.ProposalObject{} -} - -func (c *ProposalObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { - overlay_name := m[OverlayResource] - key := ProposalObjectKey{ - OverlayName: overlay_name, - ProposalName: "", - } - - if isCollection == true { - return key, nil - } - - to := t.(*module.ProposalObject) - meta_name := to.Metadata.Name - res_name := m[ProposalResource] - - if res_name != "" { - if meta_name != "" && res_name != meta_name { - return key, pkgerrors.New("Resource name unmatched metadata name") - } - - key.ProposalName = res_name - } else { - if meta_name == "" { - return key, pkgerrors.New("Unable to find resource name") - } - - key.ProposalName = meta_name - } - - return key, nil; -} - -func (c *ProposalObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { - var v module.ProposalObject - err := json.NewDecoder(r).Decode(&v) - - return &v, err -} - -func (c *ProposalObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().CreateObject(c, m, t) - - return t, err -} - -func (c *ProposalObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObject(c, m) - - return t, err -} - -func (c *ProposalObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().GetObjects(c, m) - - return t, err -} - -func (c *ProposalObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { - // DB Operation - t, err := GetDBUtils().UpdateObject(c, m, t) - - return t, err -} - -func (c *ProposalObjectManager) DeleteObject(m map[string]string) error { - // DB Operation - err := GetDBUtils().DeleteObject(c, m) - - return err -} +/* + * 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 manager + +import ( + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db" + pkgerrors "github.com/pkg/errors" + "io" +) + +type ProposalObjectKey struct { + OverlayName string `json:"overlay-name"` + ProposalName string `json:"proposal-name"` +} + +// ProposalObjectManager implements the ControllerObjectManager +type ProposalObjectManager struct { + BaseObjectManager +} + +func NewProposalObjectManager() *ProposalObjectManager { + return &ProposalObjectManager{ + BaseObjectManager{ + storeName: StoreName, + tagMeta: "proposal", + depResManagers: []ControllerObjectManager{}, + ownResManagers: []ControllerObjectManager{}, + }, + } +} + +func (c *ProposalObjectManager) GetResourceName() string { + return ProposalResource +} + +func (c *ProposalObjectManager) IsOperationSupported(oper string) bool { + return true +} + +func (c *ProposalObjectManager) CreateEmptyObject() module.ControllerObject { + return &module.ProposalObject{} +} + +func (c *ProposalObjectManager) GetStoreKey(m map[string]string, t module.ControllerObject, isCollection bool) (db.Key, error) { + overlay_name := m[OverlayResource] + key := ProposalObjectKey{ + OverlayName: overlay_name, + ProposalName: "", + } + + if isCollection == true { + return key, nil + } + + to := t.(*module.ProposalObject) + meta_name := to.Metadata.Name + res_name := m[ProposalResource] + + if res_name != "" { + if meta_name != "" && res_name != meta_name { + return key, pkgerrors.New("Resource name unmatched metadata name") + } + + key.ProposalName = res_name + } else { + if meta_name == "" { + return key, pkgerrors.New("Unable to find resource name") + } + + key.ProposalName = meta_name + } + + return key, nil +} + +func (c *ProposalObjectManager) ParseObject(r io.Reader) (module.ControllerObject, error) { + var v module.ProposalObject + err := json.NewDecoder(r).Decode(&v) + + return &v, err +} + +func (c *ProposalObjectManager) CreateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().CreateObject(c, m, t) + + return t, err +} + +func (c *ProposalObjectManager) GetObject(m map[string]string) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObject(c, m) + + return t, err +} + +func (c *ProposalObjectManager) GetObjects(m map[string]string) ([]module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().GetObjects(c, m) + + return t, err +} + +func (c *ProposalObjectManager) UpdateObject(m map[string]string, t module.ControllerObject) (module.ControllerObject, error) { + // DB Operation + t, err := GetDBUtils().UpdateObject(c, m, t) + + return t, err +} + +func (c *ProposalObjectManager) DeleteObject(m map[string]string) error { + // DB Operation + err := GetDBUtils().DeleteObject(c, m) + + return err +} diff --git a/central-controller/src/scc/pkg/manager/resutils.go b/central-controller/src/scc/pkg/manager/resutils.go index c8916c1..2103130 100644 --- a/central-controller/src/scc/pkg/manager/resutils.go +++ b/central-controller/src/scc/pkg/manager/resutils.go @@ -1,493 +1,493 @@ -/* - * 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 manager - -import ( - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" - rsyncclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" - "github.com/open-ness/EMCO/src/orchestrator/pkg/resourcestatus" - - "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext" -// rsyncclient "github.com/open-ness/EMCO/src/orchestrator/pkg/grpc/installappclient" - controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller" - "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc" - - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/wait" - - "log" - "fmt" - "time" - "encoding/json" - pkgerrors "github.com/pkg/errors" -) - -var rsync_initialized = false -var provider_name = "akraino_scc" -var project_name = "akraino_scc" - -// sdewan definition -type DeployResource struct { - Action string - Resource resource.ISdewanResource -} - -type DeployResources struct { - Resources []DeployResource -} - -type ReadResource struct { - Gvk schema.GroupVersionKind `json:"GVK,omitempty"` - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` -} - -type QueryResource struct { - Handle interface{} - Resource ReadResource -} - -type QueryResources struct { - Resources []*QueryResource -} - -type ResUtil struct { - resmap map[module.ControllerObject]*DeployResources - qryResmap map[module.ControllerObject]*QueryResources - qryCtxId string -} - -func NewResUtil() *ResUtil { - if rsync_initialized == false { - rsync_initialized = InitRsyncClient() - } - - return &ResUtil{ - resmap: make(map[module.ControllerObject]*DeployResources), - qryResmap: make(map[module.ControllerObject]*QueryResources), - qryCtxId: "", - } -} - -type contextForCompositeApp struct { - context appcontext.AppContext - ctxval interface{} - compositeAppHandle interface{} -} - -func makeAppContextForCompositeApp(p, ca, v, rName, dig string, namespace string, level string) (contextForCompositeApp, error) { - // ctxval: context.rtcObj.id - context := appcontext.AppContext{} - ctxval, err := context.InitAppContext() - if err != nil { - return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating AppContext CompositeApp") - } - compositeHandle, err := context.CreateCompositeApp() - if err != nil { - return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating CompositeApp handle") - } - err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName, DeploymentIntentGroup: dig, Namespace: namespace, Level: level}) - if err != nil { - return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error Adding CompositeAppMeta") - } - - //_, err = context.GetCompositeAppMeta() - - log.Println(":: The meta data stored in the runtime context :: ") - - cca := contextForCompositeApp{context: context, ctxval: ctxval, compositeAppHandle: compositeHandle} - - return cca, nil -} - -func addResourcesToCluster(ct appcontext.AppContext, ch interface{}, target string, resources []DeployResource, isDeploy bool) error { - - var resOrderInstr struct { - Resorder []string `json:"resorder"` - } - - var resDepInstr struct { - Resdep map[string]string `json:"resdependency"` - } - resdep := make(map[string]string) - - for _, resource := range resources { - resource_name := resource.Resource.GetName() + "+" + resource.Resource.GetType() - resource_data := resource.Resource.ToYaml(target) - resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name) - resdep[resource_name] = "go" - // rtc.RtcAddResource("/app/app_name/cluster/clusername/", res.name, res.content) - // -> save ("/app/app_name/cluster/clusername/resource/res.name/", res.content) in etcd - // return ("/app/app_name/cluster/clusername/resource/res.name/" - rh, err := ct.AddResource(ch, resource_name, resource_data) - if isDeploy == false { - //Delete resource - ct.AddLevelValue(rh, "status", resourcestatus.ResourceStatus{Status:resourcestatus.RsyncStatusEnum.Applied}) - } - if err != nil { - cleanuperr := ct.DeleteCompositeApp() - if cleanuperr != nil { - log.Printf(":: Error Cleaning up AppContext after add resource failure ::") - } - return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name) - } - jresOrderInstr, _ := json.Marshal(resOrderInstr) - resDepInstr.Resdep = resdep - jresDepInstr, _ := json.Marshal(resDepInstr) - // rtc.RtcAddInstruction("app/app_name/cluster/clusername/", "resource", "order", "{[res.name]}") - // ->save ("/app/app_name/cluster/clusername/resource/instruction/order/", "{[res.name]}") in etcd - // return "/app/app_name/cluster/clusername/resource/instruction/order/" - _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr)) - _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr)) - if err != nil { - cleanuperr := ct.DeleteCompositeApp() - if cleanuperr != nil { - log.Printf(":: Error Cleaning up AppContext after add instruction failure ::") - } - return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name) - } - } - return nil -} - -func InitRsyncClient() bool { - client := controller.NewControllerClient() - - vals, _ := client.GetControllers() - found := false - for _, v := range vals { - if v.Metadata.Name == "rsync" { - log.Println("Initializing RPC connection to resource synchronizer") - rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port) - found = true - break - } - } - return found -} - -func initializeAppContextStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error { - h, err := ac.GetCompositeAppHandle() - if err != nil { - return err - } - sh, err := ac.GetLevelHandle(h, "status") - if sh == nil { - _, err = ac.AddLevelValue(h, "status", acStatus) - } else { - err = ac.UpdateValue(sh, acStatus) - } - if err != nil { - return err - } - return nil -} - -func (d *ResUtil) contains(reses []DeployResource, res DeployResource) bool { - for _, r := range reses { - if r.Action == res.Action && - r.Resource.GetName() == res.Resource.GetName() && - r.Resource.GetType() == res.Resource.GetType() { - return true - } - } - - return false -} - -func (d *ResUtil) AddResource(device module.ControllerObject, action string, resource resource.ISdewanResource) error { - if d.resmap[device] == nil { - d.resmap[device] = &DeployResources{Resources: []DeployResource{}} - } - - ds := DeployResource{Action: action, Resource: resource,} - if !d.contains(d.resmap[device].Resources, ds) { - d.resmap[device].Resources = append(d.resmap[device].Resources, ds) - } - return nil -} - -func (d *ResUtil) TargetName (o module.ControllerObject) string { - return o.GetType() + "." + o.GetMetadata().Name -} - -func (d *ResUtil) Deploy(app_name string, format string) (string, error) { - // Generate Application context - cca, err := makeAppContextForCompositeApp(project_name, app_name + "-d", "1.0", "1.0", "di", "default", "0") - context := cca.context // appcontext.AppContext - ctxval := cca.ctxval // id - compositeHandle := cca.compositeAppHandle // cid - - var appOrderInstr struct { - Apporder []string `json:"apporder"` - } - var appDepInstr struct { - Appdep map[string]string `json:"appdependency"` - } - appdep := make(map[string]string) - // create a com_app for each device - for device, res := range d.resmap { - // Add application - app_name := device.GetMetadata().Name + "-app" - appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name) - appdep[app_name] = "go" - - // rtc.RtcAddLevel(cid, "app", app_name) -> save ("app/app_name/", app_name) in etcd - // apphandle = "app/app_name/" - apphandle, _ := context.AddApp(compositeHandle, app_name) - - // Add cluster - // err = addClustersToAppContext(listOfClusters, context, apphandle, resources) - // rtc.RtcAddLevel("app/app_name/", "cluster", clustername) - // -> save ("app/app_name/cluster/clusername/", clustername) in etcd - // return "app/app_name/cluster/clusername/" - clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name) - err = addResourcesToCluster(context, clusterhandle, d.TargetName(device), res.Resources, true) - } - - jappOrderInstr, _ := json.Marshal(appOrderInstr) - appDepInstr.Appdep = appdep - jappDepInstr, _ := json.Marshal(appDepInstr) - context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr)) - context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr)) - - // invoke deployment process - appContextID := fmt.Sprintf("%v", ctxval) - err = rsyncclient.InvokeInstallApp(appContextID) - if err != nil { - log.Println(err) - return appContextID, err - } - - return appContextID, nil -} - -func (d *ResUtil) Undeploy(app_name string, format string) (string, error) { - // Generate Application context - cca, err := makeAppContextForCompositeApp(project_name, app_name + "-u", "1.0", "1.0", "di", "default", "0") - context := cca.context // appcontext.AppContext - ctxval := cca.ctxval // id - compositeHandle := cca.compositeAppHandle // cid - - var appOrderInstr struct { - Apporder []string `json:"apporder"` - } - var appDepInstr struct { - Appdep map[string]string `json:"appdependency"` - } - appdep := make(map[string]string) - // create a com_app for each device - for device, res := range d.resmap { - // Add application - app_name := device.GetMetadata().Name + "-app" - appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name) - appdep[app_name] = "go" - apphandle, _ := context.AddApp(compositeHandle, app_name) - - // Add cluster - clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name) - err = addResourcesToCluster(context, clusterhandle, d.TargetName(device), res.Resources, false) - } - - jappOrderInstr, _ := json.Marshal(appOrderInstr) - appDepInstr.Appdep = appdep - jappDepInstr, _ := json.Marshal(appDepInstr) - context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr)) - context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr)) - - initializeAppContextStatus(context, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiated}) - // invoke deployment process - appContextID := fmt.Sprintf("%v", ctxval) - err = rsyncclient.InvokeUninstallApp(appContextID) - if err != nil { - log.Println(err) - return appContextID, err - } - - return appContextID, nil -} - -func (d *ResUtil) AddQueryResource(device module.ControllerObject, resource QueryResource) error { - if d.qryResmap[device] == nil { - d.qryResmap[device] = &QueryResources{Resources: []*QueryResource{}} - } - - d.qryResmap[device].Resources = append(d.qryResmap[device].Resources, &resource) - d.qryCtxId = "" - - return nil -} - -func addQueryResourcesToCluster(ct appcontext.AppContext, ch interface{}, resources *[]*QueryResource) error { - - var resOrderInstr struct { - Resorder []string `json:"resorder"` - } - - var resDepInstr struct { - Resdep map[string]string `json:"resdependency"` - } - resdep := make(map[string]string) - - for _, resource := range *resources { - resource_name := resource.Resource.Namespace + "+" + resource.Resource.Name - v, _ := json.Marshal(resource.Resource) - resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name) - resdep[resource_name] = "go" - - rh, err := ct.AddResource(ch, resource_name, string(v)) - - if err != nil { - return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name) - } - - // save the resource handler for query result - resource.Handle = rh - - jresOrderInstr, _ := json.Marshal(resOrderInstr) - resDepInstr.Resdep = resdep - jresDepInstr, _ := json.Marshal(resDepInstr) - - _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr)) - _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr)) - if err != nil { - return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name) - } - } - return nil -} - -func (d *ResUtil) Query(app_name string) (string, error) { - if d.qryCtxId == "" { - // Generate Application context - cca, err := makeAppContextForCompositeApp(project_name, app_name + "-d", "1.0", "1.0", "di", "default", "0") - if err != nil { - log.Println(err) - return "", err - } - - context := cca.context // appcontext.AppContext - ctxval := cca.ctxval // id - compositeHandle := cca.compositeAppHandle // cid - - var appOrderInstr struct { - Apporder []string `json:"apporder"` - } - var appDepInstr struct { - Appdep map[string]string `json:"appdependency"` - } - appdep := make(map[string]string) - // create a com_app for each device - for device, res := range d.qryResmap { - // Add application - app_name := device.GetMetadata().Name + "-query-app" - appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name) - appdep[app_name] = "go" - - apphandle, _ := context.AddApp(compositeHandle, app_name) - - // Add cluster - clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name) - err = addQueryResourcesToCluster(context, clusterhandle, &res.Resources) - } - - jappOrderInstr, _ := json.Marshal(appOrderInstr) - appDepInstr.Appdep = appdep - jappDepInstr, _ := json.Marshal(appDepInstr) - context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr)) - context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr)) - - // invoke query process - appContextID := fmt.Sprintf("%v", ctxval) - d.qryCtxId = appContextID - } - - err := rsyncclient.InvokeGetResource(d.qryCtxId) - if err != nil { - log.Println(err) - d.qryCtxId = "" - return "", err - } - - return d.qryCtxId, nil -} - -func (d *ResUtil) GetResourceData(device module.ControllerObject, ns string, name string) (string, error) { - if d.qryCtxId == "" { - return "", pkgerrors.New("Query failed to be executed.") - } - - var ac appcontext.AppContext - ah, err := ac.LoadAppContext(d.qryCtxId) - if err != nil { - return "", pkgerrors.Wrap(err, "AppContext is not found.") - } - - // wait for resource ready - err = wait.PollImmediate(time.Second, time.Second*20, - func() (bool, error) { - sh, err := ac.GetLevelHandle(ah, "status") - if err != nil { - log.Println("Waiting for Resource status to be ready.") - return false, nil - } - - s, err := ac.GetValue(sh) - if err != nil { - log.Println("Waiting for Resource status to be ready..") - return false, nil - } - - acStatus := appcontext.AppContextStatus{} - js, _ := json.Marshal(s) - json.Unmarshal(js, &acStatus) - log.Println(acStatus.Status) - if acStatus.Status == appcontext.AppContextStatusEnum.Instantiated { - return true, nil - } - - log.Println("Waiting for Resource status to be ready...") - return false, nil - }, - ) - - if err != nil { - log.Println(err) - return "", pkgerrors.Wrap(err, "Resource is not available") - } - - // found resource handle - if d.qryResmap[device] == nil { - return "", pkgerrors.Wrap(err, "No query resource found.") - } - - for _, resource := range d.qryResmap[device].Resources { - if ns == resource.Resource.Namespace && name == resource.Resource.Name { - rdh, _ := ac.GetLevelHandle(resource.Handle, "definition") - if rdh != nil { - ret, err := ac.GetValue(rdh) - if err == nil { - return ret.(string), nil - } - } - return "", pkgerrors.Wrap(err, "Failed to query the resource value.") - } - } - - return "", pkgerrors.New("No query resource found.") -} \ No newline at end of file +/* + * 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 manager + +import ( + rsyncclient "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/client" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" + "github.com/open-ness/EMCO/src/orchestrator/pkg/resourcestatus" + + "github.com/open-ness/EMCO/src/orchestrator/pkg/appcontext" + // rsyncclient "github.com/open-ness/EMCO/src/orchestrator/pkg/grpc/installappclient" + "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc" + controller "github.com/open-ness/EMCO/src/orchestrator/pkg/module/controller" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + + "encoding/json" + "fmt" + pkgerrors "github.com/pkg/errors" + "log" + "time" +) + +var rsync_initialized = false +var provider_name = "akraino_scc" +var project_name = "akraino_scc" + +// sdewan definition +type DeployResource struct { + Action string + Resource resource.ISdewanResource +} + +type DeployResources struct { + Resources []DeployResource +} + +type ReadResource struct { + Gvk schema.GroupVersionKind `json:"GVK,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` +} + +type QueryResource struct { + Handle interface{} + Resource ReadResource +} + +type QueryResources struct { + Resources []*QueryResource +} + +type ResUtil struct { + resmap map[module.ControllerObject]*DeployResources + qryResmap map[module.ControllerObject]*QueryResources + qryCtxId string +} + +func NewResUtil() *ResUtil { + if rsync_initialized == false { + rsync_initialized = InitRsyncClient() + } + + return &ResUtil{ + resmap: make(map[module.ControllerObject]*DeployResources), + qryResmap: make(map[module.ControllerObject]*QueryResources), + qryCtxId: "", + } +} + +type contextForCompositeApp struct { + context appcontext.AppContext + ctxval interface{} + compositeAppHandle interface{} +} + +func makeAppContextForCompositeApp(p, ca, v, rName, dig string, namespace string, level string) (contextForCompositeApp, error) { + // ctxval: context.rtcObj.id + context := appcontext.AppContext{} + ctxval, err := context.InitAppContext() + if err != nil { + return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating AppContext CompositeApp") + } + compositeHandle, err := context.CreateCompositeApp() + if err != nil { + return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating CompositeApp handle") + } + err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName, DeploymentIntentGroup: dig, Namespace: namespace, Level: level}) + if err != nil { + return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error Adding CompositeAppMeta") + } + + //_, err = context.GetCompositeAppMeta() + + log.Println(":: The meta data stored in the runtime context :: ") + + cca := contextForCompositeApp{context: context, ctxval: ctxval, compositeAppHandle: compositeHandle} + + return cca, nil +} + +func addResourcesToCluster(ct appcontext.AppContext, ch interface{}, target string, resources []DeployResource, isDeploy bool) error { + + var resOrderInstr struct { + Resorder []string `json:"resorder"` + } + + var resDepInstr struct { + Resdep map[string]string `json:"resdependency"` + } + resdep := make(map[string]string) + + for _, resource := range resources { + resource_name := resource.Resource.GetName() + "+" + resource.Resource.GetType() + resource_data := resource.Resource.ToYaml(target) + resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name) + resdep[resource_name] = "go" + // rtc.RtcAddResource("/app/app_name/cluster/clusername/", res.name, res.content) + // -> save ("/app/app_name/cluster/clusername/resource/res.name/", res.content) in etcd + // return ("/app/app_name/cluster/clusername/resource/res.name/" + rh, err := ct.AddResource(ch, resource_name, resource_data) + if isDeploy == false { + //Delete resource + ct.AddLevelValue(rh, "status", resourcestatus.ResourceStatus{Status: resourcestatus.RsyncStatusEnum.Applied}) + } + if err != nil { + cleanuperr := ct.DeleteCompositeApp() + if cleanuperr != nil { + log.Printf(":: Error Cleaning up AppContext after add resource failure ::") + } + return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name) + } + jresOrderInstr, _ := json.Marshal(resOrderInstr) + resDepInstr.Resdep = resdep + jresDepInstr, _ := json.Marshal(resDepInstr) + // rtc.RtcAddInstruction("app/app_name/cluster/clusername/", "resource", "order", "{[res.name]}") + // ->save ("/app/app_name/cluster/clusername/resource/instruction/order/", "{[res.name]}") in etcd + // return "/app/app_name/cluster/clusername/resource/instruction/order/" + _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr)) + _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr)) + if err != nil { + cleanuperr := ct.DeleteCompositeApp() + if cleanuperr != nil { + log.Printf(":: Error Cleaning up AppContext after add instruction failure ::") + } + return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name) + } + } + return nil +} + +func InitRsyncClient() bool { + client := controller.NewControllerClient() + + vals, _ := client.GetControllers() + found := false + for _, v := range vals { + if v.Metadata.Name == "rsync" { + log.Println("Initializing RPC connection to resource synchronizer") + rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port) + found = true + break + } + } + return found +} + +func initializeAppContextStatus(ac appcontext.AppContext, acStatus appcontext.AppContextStatus) error { + h, err := ac.GetCompositeAppHandle() + if err != nil { + return err + } + sh, err := ac.GetLevelHandle(h, "status") + if sh == nil { + _, err = ac.AddLevelValue(h, "status", acStatus) + } else { + err = ac.UpdateValue(sh, acStatus) + } + if err != nil { + return err + } + return nil +} + +func (d *ResUtil) contains(reses []DeployResource, res DeployResource) bool { + for _, r := range reses { + if r.Action == res.Action && + r.Resource.GetName() == res.Resource.GetName() && + r.Resource.GetType() == res.Resource.GetType() { + return true + } + } + + return false +} + +func (d *ResUtil) AddResource(device module.ControllerObject, action string, resource resource.ISdewanResource) error { + if d.resmap[device] == nil { + d.resmap[device] = &DeployResources{Resources: []DeployResource{}} + } + + ds := DeployResource{Action: action, Resource: resource} + if !d.contains(d.resmap[device].Resources, ds) { + d.resmap[device].Resources = append(d.resmap[device].Resources, ds) + } + return nil +} + +func (d *ResUtil) TargetName(o module.ControllerObject) string { + return o.GetType() + "." + o.GetMetadata().Name +} + +func (d *ResUtil) Deploy(app_name string, format string) (string, error) { + // Generate Application context + cca, err := makeAppContextForCompositeApp(project_name, app_name+"-d", "1.0", "1.0", "di", "default", "0") + context := cca.context // appcontext.AppContext + ctxval := cca.ctxval // id + compositeHandle := cca.compositeAppHandle // cid + + var appOrderInstr struct { + Apporder []string `json:"apporder"` + } + var appDepInstr struct { + Appdep map[string]string `json:"appdependency"` + } + appdep := make(map[string]string) + // create a com_app for each device + for device, res := range d.resmap { + // Add application + app_name := device.GetMetadata().Name + "-app" + appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name) + appdep[app_name] = "go" + + // rtc.RtcAddLevel(cid, "app", app_name) -> save ("app/app_name/", app_name) in etcd + // apphandle = "app/app_name/" + apphandle, _ := context.AddApp(compositeHandle, app_name) + + // Add cluster + // err = addClustersToAppContext(listOfClusters, context, apphandle, resources) + // rtc.RtcAddLevel("app/app_name/", "cluster", clustername) + // -> save ("app/app_name/cluster/clusername/", clustername) in etcd + // return "app/app_name/cluster/clusername/" + clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name) + err = addResourcesToCluster(context, clusterhandle, d.TargetName(device), res.Resources, true) + } + + jappOrderInstr, _ := json.Marshal(appOrderInstr) + appDepInstr.Appdep = appdep + jappDepInstr, _ := json.Marshal(appDepInstr) + context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr)) + context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr)) + + // invoke deployment process + appContextID := fmt.Sprintf("%v", ctxval) + err = rsyncclient.InvokeInstallApp(appContextID) + if err != nil { + log.Println(err) + return appContextID, err + } + + return appContextID, nil +} + +func (d *ResUtil) Undeploy(app_name string, format string) (string, error) { + // Generate Application context + cca, err := makeAppContextForCompositeApp(project_name, app_name+"-u", "1.0", "1.0", "di", "default", "0") + context := cca.context // appcontext.AppContext + ctxval := cca.ctxval // id + compositeHandle := cca.compositeAppHandle // cid + + var appOrderInstr struct { + Apporder []string `json:"apporder"` + } + var appDepInstr struct { + Appdep map[string]string `json:"appdependency"` + } + appdep := make(map[string]string) + // create a com_app for each device + for device, res := range d.resmap { + // Add application + app_name := device.GetMetadata().Name + "-app" + appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name) + appdep[app_name] = "go" + apphandle, _ := context.AddApp(compositeHandle, app_name) + + // Add cluster + clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name) + err = addResourcesToCluster(context, clusterhandle, d.TargetName(device), res.Resources, false) + } + + jappOrderInstr, _ := json.Marshal(appOrderInstr) + appDepInstr.Appdep = appdep + jappDepInstr, _ := json.Marshal(appDepInstr) + context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr)) + context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr)) + + initializeAppContextStatus(context, appcontext.AppContextStatus{Status: appcontext.AppContextStatusEnum.Instantiated}) + // invoke deployment process + appContextID := fmt.Sprintf("%v", ctxval) + err = rsyncclient.InvokeUninstallApp(appContextID) + if err != nil { + log.Println(err) + return appContextID, err + } + + return appContextID, nil +} + +func (d *ResUtil) AddQueryResource(device module.ControllerObject, resource QueryResource) error { + if d.qryResmap[device] == nil { + d.qryResmap[device] = &QueryResources{Resources: []*QueryResource{}} + } + + d.qryResmap[device].Resources = append(d.qryResmap[device].Resources, &resource) + d.qryCtxId = "" + + return nil +} + +func addQueryResourcesToCluster(ct appcontext.AppContext, ch interface{}, resources *[]*QueryResource) error { + + var resOrderInstr struct { + Resorder []string `json:"resorder"` + } + + var resDepInstr struct { + Resdep map[string]string `json:"resdependency"` + } + resdep := make(map[string]string) + + for _, resource := range *resources { + resource_name := resource.Resource.Namespace + "+" + resource.Resource.Name + v, _ := json.Marshal(resource.Resource) + resOrderInstr.Resorder = append(resOrderInstr.Resorder, resource_name) + resdep[resource_name] = "go" + + rh, err := ct.AddResource(ch, resource_name, string(v)) + + if err != nil { + return pkgerrors.Wrapf(err, "Error adding resource ::%s to AppContext", resource_name) + } + + // save the resource handler for query result + resource.Handle = rh + + jresOrderInstr, _ := json.Marshal(resOrderInstr) + resDepInstr.Resdep = resdep + jresDepInstr, _ := json.Marshal(resDepInstr) + + _, err = ct.AddInstruction(ch, "resource", "order", string(jresOrderInstr)) + _, err = ct.AddInstruction(ch, "resource", "dependency", string(jresDepInstr)) + if err != nil { + return pkgerrors.Wrapf(err, "Error adding instruction for resource ::%s to AppContext", resource_name) + } + } + return nil +} + +func (d *ResUtil) Query(app_name string) (string, error) { + if d.qryCtxId == "" { + // Generate Application context + cca, err := makeAppContextForCompositeApp(project_name, app_name+"-d", "1.0", "1.0", "di", "default", "0") + if err != nil { + log.Println(err) + return "", err + } + + context := cca.context // appcontext.AppContext + ctxval := cca.ctxval // id + compositeHandle := cca.compositeAppHandle // cid + + var appOrderInstr struct { + Apporder []string `json:"apporder"` + } + var appDepInstr struct { + Appdep map[string]string `json:"appdependency"` + } + appdep := make(map[string]string) + // create a com_app for each device + for device, res := range d.qryResmap { + // Add application + app_name := device.GetMetadata().Name + "-query-app" + appOrderInstr.Apporder = append(appOrderInstr.Apporder, app_name) + appdep[app_name] = "go" + + apphandle, _ := context.AddApp(compositeHandle, app_name) + + // Add cluster + clusterhandle, _ := context.AddCluster(apphandle, provider_name+"+"+device.GetMetadata().Name) + err = addQueryResourcesToCluster(context, clusterhandle, &res.Resources) + } + + jappOrderInstr, _ := json.Marshal(appOrderInstr) + appDepInstr.Appdep = appdep + jappDepInstr, _ := json.Marshal(appDepInstr) + context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr)) + context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr)) + + // invoke query process + appContextID := fmt.Sprintf("%v", ctxval) + d.qryCtxId = appContextID + } + + err := rsyncclient.InvokeGetResource(d.qryCtxId) + if err != nil { + log.Println(err) + d.qryCtxId = "" + return "", err + } + + return d.qryCtxId, nil +} + +func (d *ResUtil) GetResourceData(device module.ControllerObject, ns string, name string) (string, error) { + if d.qryCtxId == "" { + return "", pkgerrors.New("Query failed to be executed.") + } + + var ac appcontext.AppContext + ah, err := ac.LoadAppContext(d.qryCtxId) + if err != nil { + return "", pkgerrors.Wrap(err, "AppContext is not found.") + } + + // wait for resource ready + err = wait.PollImmediate(time.Second, time.Second*20, + func() (bool, error) { + sh, err := ac.GetLevelHandle(ah, "status") + if err != nil { + log.Println("Waiting for Resource status to be ready.") + return false, nil + } + + s, err := ac.GetValue(sh) + if err != nil { + log.Println("Waiting for Resource status to be ready..") + return false, nil + } + + acStatus := appcontext.AppContextStatus{} + js, _ := json.Marshal(s) + json.Unmarshal(js, &acStatus) + log.Println(acStatus.Status) + if acStatus.Status == appcontext.AppContextStatusEnum.Instantiated { + return true, nil + } + + log.Println("Waiting for Resource status to be ready...") + return false, nil + }, + ) + + if err != nil { + log.Println(err) + return "", pkgerrors.Wrap(err, "Resource is not available") + } + + // found resource handle + if d.qryResmap[device] == nil { + return "", pkgerrors.Wrap(err, "No query resource found.") + } + + for _, resource := range d.qryResmap[device].Resources { + if ns == resource.Resource.Namespace && name == resource.Resource.Name { + rdh, _ := ac.GetLevelHandle(resource.Handle, "definition") + if rdh != nil { + ret, err := ac.GetValue(rdh) + if err == nil { + return ret.(string), nil + } + } + return "", pkgerrors.Wrap(err, "Failed to query the resource value.") + } + } + + return "", pkgerrors.New("No query resource found.") +} diff --git a/central-controller/src/scc/pkg/manager/utils.go b/central-controller/src/scc/pkg/manager/utils.go index 44194fe..f1a8ab1 100644 --- a/central-controller/src/scc/pkg/manager/utils.go +++ b/central-controller/src/scc/pkg/manager/utils.go @@ -1,28 +1,28 @@ -/* - * Copyright 2021 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 manager - -import ( - "strings" -) - -func format_resource_name(name1 string, name2 string) string { - name1 = strings.Replace(name1, "-", "", -1) - name2 = strings.Replace(name2, "-", "", -1) - - return strings.ToLower(name1+name2) -} +/* + * Copyright 2021 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 manager + +import ( + "strings" +) + +func format_resource_name(name1 string, name2 string) string { + name1 = strings.Replace(name1, "-", "", -1) + name2 = strings.Replace(name2, "-", "", -1) + + return strings.ToLower(name1 + name2) +} diff --git a/central-controller/src/scc/pkg/module/certificateobject.go b/central-controller/src/scc/pkg/module/certificateobject.go index 9f1bf3b..5835449 100644 --- a/central-controller/src/scc/pkg/module/certificateobject.go +++ b/central-controller/src/scc/pkg/module/certificateobject.go @@ -1,42 +1,42 @@ -/* - * 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 - -// App contains metadata for Apps -type CertificateObject struct { - Metadata ObjectMetaData `json:"metadata"` - Specification CertificateObjectSpec `json:"spec"` - Data CertificateObjectData `json:"data"` -} - -// CertificateObjectSpec contains the parameters -type CertificateObjectSpec struct { -} - -type CertificateObjectData struct { - RootCA string `json:"rootca"` - Ca string `json:"ca"` - Key string `json:"key"` -} - -func (c *CertificateObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *CertificateObject) GetType() string { - return "Certificate" -} \ No newline at end of file +/* + * 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 + +// App contains metadata for Apps +type CertificateObject struct { + Metadata ObjectMetaData `json:"metadata"` + Specification CertificateObjectSpec `json:"spec"` + Data CertificateObjectData `json:"data"` +} + +// CertificateObjectSpec contains the parameters +type CertificateObjectSpec struct { +} + +type CertificateObjectData struct { + RootCA string `json:"rootca"` + Ca string `json:"ca"` + Key string `json:"key"` +} + +func (c *CertificateObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *CertificateObject) GetType() string { + return "Certificate" +} diff --git a/central-controller/src/scc/pkg/module/cnfobject.go b/central-controller/src/scc/pkg/module/cnfobject.go index 2c5c78a..c3b5a6b 100644 --- a/central-controller/src/scc/pkg/module/cnfobject.go +++ b/central-controller/src/scc/pkg/module/cnfobject.go @@ -1,31 +1,31 @@ -/* - * 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 - -// App contains metadata for Apps -type CNFObject struct { - Metadata ObjectMetaData `json:"metadata"` - Status string `json:"status"` -} - -func (c *CNFObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *CNFObject) GetType() string { - return "CNF" -} \ No newline at end of file +/* + * 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 + +// App contains metadata for Apps +type CNFObject struct { + Metadata ObjectMetaData `json:"metadata"` + Status string `json:"status"` +} + +func (c *CNFObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *CNFObject) GetType() string { + return "CNF" +} diff --git a/central-controller/src/scc/pkg/module/connectionobject.go b/central-controller/src/scc/pkg/module/connectionobject.go index 6aeeae4..466b3ff 100644 --- a/central-controller/src/scc/pkg/module/connectionobject.go +++ b/central-controller/src/scc/pkg/module/connectionobject.go @@ -1,147 +1,146 @@ -/* - * 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 ( - "log" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" -) - - -type states struct { - Created string - Deployed string - Undeployed string - Error string -} - -var StateEnum = &states{ - Created: "Created", - Deployed: "Deployed", - Undeployed: "Undeployed", - Error: "Error", -} - -type ConnectionObject struct { - Metadata ObjectMetaData `json:"metadata"` - Info ConnectionInfo `json:"information"` -} - -//ConnectionInfo contains the connection information -type ConnectionInfo struct { - End1 ConnectionEnd `json:"end1"` - End2 ConnectionEnd `json:"end2"` - ContextId string `json:"-"` - State string `json:"state"` - ErrorMessage string `json:"message"` -} - -type ConnectionEnd struct { - Name string `json:"name"` - Type string `json:"type"` - IP string `json:"ip"` - ConnObject string `json:"-"` - Resources []string `json:"-"` - ReservedRes []string `json:"-"` -} - -func (c *ConnectionObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *ConnectionObject) GetType() string { - return "Connection" -} - -func CreateEndName(t string, n string) string { - return t + "." + n -} - -func CreateConnectionName(e1 string, e2 string) string { - return e1 + "-" + e2 -} - -func NewConnectionEnd(conn_obj ControllerObject, ip string) ConnectionEnd { - obj_str, err := GetObjectBuilder().ToString(conn_obj) - if err == nil { - return ConnectionEnd{ - Name: CreateEndName(conn_obj.GetType(), conn_obj.GetMetadata().Name), - Type: conn_obj.GetType(), - IP: ip, - ConnObject: obj_str, - Resources: []string{}, - ReservedRes: []string{}, - } - } else { - log.Println(err) - return ConnectionEnd{} - } -} - -func NewConnectionObject(end1 ConnectionEnd, end2 ConnectionEnd) ConnectionObject { - return ConnectionObject{ - Metadata: ObjectMetaData{CreateConnectionName(end1.Name, end2.Name), "", "", ""}, - Info: ConnectionInfo{ - End1: end1, - End2: end2, - ContextId: "", - State: StateEnum.Created, - ErrorMessage: "", - }, - } -} - -func (c *ConnectionEnd) contains(res resource.ISdewanResource, isReserved bool) bool { - if isReserved { - for _, r_str := range c.ReservedRes { - r, err := resource.GetResourceBuilder().ToObject(r_str) - if err == nil { - if r.GetName() == res.GetName() && - r.GetType() == res.GetType() { - return true - } - } - } - } else { - for _, r_str := range c.Resources { - r, err := resource.GetResourceBuilder().ToObject(r_str) - if err == nil { - if r.GetName() == res.GetName() && - r.GetType() == res.GetType() { - return true - } - } - } - } - - return false -} - -func (c *ConnectionEnd) AddResource(res resource.ISdewanResource, isReserved bool) error { - if !c.contains(res, isReserved) { - res_str, err := resource.GetResourceBuilder().ToString(res) - if err == nil { - if isReserved { - c.ReservedRes = append(c.ReservedRes, res_str) - } else { - c.Resources = append(c.Resources, res_str) - } - } - } - - return nil -} +/* + * 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/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" + "log" +) + +type states struct { + Created string + Deployed string + Undeployed string + Error string +} + +var StateEnum = &states{ + Created: "Created", + Deployed: "Deployed", + Undeployed: "Undeployed", + Error: "Error", +} + +type ConnectionObject struct { + Metadata ObjectMetaData `json:"metadata"` + Info ConnectionInfo `json:"information"` +} + +//ConnectionInfo contains the connection information +type ConnectionInfo struct { + End1 ConnectionEnd `json:"end1"` + End2 ConnectionEnd `json:"end2"` + ContextId string `json:"-"` + State string `json:"state"` + ErrorMessage string `json:"message"` +} + +type ConnectionEnd struct { + Name string `json:"name"` + Type string `json:"type"` + IP string `json:"ip"` + ConnObject string `json:"-"` + Resources []string `json:"-"` + ReservedRes []string `json:"-"` +} + +func (c *ConnectionObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *ConnectionObject) GetType() string { + return "Connection" +} + +func CreateEndName(t string, n string) string { + return t + "." + n +} + +func CreateConnectionName(e1 string, e2 string) string { + return e1 + "-" + e2 +} + +func NewConnectionEnd(conn_obj ControllerObject, ip string) ConnectionEnd { + obj_str, err := GetObjectBuilder().ToString(conn_obj) + if err == nil { + return ConnectionEnd{ + Name: CreateEndName(conn_obj.GetType(), conn_obj.GetMetadata().Name), + Type: conn_obj.GetType(), + IP: ip, + ConnObject: obj_str, + Resources: []string{}, + ReservedRes: []string{}, + } + } else { + log.Println(err) + return ConnectionEnd{} + } +} + +func NewConnectionObject(end1 ConnectionEnd, end2 ConnectionEnd) ConnectionObject { + return ConnectionObject{ + Metadata: ObjectMetaData{CreateConnectionName(end1.Name, end2.Name), "", "", ""}, + Info: ConnectionInfo{ + End1: end1, + End2: end2, + ContextId: "", + State: StateEnum.Created, + ErrorMessage: "", + }, + } +} + +func (c *ConnectionEnd) contains(res resource.ISdewanResource, isReserved bool) bool { + if isReserved { + for _, r_str := range c.ReservedRes { + r, err := resource.GetResourceBuilder().ToObject(r_str) + if err == nil { + if r.GetName() == res.GetName() && + r.GetType() == res.GetType() { + return true + } + } + } + } else { + for _, r_str := range c.Resources { + r, err := resource.GetResourceBuilder().ToObject(r_str) + if err == nil { + if r.GetName() == res.GetName() && + r.GetType() == res.GetType() { + return true + } + } + } + } + + return false +} + +func (c *ConnectionEnd) AddResource(res resource.ISdewanResource, isReserved bool) error { + if !c.contains(res, isReserved) { + res_str, err := resource.GetResourceBuilder().ToString(res) + if err == nil { + if isReserved { + c.ReservedRes = append(c.ReservedRes, res_str) + } else { + c.Resources = append(c.Resources, res_str) + } + } + } + + return nil +} diff --git a/central-controller/src/scc/pkg/module/controllerobject.go b/central-controller/src/scc/pkg/module/controllerobject.go index 22754a5..a194208 100644 --- a/central-controller/src/scc/pkg/module/controllerobject.go +++ b/central-controller/src/scc/pkg/module/controllerobject.go @@ -1,31 +1,31 @@ -/* - * 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 - -// ControllerObject define the basic functionality of ControllerObject -type ControllerObject interface { - GetMetadata() ObjectMetaData - GetType() string -} - -// ObjectMetaData contains the parameters -type ObjectMetaData struct { - Name string `json:"name" validate:"required,hostname_rfc1123"` - Description string `json:"description"` - UserData1 string `json:"userData1"` - UserData2 string `json:"userData2"` -} \ No newline at end of file +/* + * 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 + +// ControllerObject define the basic functionality of ControllerObject +type ControllerObject interface { + GetMetadata() ObjectMetaData + GetType() string +} + +// ObjectMetaData contains the parameters +type ObjectMetaData struct { + Name string `json:"name" validate:"required,hostname_rfc1123"` + Description string `json:"description"` + UserData1 string `json:"userData1"` + UserData2 string `json:"userData2"` +} diff --git a/central-controller/src/scc/pkg/module/deviceobject.go b/central-controller/src/scc/pkg/module/deviceobject.go index bbc7b52..1a27ebe 100644 --- a/central-controller/src/scc/pkg/module/deviceobject.go +++ b/central-controller/src/scc/pkg/module/deviceobject.go @@ -1,72 +1,72 @@ -/* - * 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 - -// App contains metadata for Apps -type DeviceObject struct { - Metadata ObjectMetaData `json:"metadata"` - Specification DeviceObjectSpec `json:"spec"` - Status DeviceObjectStatus `json:"-"` -} - -// DeviceObjectSpec contains the parameters -type DeviceObjectSpec struct { - PublicIps []string `json:"publicIps"` - ForceHubConnectivity bool `json:"forceHubConnectivity"` - ProxyHub string `json:"proxyHub"` - ProxyHubPort int `json:"proxyHubPort"` - UseHub4Internet bool `json:"useHub4Internet"` - DedicatedSFC bool `json:"dedicatedSFC"` - CertificateId string `json:"certificateId"` - KubeConfig string `json:"kubeConfig"` -} - -// DeviceObjectStatus -type DeviceObjectStatus struct { - // 1: use public ip 2: use hub as proxy - Mode int - // ip used for external connection - // if Mode=1, ip is one of public ip - // if Mode=2, ip is the OIP allocated by SCC - Ip string - // Status Data - Data map[string]string -} - -func (c *DeviceObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *DeviceObject) GetType() string { - return "Device" -} - -func (c *DeviceObject) IsProxyHub(hub_name string) bool { - if c.Status.Mode == 2 { - return c.Specification.ProxyHub == hub_name - } - - return false -} - -func init() { - GetObjectBuilder().Register("Device", &DeviceObject{}) -} - -func (c *DeviceObject) GetCertName() string { - return "device-" + c.Metadata.Name + "-cert" -} +/* + * 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 + +// App contains metadata for Apps +type DeviceObject struct { + Metadata ObjectMetaData `json:"metadata"` + Specification DeviceObjectSpec `json:"spec"` + Status DeviceObjectStatus `json:"-"` +} + +// DeviceObjectSpec contains the parameters +type DeviceObjectSpec struct { + PublicIps []string `json:"publicIps"` + ForceHubConnectivity bool `json:"forceHubConnectivity"` + ProxyHub string `json:"proxyHub"` + ProxyHubPort int `json:"proxyHubPort"` + UseHub4Internet bool `json:"useHub4Internet"` + DedicatedSFC bool `json:"dedicatedSFC"` + CertificateId string `json:"certificateId"` + KubeConfig string `json:"kubeConfig"` +} + +// DeviceObjectStatus +type DeviceObjectStatus struct { + // 1: use public ip 2: use hub as proxy + Mode int + // ip used for external connection + // if Mode=1, ip is one of public ip + // if Mode=2, ip is the OIP allocated by SCC + Ip string + // Status Data + Data map[string]string +} + +func (c *DeviceObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *DeviceObject) GetType() string { + return "Device" +} + +func (c *DeviceObject) IsProxyHub(hub_name string) bool { + if c.Status.Mode == 2 { + return c.Specification.ProxyHub == hub_name + } + + return false +} + +func init() { + GetObjectBuilder().Register("Device", &DeviceObject{}) +} + +func (c *DeviceObject) GetCertName() string { + return "device-" + c.Metadata.Name + "-cert" +} diff --git a/central-controller/src/scc/pkg/module/emptyobject.go b/central-controller/src/scc/pkg/module/emptyobject.go index 6f55544..21aae42 100644 --- a/central-controller/src/scc/pkg/module/emptyobject.go +++ b/central-controller/src/scc/pkg/module/emptyobject.go @@ -1,30 +1,30 @@ -/* - * 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 - -// App contains metadata for Apps -type EmptyObject struct { - Metadata ObjectMetaData `json:"metadata"` -} - -func (c *EmptyObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *EmptyObject) GetType() string { - return "Empty" -} \ No newline at end of file +/* + * 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 + +// App contains metadata for Apps +type EmptyObject struct { + Metadata ObjectMetaData `json:"metadata"` +} + +func (c *EmptyObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *EmptyObject) GetType() string { + return "Empty" +} diff --git a/central-controller/src/scc/pkg/module/hubdeviceobject.go b/central-controller/src/scc/pkg/module/hubdeviceobject.go index 27d7855..876b45a 100644 --- a/central-controller/src/scc/pkg/module/hubdeviceobject.go +++ b/central-controller/src/scc/pkg/module/hubdeviceobject.go @@ -1,36 +1,36 @@ -/* - * 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 - -// App contains metadata for Apps -type HubDeviceObject struct { - Metadata ObjectMetaData `json:"metadata"` - Specification HubDeviceObjectSpec `json:"spec"` -} - -//HubDeviceObjectSpec contains the parameters -type HubDeviceObjectSpec struct { - Device string `json:"device"` -} - -func (c *HubDeviceObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *HubDeviceObject) GetType() string { - return "HubDevice" -} \ No newline at end of file +/* + * 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 + +// App contains metadata for Apps +type HubDeviceObject struct { + Metadata ObjectMetaData `json:"metadata"` + Specification HubDeviceObjectSpec `json:"spec"` +} + +//HubDeviceObjectSpec contains the parameters +type HubDeviceObjectSpec struct { + Device string `json:"device"` +} + +func (c *HubDeviceObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *HubDeviceObject) GetType() string { + return "HubDevice" +} diff --git a/central-controller/src/scc/pkg/module/hubobject.go b/central-controller/src/scc/pkg/module/hubobject.go index 1fb77f2..70d221e 100644 --- a/central-controller/src/scc/pkg/module/hubobject.go +++ b/central-controller/src/scc/pkg/module/hubobject.go @@ -1,93 +1,92 @@ -/* - * 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 ( - "strconv" - pkgerrors "github.com/pkg/errors" -) - -const ( - MinProxyPort = 10000 - MaxProxyPort = 16000 -) - -// App contains metadata for Apps -type HubObject struct { - Metadata ObjectMetaData `json:"metadata"` - Specification HubObjectSpec `json:"spec"` - Status HubObjectStatus `json:"-"` -} - -//HubObjectSpec contains the parameters -type HubObjectSpec struct { - PublicIps []string `json:"publicIps"` - CertificateId string `json:"certificateId"` - KubeConfig string `json:"kubeConfig"` -} - -//HubObjectStatus -type HubObjectStatus struct { - Ip string - Data map[string]string - // Allocated proxy port for device - ProxyPort map[string]string -} - -func (c *HubObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - - -func (c *HubObject) GetCertName() string { - return "hub-" + c.Metadata.Name + "-cert" -} - -func (c *HubObject) GetType() string { - return "Hub" -} - -func (c *HubObject) IsProxyPortUsed(port int) bool { - _, ok := c.Status.ProxyPort[strconv.Itoa(port)] - return ok -} - -func (c *HubObject) SetProxyPort(port int, device string) { - c.Status.ProxyPort[strconv.Itoa(port)] = device -} - -func (c *HubObject) UnsetProxyPort(port int) { - delete(c.Status.ProxyPort, strconv.Itoa(port)) -} - -func (c *HubObject) GetProxyPort(port int) string { - return c.Status.ProxyPort[strconv.Itoa(port)] -} - -func (c *HubObject) AllocateProxyPort() (int, error) { - for i:=MinProxyPort; i o.Specification.MaxIp || c.Specification.MaxIp < o.Specification.MinIp { - return false - } - - return true -} - -func (c *IPRangeObject) InUsed() bool { - return (len(c.Status.Data) != 0) -} - -func (c *IPRangeObject) Allocate(name string) (string, error) { - i := c.Specification.MinIp - index := (c.Specification.MinIp-1)/8 - b := byte(math.Exp2(float64(7-(c.Specification.MinIp-1)%8))) - for i <= c.Specification.MaxIp { - if c.Status.Masks[index] & b == 0 { - c.Status.Masks[index] |= b - c.Status.Data[strconv.Itoa(i)] = name - return c.base() + strconv.Itoa(i), nil - } - if (i % 8 == 0) { - b = 0x80 - index += 1 - for c.Status.Masks[index] == 0xff { - // log.Println("by pass", index) - i += 8 - index += 1 - } - } else { - b = b / 2 - } - i = i + 1 - } - - return "", pkgerrors.New("No available IP") -} - -func (c *IPRangeObject) Free(sip string) error { - ip := 0 - i := strings.LastIndex(sip, ".") - if i == -1 { - return pkgerrors.New("invalid ip") - } else { - base_ip := sip[0:i+1] - if c.base() != base_ip { - return pkgerrors.New("ip is not in range") - } - - ip, _ = strconv.Atoi(sip[i+1:len(sip)]) - } - - if ip < c.Specification.MinIp || ip > c.Specification.MaxIp { - return pkgerrors.New("ip is not in range") - } - - index := (ip-1)/8 - b := byte(math.Exp2(float64(7-(ip-1)%8))) - if c.Status.Masks[index] & b == 0 { - return pkgerrors.New("ip is not allocated") - } - - delete(c.Status.Data, strconv.Itoa(ip)) - c.Status.Masks[index] &= (^b) - return nil -} - -func (c *IPRangeObject) FreeAll() error { - for sip, _ := range c.Status.Data { - ip, _ := strconv.Atoi(sip) - index := (ip-1)/8 - b := byte(math.Exp2(float64(7-(ip-1)%8))) - delete(c.Status.Data, sip) - c.Status.Masks[index] &= (^b) - } - return nil -} \ No newline at end of file +/* + * 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 ( + pkgerrors "github.com/pkg/errors" + "math" + "strconv" + "strings" +) + +// App contains metadata for Apps +type IPRangeObject struct { + Metadata ObjectMetaData `json:"metadata"` + Specification IPRangeObjectSpec `json:"spec"` + Status IPRangeObjectStatus `json:"-"` +} + +//IPRangeObjectSpec contains the parameters +type IPRangeObjectSpec struct { + Subnet string `json:"subnet" validate:"required,ipv4"` + MinIp int `json:"minIp" validate:"gte=1,lte=255"` + MaxIp int `json:"maxIp" validate:"gte=1,lte=255"` +} + +type IPRangeObjectStatus struct { + Masks [32]byte + Data map[string]string +} + +func (c *IPRangeObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *IPRangeObject) GetType() string { + return "IPRange" +} + +func (c *IPRangeObject) base() string { + index := strings.LastIndex(c.Specification.Subnet, ".") + if index == -1 { + return c.Specification.Subnet + } else { + return c.Specification.Subnet[0 : index+1] + } +} + +func (c *IPRangeObject) IsConflict(o *IPRangeObject) bool { + if strings.Compare(c.base(), o.base()) != 0 { + return false + } + + if c.Specification.MinIp > o.Specification.MaxIp || c.Specification.MaxIp < o.Specification.MinIp { + return false + } + + return true +} + +func (c *IPRangeObject) InUsed() bool { + return (len(c.Status.Data) != 0) +} + +func (c *IPRangeObject) Allocate(name string) (string, error) { + i := c.Specification.MinIp + index := (c.Specification.MinIp - 1) / 8 + b := byte(math.Exp2(float64(7 - (c.Specification.MinIp-1)%8))) + for i <= c.Specification.MaxIp { + if c.Status.Masks[index]&b == 0 { + c.Status.Masks[index] |= b + c.Status.Data[strconv.Itoa(i)] = name + return c.base() + strconv.Itoa(i), nil + } + if i%8 == 0 { + b = 0x80 + index += 1 + for c.Status.Masks[index] == 0xff { + // log.Println("by pass", index) + i += 8 + index += 1 + } + } else { + b = b / 2 + } + i = i + 1 + } + + return "", pkgerrors.New("No available IP") +} + +func (c *IPRangeObject) Free(sip string) error { + ip := 0 + i := strings.LastIndex(sip, ".") + if i == -1 { + return pkgerrors.New("invalid ip") + } else { + base_ip := sip[0 : i+1] + if c.base() != base_ip { + return pkgerrors.New("ip is not in range") + } + + ip, _ = strconv.Atoi(sip[i+1 : len(sip)]) + } + + if ip < c.Specification.MinIp || ip > c.Specification.MaxIp { + return pkgerrors.New("ip is not in range") + } + + index := (ip - 1) / 8 + b := byte(math.Exp2(float64(7 - (ip-1)%8))) + if c.Status.Masks[index]&b == 0 { + return pkgerrors.New("ip is not allocated") + } + + delete(c.Status.Data, strconv.Itoa(ip)) + c.Status.Masks[index] &= (^b) + return nil +} + +func (c *IPRangeObject) FreeAll() error { + for sip, _ := range c.Status.Data { + ip, _ := strconv.Atoi(sip) + index := (ip - 1) / 8 + b := byte(math.Exp2(float64(7 - (ip-1)%8))) + delete(c.Status.Data, sip) + c.Status.Masks[index] &= (^b) + } + return nil +} diff --git a/central-controller/src/scc/pkg/module/objectbuilder.go b/central-controller/src/scc/pkg/module/objectbuilder.go index d84a278..c702cb8 100644 --- a/central-controller/src/scc/pkg/module/objectbuilder.go +++ b/central-controller/src/scc/pkg/module/objectbuilder.go @@ -1,64 +1,64 @@ -/* - * Copyright 2020 Intel Corporation, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package module - -import ( - "strings" - "reflect" - "encoding/json" - pkgerrors "github.com/pkg/errors" -) - -type ObjectBuilder struct { - omap map[string]reflect.Type -} - -var obj_builder = ObjectBuilder{ - omap: make(map[string]reflect.Type), -} - -func GetObjectBuilder() *ObjectBuilder { - return &obj_builder -} - -func (c *ObjectBuilder) Register(name string, r interface{}) { - c.omap[name] = reflect.TypeOf(r).Elem() -} - -func (c *ObjectBuilder) ToString(obj ControllerObject) (string, error) { - obj_str, err := json.Marshal(obj) - if err != nil { - return "", err - } - - return obj.GetType() + "-" + string(obj_str), nil -} - -func (c *ObjectBuilder) ToObject(obj_str string) (ControllerObject, error) { - if !strings.Contains(obj_str, "-") { - return &EmptyObject{}, pkgerrors.New("Not a valid object") - } - strs := strings.SplitN(obj_str, "-", 2) - - if v, ok := c.omap[strs[0]]; ok { - retObj := reflect.New(v).Interface() - err := json.Unmarshal([]byte(strs[1]), retObj) - return retObj.(ControllerObject), err - } else { - return &EmptyObject{}, pkgerrors.New("Not a valid object") - } -} +/* + * 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" + pkgerrors "github.com/pkg/errors" + "reflect" + "strings" +) + +type ObjectBuilder struct { + omap map[string]reflect.Type +} + +var obj_builder = ObjectBuilder{ + omap: make(map[string]reflect.Type), +} + +func GetObjectBuilder() *ObjectBuilder { + return &obj_builder +} + +func (c *ObjectBuilder) Register(name string, r interface{}) { + c.omap[name] = reflect.TypeOf(r).Elem() +} + +func (c *ObjectBuilder) ToString(obj ControllerObject) (string, error) { + obj_str, err := json.Marshal(obj) + if err != nil { + return "", err + } + + return obj.GetType() + "-" + string(obj_str), nil +} + +func (c *ObjectBuilder) ToObject(obj_str string) (ControllerObject, error) { + if !strings.Contains(obj_str, "-") { + return &EmptyObject{}, pkgerrors.New("Not a valid object") + } + strs := strings.SplitN(obj_str, "-", 2) + + if v, ok := c.omap[strs[0]]; ok { + retObj := reflect.New(v).Interface() + err := json.Unmarshal([]byte(strs[1]), retObj) + return retObj.(ControllerObject), err + } else { + return &EmptyObject{}, pkgerrors.New("Not a valid object") + } +} diff --git a/central-controller/src/scc/pkg/module/overlayobject.go b/central-controller/src/scc/pkg/module/overlayobject.go index 9f398c6..64d9aaa 100644 --- a/central-controller/src/scc/pkg/module/overlayobject.go +++ b/central-controller/src/scc/pkg/module/overlayobject.go @@ -1,35 +1,35 @@ -/* - * 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 - -// App contains metadata for Apps -type OverlayObject struct { - Metadata ObjectMetaData `json:"metadata"` - Specification OverlayObjectSpec `json:"spec"` -} - -//OverlayObjectSpec contains the parameters -type OverlayObjectSpec struct { -} - -func (c *OverlayObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *OverlayObject) GetType() string { - return "Overlay" -} \ No newline at end of file +/* + * 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 + +// App contains metadata for Apps +type OverlayObject struct { + Metadata ObjectMetaData `json:"metadata"` + Specification OverlayObjectSpec `json:"spec"` +} + +//OverlayObjectSpec contains the parameters +type OverlayObjectSpec struct { +} + +func (c *OverlayObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *OverlayObject) GetType() string { + return "Overlay" +} diff --git a/central-controller/src/scc/pkg/module/proposalobject.go b/central-controller/src/scc/pkg/module/proposalobject.go index cdb1e6f..f989170 100644 --- a/central-controller/src/scc/pkg/module/proposalobject.go +++ b/central-controller/src/scc/pkg/module/proposalobject.go @@ -1,51 +1,51 @@ -/* - * 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/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" -) - -// App contains metadata for Apps -type ProposalObject struct { - Metadata ObjectMetaData `json:"metadata"` - Specification ProposalObjectSpec `json:"spec"` -} - -//ProposalObjectSpec contains the parameters -type ProposalObjectSpec struct { - Encryption string `json:"encryption"` - Hash string `json:"hash"` - DhGroup string `json:"dhGroup"` -} - -func (c *ProposalObject) GetMetadata() ObjectMetaData { - return c.Metadata -} - -func (c *ProposalObject) GetType() string { - return "Proposal" -} - -func (c *ProposalObject) ToResource() *resource.ProposalResource { - return &resource.ProposalResource{ - Name: c.Metadata.Name, - Encryption: c.Specification.Encryption, - Hash: c.Specification.Hash, - DhGroup: c.Specification.DhGroup, - } -} \ No newline at end of file +/* + * 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/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/resource" +) + +// App contains metadata for Apps +type ProposalObject struct { + Metadata ObjectMetaData `json:"metadata"` + Specification ProposalObjectSpec `json:"spec"` +} + +//ProposalObjectSpec contains the parameters +type ProposalObjectSpec struct { + Encryption string `json:"encryption"` + Hash string `json:"hash"` + DhGroup string `json:"dhGroup"` +} + +func (c *ProposalObject) GetMetadata() ObjectMetaData { + return c.Metadata +} + +func (c *ProposalObject) GetType() string { + return "Proposal" +} + +func (c *ProposalObject) ToResource() *resource.ProposalResource { + return &resource.ProposalResource{ + Name: c.Metadata.Name, + Encryption: c.Specification.Encryption, + Hash: c.Specification.Hash, + DhGroup: c.Specification.DhGroup, + } +} diff --git a/central-controller/src/scc/pkg/resource/empty_resource.go b/central-controller/src/scc/pkg/resource/empty_resource.go index 814218c..52db254 100644 --- a/central-controller/src/scc/pkg/resource/empty_resource.go +++ b/central-controller/src/scc/pkg/resource/empty_resource.go @@ -1,35 +1,34 @@ -/* - * 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 resource - -import ( -) - -type EmptyResource struct { -} - -func (c *EmptyResource) GetName() string { - return "" -} - -func (c *EmptyResource) GetType() string { - return "Empty" -} - -func (c *EmptyResource) ToYaml(target string) string { - return "" -} \ No newline at end of file +/* + * 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 resource + +import () + +type EmptyResource struct { +} + +func (c *EmptyResource) GetName() string { + return "" +} + +func (c *EmptyResource) GetType() string { + return "Empty" +} + +func (c *EmptyResource) ToYaml(target string) string { + return "" +} diff --git a/central-controller/src/scc/pkg/resource/file_resource.go b/central-controller/src/scc/pkg/resource/file_resource.go index 62baa34..1cba996 100644 --- a/central-controller/src/scc/pkg/resource/file_resource.go +++ b/central-controller/src/scc/pkg/resource/file_resource.go @@ -1,44 +1,44 @@ -/* - * 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 resource - -import ( - "io/ioutil" -) - -type FileResource struct { - Name string - Type string - FileName string -} - -func (c *FileResource) GetName() string { - return c.Name -} - -func (c *FileResource) GetType() string { - return "File" -} - -func (c *FileResource) ToYaml(target string) string { - yamlFile, _ := ioutil.ReadFile(c.FileName) - return string(yamlFile) -} - -func init() { - GetResourceBuilder().Register("File", &FileResource{}) -} \ No newline at end of file +/* + * 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 resource + +import ( + "io/ioutil" +) + +type FileResource struct { + Name string + Type string + FileName string +} + +func (c *FileResource) GetName() string { + return c.Name +} + +func (c *FileResource) GetType() string { + return "File" +} + +func (c *FileResource) ToYaml(target string) string { + yamlFile, _ := ioutil.ReadFile(c.FileName) + return string(yamlFile) +} + +func init() { + GetResourceBuilder().Register("File", &FileResource{}) +} diff --git a/central-controller/src/scc/pkg/resource/firewall_dnat_resource.go b/central-controller/src/scc/pkg/resource/firewall_dnat_resource.go index db7dcac..8b47291 100644 --- a/central-controller/src/scc/pkg/resource/firewall_dnat_resource.go +++ b/central-controller/src/scc/pkg/resource/firewall_dnat_resource.go @@ -1,69 +1,68 @@ -/* - * 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 resource - -import ( -) - -type FirewallDnatResource struct { - Name string - Source string - SourceIP string - SourceDestIP string - SourceDestPort string - DestinationIP string - DestinationPort string - Protocol string -} - -func (c *FirewallDnatResource) GetName() string { - return c.Name -} - -func (c *FirewallDnatResource) GetType() string { - return "FirewallDNAT" -} - -func (c *FirewallDnatResource) ToYaml(target string) string { - basic := `apiVersion: ` + SdewanApiVersion + ` -kind: FirewallDNAT -metadata: - name: ` + c.Name + ` - namespace: default - labels: - sdewanPurpose: ` + SdewanPurpose + ` - targetCluster: ` + target + ` -spec: - src: ` + c.Source + ` - src_dip: ` + c.SourceDestIP + ` - src_dport: ` + c.SourceDestPort + ` - dest_ip: ` + c.DestinationIP + ` - dest_port: ` + c.DestinationPort + ` - proto: ` + c.Protocol + ` - target: DNAT ` - - if c.SourceIP != "" { - basic += ` - src_ip: ` + c.SourceIP - } - - return basic -} - -func init() { - GetResourceBuilder().Register("FirewallDnat", &FirewallDnatResource{}) -} +/* + * 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 resource + +import () + +type FirewallDnatResource struct { + Name string + Source string + SourceIP string + SourceDestIP string + SourceDestPort string + DestinationIP string + DestinationPort string + Protocol string +} + +func (c *FirewallDnatResource) GetName() string { + return c.Name +} + +func (c *FirewallDnatResource) GetType() string { + return "FirewallDNAT" +} + +func (c *FirewallDnatResource) ToYaml(target string) string { + basic := `apiVersion: ` + SdewanApiVersion + ` +kind: FirewallDNAT +metadata: + name: ` + c.Name + ` + namespace: default + labels: + sdewanPurpose: ` + SdewanPurpose + ` + targetCluster: ` + target + ` +spec: + src: ` + c.Source + ` + src_dip: ` + c.SourceDestIP + ` + src_dport: ` + c.SourceDestPort + ` + dest_ip: ` + c.DestinationIP + ` + dest_port: ` + c.DestinationPort + ` + proto: ` + c.Protocol + ` + target: DNAT ` + + if c.SourceIP != "" { + basic += ` + src_ip: ` + c.SourceIP + } + + return basic +} + +func init() { + GetResourceBuilder().Register("FirewallDnat", &FirewallDnatResource{}) +} diff --git a/central-controller/src/scc/pkg/resource/firewall_zone_resource.go b/central-controller/src/scc/pkg/resource/firewall_zone_resource.go index 31f9997..b69e667 100644 --- a/central-controller/src/scc/pkg/resource/firewall_zone_resource.go +++ b/central-controller/src/scc/pkg/resource/firewall_zone_resource.go @@ -1,68 +1,68 @@ -/* - * 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 resource - -import ( - "strings" -) - -type FirewallZoneResource struct { - Name string - Network []string - Input string - Output string - Forward string - MASQ string - MTU_FIX string -} - -func (c *FirewallZoneResource) GetName() string { - return c.Name -} - -func (c *FirewallZoneResource) GetType() string { - return "FirewallZone" -} - -func (c *FirewallZoneResource) ToYaml(target string) string { - basic := `apiVersion: ` + SdewanApiVersion + ` -kind: FirewallZone -metadata: - name: ` + c.Name + ` - namespace: default - labels: - sdewanPurpose: ` + SdewanPurpose + ` - targetCluster: ` + target + ` -spec: - network: [` + strings.Join(c.Network, ",") + `] - input: ` + c.Input + ` - output: ` + c.Output + ` - forward: ` + c.Forward - - if (c.MASQ != "" && c.MTU_FIX != "") { - optional := ` - masq: ` + c.MASQ + ` - mtu_fix: ` + c.MTU_FIX - basic += optional - } - - return basic -} - -func init() { - GetResourceBuilder().Register("FirewallZone", &FirewallZoneResource{}) -} +/* + * 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 resource + +import ( + "strings" +) + +type FirewallZoneResource struct { + Name string + Network []string + Input string + Output string + Forward string + MASQ string + MTU_FIX string +} + +func (c *FirewallZoneResource) GetName() string { + return c.Name +} + +func (c *FirewallZoneResource) GetType() string { + return "FirewallZone" +} + +func (c *FirewallZoneResource) ToYaml(target string) string { + basic := `apiVersion: ` + SdewanApiVersion + ` +kind: FirewallZone +metadata: + name: ` + c.Name + ` + namespace: default + labels: + sdewanPurpose: ` + SdewanPurpose + ` + targetCluster: ` + target + ` +spec: + network: [` + strings.Join(c.Network, ",") + `] + input: ` + c.Input + ` + output: ` + c.Output + ` + forward: ` + c.Forward + + if c.MASQ != "" && c.MTU_FIX != "" { + optional := ` + masq: ` + c.MASQ + ` + mtu_fix: ` + c.MTU_FIX + basic += optional + } + + return basic +} + +func init() { + GetResourceBuilder().Register("FirewallZone", &FirewallZoneResource{}) +} diff --git a/central-controller/src/scc/pkg/resource/ipsec_resource.go b/central-controller/src/scc/pkg/resource/ipsec_resource.go index 2a962a9..70d0ad4 100644 --- a/central-controller/src/scc/pkg/resource/ipsec_resource.go +++ b/central-controller/src/scc/pkg/resource/ipsec_resource.go @@ -1,189 +1,189 @@ -/* - * 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 governinog permissions and - * limitations under the License. - */ - -package resource - -import ( - "strings" -) - -const ( - AuthTypePSK = "psk" - AuthTypePUBKEY = "pubkey" -) - -type Connection struct { - Name string - ConnectionType string - Mode string - LocalSubnet string - LocalSourceIp string - LocalUpDown string - LocalFirewall string - RemoteSubnet string - RemoteSourceIp string - RemoteUpDown string - RemoteFirewall string - CryptoProposal []string - Mark string - IfId string -} - -type IpsecResource struct { - Name string - Type string - Remote string - AuthenticationMethod string - CryptoProposal []string - LocalIdentifier string - RemoteIdentifier string - ForceCryptoProposal string - PresharedKey string - PublicCert string - PrivateCert string - SharedCA string - Connections Connection -} - -func (c *IpsecResource) GetName() string { - return c.Name -} - -func (c *IpsecResource) GetType() string { - return "Ipsec" -} - -func (c *IpsecResource) ToYaml(target string) string { - p := strings.Join(c.CryptoProposal, ",") - pr := strings.Join(c.Connections.CryptoProposal, ",") - var connection = "" - - if c.Connections.LocalSubnet != "" { - base := `apiVersion: ` + SdewanApiVersion + ` -kind: IpsecSite -metadata: - name: ` + c.Name + ` - namespace: default - labels: - sdewanPurpose: ` + SdewanPurpose + ` - targetCluster: ` + target + ` -spec: - type: ` + c.Type + ` - remote: '` + c.Remote + `' - authentication_method: `+ c.AuthenticationMethod + ` - force_crypto_proposal: "` + c.ForceCryptoProposal + ` - crypto_proposal: [` + p + `]` - - connection = ` - connections: - - name: ` + c.Connections.Name + ` - conn_type: ` + c.Connections.ConnectionType + ` - mode: ` + c.Connections.Mode + ` - mark: "` + c.Connections.Mark + `" - local_updown: ` + c.Connections.LocalUpDown + ` - local_subnet: ` + c.Connections.LocalSubnet + ` - crypto_proposal: [` + pr +`]` - - if c.Connections.RemoteSourceIp != "" { - remote_source_ip := ` - remote_source_ip: '` + c.Connections.RemoteSourceIp + `'` - connection += remote_source_ip - } - - if c.AuthenticationMethod == AuthTypePUBKEY { - auth := ` - local_public_cert: ` + c.PublicCert + ` - local_private_cert: ` + c.PrivateCert + ` - shared_ca: ` + c.SharedCA + ` - local_identifier: ` + c.LocalIdentifier + ` - remote_identifier: ` + c.RemoteIdentifier - return base + auth + connection - } else if c.AuthenticationMethod == AuthTypePSK { - auth := ` - pre_shared_key: ` + c.PresharedKey + ` - local_identifier: ` + c.LocalIdentifier + ` - remote_identifier: ` + c.RemoteIdentifier - return base + auth + connection - } else { - return "Error in authentication method" - } - - } - - base := `apiVersion: ` + SdewanApiVersion + ` -kind: IpsecHost -metadata: - name: ` + c.Name + ` - namespace: default - labels: - sdewanPurpose: ` + SdewanPurpose + ` -spec: - type: ` + c.Type + ` - remote: '` + c.Remote + `' - authentication_method: `+ c.AuthenticationMethod +` - force_crypto_proposal: "` + c.ForceCryptoProposal + `" - crypto_proposal: [` + p + `]` - - if c.Connections.LocalSourceIp != "" { - connection = ` - connections: - - name: ` + c.Connections.Name + ` - conn_type: ` + c.Connections.ConnectionType + ` - mode: ` + c.Connections.Mode + ` - mark: "` + c.Connections.Mark + `" - local_updown: ` + c.Connections.LocalUpDown + ` - local_sourceip: '` + c.Connections.LocalSourceIp + `' - crypto_proposal: [` + pr +`]` - } else { - connection = ` - connections: - - name: ` + c.Connections.Name + ` - conn_type: ` + c.Connections.ConnectionType + ` - mode: ` + c.Connections.Mode + ` - mark: "` + c.Connections.Mark + `" - local_updown: ` + c.Connections.LocalUpDown + ` - crypto_proposal: [` + pr +`]` - } - - if c.Connections.RemoteSourceIp != "" { - remote_source_ip := ` - remote_sourceip: '` + c.Connections.RemoteSourceIp + `'` - connection += remote_source_ip - } - - if c.AuthenticationMethod == AuthTypePUBKEY { - auth := ` - local_public_cert: ` + c.PublicCert + ` - local_private_cert: ` + c.PrivateCert + ` - shared_ca: ` + c.SharedCA + ` - local_identifier: ` + c.LocalIdentifier + ` - remote_identifier: ` + c.RemoteIdentifier - return base + auth + connection - } else if c.AuthenticationMethod == AuthTypePSK { - auth := ` - pre_shared_key: ` + c.PresharedKey + ` - local_identifier: ` + c.LocalIdentifier + ` - remote_identifier: ` + c.RemoteIdentifier - return base + auth + connection - } else { - return "Error in authentication method" - } - -} - -func init() { - GetResourceBuilder().Register("Ipsec", &IpsecResource{}) -} +/* + * 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 governinog permissions and + * limitations under the License. + */ + +package resource + +import ( + "strings" +) + +const ( + AuthTypePSK = "psk" + AuthTypePUBKEY = "pubkey" +) + +type Connection struct { + Name string + ConnectionType string + Mode string + LocalSubnet string + LocalSourceIp string + LocalUpDown string + LocalFirewall string + RemoteSubnet string + RemoteSourceIp string + RemoteUpDown string + RemoteFirewall string + CryptoProposal []string + Mark string + IfId string +} + +type IpsecResource struct { + Name string + Type string + Remote string + AuthenticationMethod string + CryptoProposal []string + LocalIdentifier string + RemoteIdentifier string + ForceCryptoProposal string + PresharedKey string + PublicCert string + PrivateCert string + SharedCA string + Connections Connection +} + +func (c *IpsecResource) GetName() string { + return c.Name +} + +func (c *IpsecResource) GetType() string { + return "Ipsec" +} + +func (c *IpsecResource) ToYaml(target string) string { + p := strings.Join(c.CryptoProposal, ",") + pr := strings.Join(c.Connections.CryptoProposal, ",") + var connection = "" + + if c.Connections.LocalSubnet != "" { + base := `apiVersion: ` + SdewanApiVersion + ` +kind: IpsecSite +metadata: + name: ` + c.Name + ` + namespace: default + labels: + sdewanPurpose: ` + SdewanPurpose + ` + targetCluster: ` + target + ` +spec: + type: ` + c.Type + ` + remote: '` + c.Remote + `' + authentication_method: ` + c.AuthenticationMethod + ` + force_crypto_proposal: "` + c.ForceCryptoProposal + ` + crypto_proposal: [` + p + `]` + + connection = ` + connections: + - name: ` + c.Connections.Name + ` + conn_type: ` + c.Connections.ConnectionType + ` + mode: ` + c.Connections.Mode + ` + mark: "` + c.Connections.Mark + `" + local_updown: ` + c.Connections.LocalUpDown + ` + local_subnet: ` + c.Connections.LocalSubnet + ` + crypto_proposal: [` + pr + `]` + + if c.Connections.RemoteSourceIp != "" { + remote_source_ip := ` + remote_source_ip: '` + c.Connections.RemoteSourceIp + `'` + connection += remote_source_ip + } + + if c.AuthenticationMethod == AuthTypePUBKEY { + auth := ` + local_public_cert: ` + c.PublicCert + ` + local_private_cert: ` + c.PrivateCert + ` + shared_ca: ` + c.SharedCA + ` + local_identifier: ` + c.LocalIdentifier + ` + remote_identifier: ` + c.RemoteIdentifier + return base + auth + connection + } else if c.AuthenticationMethod == AuthTypePSK { + auth := ` + pre_shared_key: ` + c.PresharedKey + ` + local_identifier: ` + c.LocalIdentifier + ` + remote_identifier: ` + c.RemoteIdentifier + return base + auth + connection + } else { + return "Error in authentication method" + } + + } + + base := `apiVersion: ` + SdewanApiVersion + ` +kind: IpsecHost +metadata: + name: ` + c.Name + ` + namespace: default + labels: + sdewanPurpose: ` + SdewanPurpose + ` +spec: + type: ` + c.Type + ` + remote: '` + c.Remote + `' + authentication_method: ` + c.AuthenticationMethod + ` + force_crypto_proposal: "` + c.ForceCryptoProposal + `" + crypto_proposal: [` + p + `]` + + if c.Connections.LocalSourceIp != "" { + connection = ` + connections: + - name: ` + c.Connections.Name + ` + conn_type: ` + c.Connections.ConnectionType + ` + mode: ` + c.Connections.Mode + ` + mark: "` + c.Connections.Mark + `" + local_updown: ` + c.Connections.LocalUpDown + ` + local_sourceip: '` + c.Connections.LocalSourceIp + `' + crypto_proposal: [` + pr + `]` + } else { + connection = ` + connections: + - name: ` + c.Connections.Name + ` + conn_type: ` + c.Connections.ConnectionType + ` + mode: ` + c.Connections.Mode + ` + mark: "` + c.Connections.Mark + `" + local_updown: ` + c.Connections.LocalUpDown + ` + crypto_proposal: [` + pr + `]` + } + + if c.Connections.RemoteSourceIp != "" { + remote_source_ip := ` + remote_sourceip: '` + c.Connections.RemoteSourceIp + `'` + connection += remote_source_ip + } + + if c.AuthenticationMethod == AuthTypePUBKEY { + auth := ` + local_public_cert: ` + c.PublicCert + ` + local_private_cert: ` + c.PrivateCert + ` + shared_ca: ` + c.SharedCA + ` + local_identifier: ` + c.LocalIdentifier + ` + remote_identifier: ` + c.RemoteIdentifier + return base + auth + connection + } else if c.AuthenticationMethod == AuthTypePSK { + auth := ` + pre_shared_key: ` + c.PresharedKey + ` + local_identifier: ` + c.LocalIdentifier + ` + remote_identifier: ` + c.RemoteIdentifier + return base + auth + connection + } else { + return "Error in authentication method" + } + +} + +func init() { + GetResourceBuilder().Register("Ipsec", &IpsecResource{}) +} diff --git a/central-controller/src/scc/pkg/resource/proposal_resource.go b/central-controller/src/scc/pkg/resource/proposal_resource.go index 26df257..9d94e53 100644 --- a/central-controller/src/scc/pkg/resource/proposal_resource.go +++ b/central-controller/src/scc/pkg/resource/proposal_resource.go @@ -1,54 +1,53 @@ -/* - * 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 resource - -import ( -) - -type ProposalResource struct { - Name string - Encryption string - Hash string - DhGroup string -} - -func (c *ProposalResource) GetName() string { - return c.Name -} - -func (c *ProposalResource) GetType() string { - return "Proposal" -} - -func (c *ProposalResource) ToYaml(target string) string { - return `apiVersion: ` + SdewanApiVersion + ` -kind: IpsecProposal -metadata: - name: ` + c.Name + ` - namespace: default - labels: - sdewanPurpose: ` + SdewanPurpose + ` - targetCluster: ` + target + ` -spec: - encryption_algorithm: ` + c.Encryption + ` - hash_algorithm: ` + c.Hash + ` - dh_group: ` + c.DhGroup -} - -func init() { - GetResourceBuilder().Register("Proposal", &ProposalResource{}) -} \ No newline at end of file +/* + * 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 resource + +import () + +type ProposalResource struct { + Name string + Encryption string + Hash string + DhGroup string +} + +func (c *ProposalResource) GetName() string { + return c.Name +} + +func (c *ProposalResource) GetType() string { + return "Proposal" +} + +func (c *ProposalResource) ToYaml(target string) string { + return `apiVersion: ` + SdewanApiVersion + ` +kind: IpsecProposal +metadata: + name: ` + c.Name + ` + namespace: default + labels: + sdewanPurpose: ` + SdewanPurpose + ` + targetCluster: ` + target + ` +spec: + encryption_algorithm: ` + c.Encryption + ` + hash_algorithm: ` + c.Hash + ` + dh_group: ` + c.DhGroup +} + +func init() { + GetResourceBuilder().Register("Proposal", &ProposalResource{}) +} diff --git a/central-controller/src/scc/pkg/resource/resourcebuilder.go b/central-controller/src/scc/pkg/resource/resourcebuilder.go index c17c319..06abc40 100644 --- a/central-controller/src/scc/pkg/resource/resourcebuilder.go +++ b/central-controller/src/scc/pkg/resource/resourcebuilder.go @@ -1,67 +1,67 @@ -/* - * 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 resource - -import ( - "strings" - "reflect" - "encoding/json" - pkgerrors "github.com/pkg/errors" -) - -type ResourceBuilder struct { - omap map[string]reflect.Type -} - -var res_builder = ResourceBuilder{ - omap: make(map[string]reflect.Type), -} - -func GetResourceBuilder() *ResourceBuilder { - return &res_builder -} - -func (c *ResourceBuilder) Register(name string, r interface{}) { - c.omap[name] = reflect.TypeOf(r).Elem() -} - -func (c *ResourceBuilder) ToString(obj ISdewanResource) (string, error) { - obj_str, err := json.Marshal(obj) - if err != nil { - return "", err - } - - return obj.GetType() + "-" + string(obj_str), nil -} - -func (c *ResourceBuilder) ToObject(obj_str string) (ISdewanResource, error) { - if !strings.Contains(obj_str, "-") { - return &EmptyResource{}, pkgerrors.New("Not a valid object") - } - strs := strings.SplitN(obj_str, "-", 2) - if len(strs) != 2 { - return &EmptyResource{}, pkgerrors.New("Not a valid object") - } - - if v, ok := c.omap[strs[0]]; ok { - retObj := reflect.New(v).Interface() - err := json.Unmarshal([]byte(strs[1]), retObj) - return retObj.(ISdewanResource), err - } else { - return &EmptyResource{}, pkgerrors.New("Not a valid object") - } -} +/* + * 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 resource + +import ( + "encoding/json" + pkgerrors "github.com/pkg/errors" + "reflect" + "strings" +) + +type ResourceBuilder struct { + omap map[string]reflect.Type +} + +var res_builder = ResourceBuilder{ + omap: make(map[string]reflect.Type), +} + +func GetResourceBuilder() *ResourceBuilder { + return &res_builder +} + +func (c *ResourceBuilder) Register(name string, r interface{}) { + c.omap[name] = reflect.TypeOf(r).Elem() +} + +func (c *ResourceBuilder) ToString(obj ISdewanResource) (string, error) { + obj_str, err := json.Marshal(obj) + if err != nil { + return "", err + } + + return obj.GetType() + "-" + string(obj_str), nil +} + +func (c *ResourceBuilder) ToObject(obj_str string) (ISdewanResource, error) { + if !strings.Contains(obj_str, "-") { + return &EmptyResource{}, pkgerrors.New("Not a valid object") + } + strs := strings.SplitN(obj_str, "-", 2) + if len(strs) != 2 { + return &EmptyResource{}, pkgerrors.New("Not a valid object") + } + + if v, ok := c.omap[strs[0]]; ok { + retObj := reflect.New(v).Interface() + err := json.Unmarshal([]byte(strs[1]), retObj) + return retObj.(ISdewanResource), err + } else { + return &EmptyResource{}, pkgerrors.New("Not a valid object") + } +} diff --git a/central-controller/src/scc/pkg/resource/sdewan_resource.go b/central-controller/src/scc/pkg/resource/sdewan_resource.go index 7c588ea..dffdac7 100644 --- a/central-controller/src/scc/pkg/resource/sdewan_resource.go +++ b/central-controller/src/scc/pkg/resource/sdewan_resource.go @@ -1,31 +1,30 @@ -/* - * 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 resource - -import ( -) - -const ( - SdewanApiVersion = "batch.sdewan.akraino.org/v1alpha1" - SdewanPurpose = "base" -) - -type ISdewanResource interface { - GetName() string - GetType() string - ToYaml(target string) string -} \ No newline at end of file +/* + * 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 resource + +import () + +const ( + SdewanApiVersion = "batch.sdewan.akraino.org/v1alpha1" + SdewanPurpose = "base" +) + +type ISdewanResource interface { + GetName() string + GetType() string + ToYaml(target string) string +} diff --git a/central-controller/src/scc/test/certificateobject_test.go b/central-controller/src/scc/test/certificateobject_test.go index 1cfa1c2..3179b49 100644 --- a/central-controller/src/scc/test/certificateobject_test.go +++ b/central-controller/src/scc/test/certificateobject_test.go @@ -1,174 +1,174 @@ -package test - -import ( - "testing" - "flag" - "encoding/json" - "fmt" - "os" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" -) - -var BaseUrl string -var OverlayUrl string - -func TestMain(m *testing.M) { - servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") - flag.Parse() - OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection - BaseUrl = OverlayUrl + "/overlay1/" + manager.CertCollection - - var overlay_object = module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}} - - var cert_object1 = module.CertificateObject{ - Metadata: module.ObjectMetaData{"device1", "", "", ""}} - var cert_object2 = module.CertificateObject{ - Metadata: module.ObjectMetaData{"device2", "", "", ""}} - - createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{}) - createControllerObject(BaseUrl, &cert_object1, &module.CertificateObject{}) - createControllerObject(BaseUrl, &cert_object2, &module.CertificateObject{}) - - var ret = m.Run() - - deleteControllerObject(BaseUrl, "device1") - deleteControllerObject(BaseUrl, "device2") - deleteControllerObject(OverlayUrl, "overlay1") - - os.Exit(ret) -} - -func TestGetObjects(t *testing.T) { - url := BaseUrl - res, err := callRest("GET", url, "") - if err != nil { - printError(err) - t.Errorf("Test case GetObjects: can not get Objects") - return - } - - var objs []module.CertificateObject - err = json.Unmarshal([]byte(res), &objs) - - if len(objs) == 0 { - fmt.Printf("Test case GetObjects: no object found") - return - } - - p_data, _ := json.Marshal(objs) - fmt.Printf("%s\n", string(p_data)) -} - -func TestGetObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "Normal", - object_name: "device1", - }, - { - name: "GetFoolName", - object_name: "foo_name", - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - obj, err := getControllerObject(BaseUrl, tcase.object_name, &module.CertificateObject{}) - if err == nil { - p_data, _ := json.Marshal(obj) - fmt.Printf("%s\n", string(p_data)) - } - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestCreateObject(t *testing.T) { - tcases := []struct { - name string - url string - obj module.CertificateObject - expectedErr bool - expectedErrCode int - }{ - { - name: "EmptyName", - obj: module.CertificateObject{ - Metadata: module.ObjectMetaData{"", "object 1", "", ""}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "WrongOverlayName", - obj: module.CertificateObject{ - Metadata: module.ObjectMetaData{"device3", "", "", ""}}, - url: OverlayUrl + "/foooverlay/" + manager.CertCollection, - expectedErr: true, - expectedErrCode: 500, - }, - { - name: "DumplicateName", - obj: module.CertificateObject{ - Metadata: module.ObjectMetaData{"device1", "", "", ""}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 409, - }, - } - - for _, tcase := range tcases { - _, err := createControllerObject(tcase.url, &tcase.obj, &module.CertificateObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestDeleteObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "FoolName", - object_name: "foo_name", - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := deleteControllerObject(BaseUrl, tcase.object_name) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestHappyPath(t *testing.T) { - cert_name := "my-device" - - obj := module.CertificateObject{ - Metadata: module.ObjectMetaData{cert_name, "", "", ""}} - - _, err := createControllerObject(BaseUrl, &obj, &module.CertificateObject{}) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - _, err = deleteControllerObject(BaseUrl, cert_name) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: delete object") - return - } -} \ No newline at end of file +package test + +import ( + "encoding/json" + "flag" + "fmt" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "os" + "testing" +) + +var BaseUrl string +var OverlayUrl string + +func TestMain(m *testing.M) { + servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") + flag.Parse() + OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection + BaseUrl = OverlayUrl + "/overlay1/" + manager.CertCollection + + var overlay_object = module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}} + + var cert_object1 = module.CertificateObject{ + Metadata: module.ObjectMetaData{"device1", "", "", ""}} + var cert_object2 = module.CertificateObject{ + Metadata: module.ObjectMetaData{"device2", "", "", ""}} + + createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{}) + createControllerObject(BaseUrl, &cert_object1, &module.CertificateObject{}) + createControllerObject(BaseUrl, &cert_object2, &module.CertificateObject{}) + + var ret = m.Run() + + deleteControllerObject(BaseUrl, "device1") + deleteControllerObject(BaseUrl, "device2") + deleteControllerObject(OverlayUrl, "overlay1") + + os.Exit(ret) +} + +func TestGetObjects(t *testing.T) { + url := BaseUrl + res, err := callRest("GET", url, "") + if err != nil { + printError(err) + t.Errorf("Test case GetObjects: can not get Objects") + return + } + + var objs []module.CertificateObject + err = json.Unmarshal([]byte(res), &objs) + + if len(objs) == 0 { + fmt.Printf("Test case GetObjects: no object found") + return + } + + p_data, _ := json.Marshal(objs) + fmt.Printf("%s\n", string(p_data)) +} + +func TestGetObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "Normal", + object_name: "device1", + }, + { + name: "GetFoolName", + object_name: "foo_name", + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + obj, err := getControllerObject(BaseUrl, tcase.object_name, &module.CertificateObject{}) + if err == nil { + p_data, _ := json.Marshal(obj) + fmt.Printf("%s\n", string(p_data)) + } + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestCreateObject(t *testing.T) { + tcases := []struct { + name string + url string + obj module.CertificateObject + expectedErr bool + expectedErrCode int + }{ + { + name: "EmptyName", + obj: module.CertificateObject{ + Metadata: module.ObjectMetaData{"", "object 1", "", ""}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "WrongOverlayName", + obj: module.CertificateObject{ + Metadata: module.ObjectMetaData{"device3", "", "", ""}}, + url: OverlayUrl + "/foooverlay/" + manager.CertCollection, + expectedErr: true, + expectedErrCode: 500, + }, + { + name: "DumplicateName", + obj: module.CertificateObject{ + Metadata: module.ObjectMetaData{"device1", "", "", ""}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 409, + }, + } + + for _, tcase := range tcases { + _, err := createControllerObject(tcase.url, &tcase.obj, &module.CertificateObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestDeleteObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "FoolName", + object_name: "foo_name", + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := deleteControllerObject(BaseUrl, tcase.object_name) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestHappyPath(t *testing.T) { + cert_name := "my-device" + + obj := module.CertificateObject{ + Metadata: module.ObjectMetaData{cert_name, "", "", ""}} + + _, err := createControllerObject(BaseUrl, &obj, &module.CertificateObject{}) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + _, err = deleteControllerObject(BaseUrl, cert_name) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: delete object") + return + } +} diff --git a/central-controller/src/scc/test/cnfobject_test.go b/central-controller/src/scc/test/cnfobject_test.go index 26bd674..6a042ae 100644 --- a/central-controller/src/scc/test/cnfobject_test.go +++ b/central-controller/src/scc/test/cnfobject_test.go @@ -1,52 +1,52 @@ -package test - -import ( - "testing" - "flag" - "encoding/json" - "fmt" - "os" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" -) - -var BaseUrl string - -func TestMain(m *testing.M) { - servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") - flag.Parse() - BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection - - var object1 = module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}} - - createControllerObject(BaseUrl, &object1, &module.OverlayObject{}) - - var ret = m.Run() - - deleteControllerObject(BaseUrl, "overlay1") - - os.Exit(ret) -} - -func TestGetObjects(t *testing.T) { - url := BaseUrl + "/overlay1/devices/device1/cnfs" - res, err := callRest("GET", url, "") - if err != nil { - printError(err) - t.Errorf("Test case GetObjects: can not get Objects") - return - } - - var objs []module.CNFObject - err = json.Unmarshal([]byte(res), &objs) - - if len(objs) == 0 { - fmt.Printf("Test case GetObjects: no object found") - return - } - - p_data, _ := json.Marshal(objs) - fmt.Printf("%s\n", string(p_data)) -} \ No newline at end of file +package test + +import ( + "encoding/json" + "flag" + "fmt" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "os" + "testing" +) + +var BaseUrl string + +func TestMain(m *testing.M) { + servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") + flag.Parse() + BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection + + var object1 = module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}} + + createControllerObject(BaseUrl, &object1, &module.OverlayObject{}) + + var ret = m.Run() + + deleteControllerObject(BaseUrl, "overlay1") + + os.Exit(ret) +} + +func TestGetObjects(t *testing.T) { + url := BaseUrl + "/overlay1/devices/device1/cnfs" + res, err := callRest("GET", url, "") + if err != nil { + printError(err) + t.Errorf("Test case GetObjects: can not get Objects") + return + } + + var objs []module.CNFObject + err = json.Unmarshal([]byte(res), &objs) + + if len(objs) == 0 { + fmt.Printf("Test case GetObjects: no object found") + return + } + + p_data, _ := json.Marshal(objs) + fmt.Printf("%s\n", string(p_data)) +} diff --git a/central-controller/src/scc/test/iprangeobject_test.go b/central-controller/src/scc/test/iprangeobject_test.go index e756feb..541eaa6 100644 --- a/central-controller/src/scc/test/iprangeobject_test.go +++ b/central-controller/src/scc/test/iprangeobject_test.go @@ -1,235 +1,235 @@ -package test - -import ( - "testing" - "flag" - "encoding/json" - "fmt" - "os" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" -) - -var BaseUrl string -var OverlayUrl string - -func TestMain(m *testing.M) { - servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") - flag.Parse() - OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection - BaseUrl = OverlayUrl + "/overlay1/" + manager.IPRangeCollection - - var overlay_object = module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}} - - var iprange_object1 = module.IPRangeObject{ - Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 12}} - var iprange_object2 = module.IPRangeObject{ - Metadata: module.ObjectMetaData{"ipr2", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.1.3", 32, 36}} - - createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{}) - createControllerObject(BaseUrl, &iprange_object1, &module.IPRangeObject{}) - createControllerObject(BaseUrl, &iprange_object2, &module.IPRangeObject{}) - - var ret = m.Run() - - deleteControllerObject(BaseUrl, "ipr1") - deleteControllerObject(BaseUrl, "ipr2") - deleteControllerObject(OverlayUrl, "overlay1") - - os.Exit(ret) -} - -func TestGetObjects(t *testing.T) { - url := BaseUrl - res, err := callRest("GET", url, "") - if err != nil { - printError(err) - t.Errorf("Test case GetObjects: can not get Objects") - return - } - - var objs []module.IPRangeObject - err = json.Unmarshal([]byte(res), &objs) - - if len(objs) == 0 { - fmt.Printf("Test case GetObjects: no object found") - return - } - - p_data, _ := json.Marshal(objs) - fmt.Printf("%s\n", string(p_data)) -} - -func TestGetObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "Normal", - object_name: "ipr1", - }, - { - name: "GetFoolName", - object_name: "foo_name", - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := getControllerObject(BaseUrl, tcase.object_name, &module.IPRangeObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestCreateObject(t *testing.T) { - tcases := []struct { - name string - url string - obj module.IPRangeObject - expectedErr bool - expectedErrCode int - }{ - { - name: "EmptyName", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"", "object 1", "", ""}, - Specification: module.IPRangeObjectSpec{}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "DumplicateName", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 409, - }, - { - name: "WrongOverlayName", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}}, - url: OverlayUrl + "/foooverlay/" + manager.IPRangeCollection, - expectedErr: true, - expectedErrCode: 500, - }, - { - name: "WrongSubnet", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.3.0", 1, 15}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "WrongMinIP", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.3", 0, 15}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "WrongMaxIP", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.1.3", 1, 300}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "WrongMinMaxIP", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.3", 20, 15}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "ConflictRange1", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.0.3", 11, 15}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 500, - }, - { - name: "ConflictRange2", - obj: module.IPRangeObject{ - Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.1.3", 30, 40}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := createControllerObject(tcase.url, &tcase.obj, &module.IPRangeObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestDeleteObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "FoolName", - object_name: "foo_name", - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := deleteControllerObject(BaseUrl, tcase.object_name) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestHappyPath(t *testing.T) { - ipr_name := "my-ipr" - - obj := module.IPRangeObject{ - Metadata: module.ObjectMetaData{ipr_name, "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}} - - ret_obj, err := createControllerObject(BaseUrl, &obj, &module.IPRangeObject{}) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - if ret_obj.(*module.IPRangeObject).Specification.Subnet != "192.168.2.3" { - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - _, err = deleteControllerObject(BaseUrl, ipr_name) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: delete object") - return - } -} \ No newline at end of file +package test + +import ( + "encoding/json" + "flag" + "fmt" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "os" + "testing" +) + +var BaseUrl string +var OverlayUrl string + +func TestMain(m *testing.M) { + servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") + flag.Parse() + OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection + BaseUrl = OverlayUrl + "/overlay1/" + manager.IPRangeCollection + + var overlay_object = module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}} + + var iprange_object1 = module.IPRangeObject{ + Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 12}} + var iprange_object2 = module.IPRangeObject{ + Metadata: module.ObjectMetaData{"ipr2", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.1.3", 32, 36}} + + createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{}) + createControllerObject(BaseUrl, &iprange_object1, &module.IPRangeObject{}) + createControllerObject(BaseUrl, &iprange_object2, &module.IPRangeObject{}) + + var ret = m.Run() + + deleteControllerObject(BaseUrl, "ipr1") + deleteControllerObject(BaseUrl, "ipr2") + deleteControllerObject(OverlayUrl, "overlay1") + + os.Exit(ret) +} + +func TestGetObjects(t *testing.T) { + url := BaseUrl + res, err := callRest("GET", url, "") + if err != nil { + printError(err) + t.Errorf("Test case GetObjects: can not get Objects") + return + } + + var objs []module.IPRangeObject + err = json.Unmarshal([]byte(res), &objs) + + if len(objs) == 0 { + fmt.Printf("Test case GetObjects: no object found") + return + } + + p_data, _ := json.Marshal(objs) + fmt.Printf("%s\n", string(p_data)) +} + +func TestGetObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "Normal", + object_name: "ipr1", + }, + { + name: "GetFoolName", + object_name: "foo_name", + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := getControllerObject(BaseUrl, tcase.object_name, &module.IPRangeObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestCreateObject(t *testing.T) { + tcases := []struct { + name string + url string + obj module.IPRangeObject + expectedErr bool + expectedErrCode int + }{ + { + name: "EmptyName", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"", "object 1", "", ""}, + Specification: module.IPRangeObjectSpec{}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "DumplicateName", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 409, + }, + { + name: "WrongOverlayName", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}}, + url: OverlayUrl + "/foooverlay/" + manager.IPRangeCollection, + expectedErr: true, + expectedErrCode: 500, + }, + { + name: "WrongSubnet", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.3.0", 1, 15}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "WrongMinIP", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.3", 0, 15}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "WrongMaxIP", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.1.3", 1, 300}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "WrongMinMaxIP", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.3", 20, 15}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "ConflictRange1", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.0.3", 11, 15}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 500, + }, + { + name: "ConflictRange2", + obj: module.IPRangeObject{ + Metadata: module.ObjectMetaData{"my-ipr", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.1.3", 30, 40}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := createControllerObject(tcase.url, &tcase.obj, &module.IPRangeObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestDeleteObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "FoolName", + object_name: "foo_name", + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := deleteControllerObject(BaseUrl, tcase.object_name) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestHappyPath(t *testing.T) { + ipr_name := "my-ipr" + + obj := module.IPRangeObject{ + Metadata: module.ObjectMetaData{ipr_name, "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.3", 10, 15}} + + ret_obj, err := createControllerObject(BaseUrl, &obj, &module.IPRangeObject{}) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + if ret_obj.(*module.IPRangeObject).Specification.Subnet != "192.168.2.3" { + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + _, err = deleteControllerObject(BaseUrl, ipr_name) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: delete object") + return + } +} diff --git a/central-controller/src/scc/test/overlayobject_test.go b/central-controller/src/scc/test/overlayobject_test.go index 7ec2f09..ab5c693 100644 --- a/central-controller/src/scc/test/overlayobject_test.go +++ b/central-controller/src/scc/test/overlayobject_test.go @@ -1,209 +1,209 @@ -package test - -import ( - "testing" - "flag" - "encoding/json" - "fmt" - "os" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" -) - -var BaseUrl string - -func TestMain(m *testing.M) { - servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") - flag.Parse() - BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection - - var object1 = module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}} - var object2 = module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay2", "", "", ""}, - Specification: module.OverlayObjectSpec{}} - - createControllerObject(BaseUrl, &object1, &module.OverlayObject{}) - createControllerObject(BaseUrl, &object2, &module.OverlayObject{}) - - var ret = m.Run() - - deleteControllerObject(BaseUrl, "overlay1") - deleteControllerObject(BaseUrl, "overlay2") - - os.Exit(ret) -} - -func TestGetObjects(t *testing.T) { - url := BaseUrl - res, err := callRest("GET", url, "") - if err != nil { - printError(err) - t.Errorf("Test case GetObjects: can not get Objects") - return - } - - var objs []module.OverlayObject - err = json.Unmarshal([]byte(res), &objs) - - if len(objs) == 0 { - fmt.Printf("Test case GetObjects: no object found") - return - } - - p_data, _ := json.Marshal(objs) - fmt.Printf("%s\n", string(p_data)) -} - -func TestGetObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "Normal", - object_name: "overlay1", - }, - { - name: "GetFoolName", - object_name: "foo_name", - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := getControllerObject(BaseUrl, tcase.object_name, &module.OverlayObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestCreateObject(t *testing.T) { - tcases := []struct { - name string - obj module.OverlayObject - expectedErr bool - expectedErrCode int - }{ - { - name: "EmptyName", - obj: module.OverlayObject{ - Metadata: module.ObjectMetaData{"", "object 1", "", ""}, - Specification: module.OverlayObjectSpec{}}, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "DumplicateName", - obj: module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}}, - expectedErr: true, - expectedErrCode: 409, - }, - } - - for _, tcase := range tcases { - _, err := createControllerObject(BaseUrl, &tcase.obj, &module.OverlayObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestUpdateObject(t *testing.T) { - tcases := []struct { - name string - object_name string - obj module.OverlayObject - expectedErr bool - expectedErrCode int - }{ - { - name: "EmptyName", - object_name: "overlay1", - obj: module.OverlayObject{ - Metadata: module.ObjectMetaData{"", "object 1", "", ""}, - Specification: module.OverlayObjectSpec{}}, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "MisMatchName", - object_name: "overlay2", - obj: module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}}, - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.OverlayObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestDeleteObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "FoolName", - object_name: "foo_name", - }, - } - - for _, tcase := range tcases { - _, err := deleteControllerObject(BaseUrl, tcase.object_name) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestHappyPath(t *testing.T) { - overlay_name := "my-overlay" - - obj := module.OverlayObject{ - Metadata: module.ObjectMetaData{overlay_name, "object 1", "", ""}, - Specification: module.OverlayObjectSpec{}} - - obj_update := module.OverlayObject{ - Metadata: module.ObjectMetaData{overlay_name, "object 2", "", ""}, - Specification: module.OverlayObjectSpec{}} - - ret_obj, err := createControllerObject(BaseUrl, &obj, &module.OverlayObject{}) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - if ret_obj.(*module.OverlayObject).Metadata.Description != "object 1" { - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - ret_obj, err = updateControllerObject(BaseUrl, overlay_name, &obj_update, &module.OverlayObject{}) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: update object") - return - } - - if ret_obj.(*module.OverlayObject).Metadata.Description != "object 2" { - t.Errorf("Test Case 'Happy Path' failed: update object") - return - } - - _, err = deleteControllerObject(BaseUrl, overlay_name) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: delete object") - return - } -} +package test + +import ( + "encoding/json" + "flag" + "fmt" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "os" + "testing" +) + +var BaseUrl string + +func TestMain(m *testing.M) { + servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") + flag.Parse() + BaseUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection + + var object1 = module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}} + var object2 = module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay2", "", "", ""}, + Specification: module.OverlayObjectSpec{}} + + createControllerObject(BaseUrl, &object1, &module.OverlayObject{}) + createControllerObject(BaseUrl, &object2, &module.OverlayObject{}) + + var ret = m.Run() + + deleteControllerObject(BaseUrl, "overlay1") + deleteControllerObject(BaseUrl, "overlay2") + + os.Exit(ret) +} + +func TestGetObjects(t *testing.T) { + url := BaseUrl + res, err := callRest("GET", url, "") + if err != nil { + printError(err) + t.Errorf("Test case GetObjects: can not get Objects") + return + } + + var objs []module.OverlayObject + err = json.Unmarshal([]byte(res), &objs) + + if len(objs) == 0 { + fmt.Printf("Test case GetObjects: no object found") + return + } + + p_data, _ := json.Marshal(objs) + fmt.Printf("%s\n", string(p_data)) +} + +func TestGetObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "Normal", + object_name: "overlay1", + }, + { + name: "GetFoolName", + object_name: "foo_name", + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := getControllerObject(BaseUrl, tcase.object_name, &module.OverlayObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestCreateObject(t *testing.T) { + tcases := []struct { + name string + obj module.OverlayObject + expectedErr bool + expectedErrCode int + }{ + { + name: "EmptyName", + obj: module.OverlayObject{ + Metadata: module.ObjectMetaData{"", "object 1", "", ""}, + Specification: module.OverlayObjectSpec{}}, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "DumplicateName", + obj: module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}}, + expectedErr: true, + expectedErrCode: 409, + }, + } + + for _, tcase := range tcases { + _, err := createControllerObject(BaseUrl, &tcase.obj, &module.OverlayObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestUpdateObject(t *testing.T) { + tcases := []struct { + name string + object_name string + obj module.OverlayObject + expectedErr bool + expectedErrCode int + }{ + { + name: "EmptyName", + object_name: "overlay1", + obj: module.OverlayObject{ + Metadata: module.ObjectMetaData{"", "object 1", "", ""}, + Specification: module.OverlayObjectSpec{}}, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "MisMatchName", + object_name: "overlay2", + obj: module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}}, + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.OverlayObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestDeleteObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "FoolName", + object_name: "foo_name", + }, + } + + for _, tcase := range tcases { + _, err := deleteControllerObject(BaseUrl, tcase.object_name) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestHappyPath(t *testing.T) { + overlay_name := "my-overlay" + + obj := module.OverlayObject{ + Metadata: module.ObjectMetaData{overlay_name, "object 1", "", ""}, + Specification: module.OverlayObjectSpec{}} + + obj_update := module.OverlayObject{ + Metadata: module.ObjectMetaData{overlay_name, "object 2", "", ""}, + Specification: module.OverlayObjectSpec{}} + + ret_obj, err := createControllerObject(BaseUrl, &obj, &module.OverlayObject{}) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + if ret_obj.(*module.OverlayObject).Metadata.Description != "object 1" { + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + ret_obj, err = updateControllerObject(BaseUrl, overlay_name, &obj_update, &module.OverlayObject{}) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: update object") + return + } + + if ret_obj.(*module.OverlayObject).Metadata.Description != "object 2" { + t.Errorf("Test Case 'Happy Path' failed: update object") + return + } + + _, err = deleteControllerObject(BaseUrl, overlay_name) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: delete object") + return + } +} diff --git a/central-controller/src/scc/test/proposalobject_test.go b/central-controller/src/scc/test/proposalobject_test.go index e2c9559..7a72176 100644 --- a/central-controller/src/scc/test/proposalobject_test.go +++ b/central-controller/src/scc/test/proposalobject_test.go @@ -1,241 +1,241 @@ -package test - -import ( - "testing" - "flag" - "encoding/json" - "fmt" - "os" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" -) - -var BaseUrl string -var OverlayUrl string - -func TestMain(m *testing.M) { - servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") - flag.Parse() - OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection - IPBaseUrl := OverlayUrl + "/overlay1/" + manager.IPRangeCollection - BaseUrl = OverlayUrl + "/overlay1/" + manager.ProposalCollection - - var overlay_object = module.OverlayObject{ - Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, - Specification: module.OverlayObjectSpec{}} - - var iprange_object1 = module.IPRangeObject{ - Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 20}} - var iprange_object2 = module.IPRangeObject{ - Metadata: module.ObjectMetaData{"ipr2", "", "", ""}, - Specification: module.IPRangeObjectSpec{"192.168.2.2", 18, 20}} - - var proposal_object1 = module.ProposalObject{ - Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, - Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}} - var proposal_object2 = module.ProposalObject{ - Metadata: module.ObjectMetaData{"proposal2", "", "", ""}, - Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}} - - createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{}) - createControllerObject(IPBaseUrl, &iprange_object1, &module.IPRangeObject{}) - createControllerObject(IPBaseUrl, &iprange_object2, &module.IPRangeObject{}) - createControllerObject(BaseUrl, &proposal_object1, &module.ProposalObject{}) - createControllerObject(BaseUrl, &proposal_object2, &module.ProposalObject{}) - - var ret = m.Run() - - deleteControllerObject(BaseUrl, "proposal1") - deleteControllerObject(BaseUrl, "proposal2") - deleteControllerObject(IPBaseUrl, "ipr1") - deleteControllerObject(IPBaseUrl, "ipr2") - deleteControllerObject(OverlayUrl, "overlay1") - - os.Exit(ret) -} - -func TestGetObjects(t *testing.T) { - url := BaseUrl - res, err := callRest("GET", url, "") - if err != nil { - printError(err) - t.Errorf("Test case GetObjects: can not get Objects") - return - } - - var objs []module.ProposalObject - err = json.Unmarshal([]byte(res), &objs) - - if len(objs) == 0 { - fmt.Printf("Test case GetObjects: no object found") - return - } - - p_data, _ := json.Marshal(objs) - fmt.Printf("%s\n", string(p_data)) -} - -func TestGetObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "Normal", - object_name: "proposal1", - }, - { - name: "GetFoolName", - object_name: "foo_name", - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := getControllerObject(BaseUrl, tcase.object_name, &module.ProposalObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestCreateObject(t *testing.T) { - tcases := []struct { - name string - url string - obj module.ProposalObject - expectedErr bool - expectedErrCode int - }{ - { - name: "EmptyName", - obj: module.ProposalObject{ - Metadata: module.ObjectMetaData{"", "object 1", "", ""}, - Specification: module.ProposalObjectSpec{}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "WrongOverlayName", - obj: module.ProposalObject{ - Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, - Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, - url: OverlayUrl + "/foooverlay/" + manager.ProposalCollection, - expectedErr: true, - expectedErrCode: 500, - }, - { - name: "DumplicateName", - obj: module.ProposalObject{ - Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, - Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, - url: BaseUrl, - expectedErr: true, - expectedErrCode: 409, - }, - } - - for _, tcase := range tcases { - _, err := createControllerObject(tcase.url, &tcase.obj, &module.ProposalObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestUpdateObject(t *testing.T) { - tcases := []struct { - name string - object_name string - obj module.ProposalObject - expectedErr bool - expectedErrCode int - }{ - { - name: "EmptyName", - object_name: "proposal1", - obj: module.ProposalObject{ - Metadata: module.ObjectMetaData{"", "object 1", "", ""}, - Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, - expectedErr: true, - expectedErrCode: 422, - }, - { - name: "MisMatchName", - object_name: "proposal2", - obj: module.ProposalObject{ - Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, - Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, - expectedErr: true, - expectedErrCode: 500, - }, - } - - for _, tcase := range tcases { - _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.ProposalObject{}) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestDeleteObject(t *testing.T) { - tcases := []struct { - name string - object_name string - expectedErr bool - expectedErrCode int - }{ - { - name: "FoolName", - object_name: "foo_name", - }, - } - - for _, tcase := range tcases { - _, err := deleteControllerObject(BaseUrl, tcase.object_name) - handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) - } -} - -func TestHappyPath(t *testing.T) { - proposal_name := "my-proposal" - - obj := module.ProposalObject{ - Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""}, - Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}} - - obj_update := module.ProposalObject{ - Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""}, - Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}} - - ret_obj, err := createControllerObject(BaseUrl, &obj, &module.ProposalObject{}) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes256" { - t.Errorf("Test Case 'Happy Path' failed: create object") - return - } - - ret_obj, err = updateControllerObject(BaseUrl, proposal_name, &obj_update, &module.ProposalObject{}) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: update object") - return - } - - if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes512" { - t.Errorf("Test Case 'Happy Path' failed: update object") - return - } - - _, err = deleteControllerObject(BaseUrl, proposal_name) - if err != nil { - printError(err) - t.Errorf("Test Case 'Happy Path' failed: delete object") - return - } -} \ No newline at end of file +package test + +import ( + "encoding/json" + "flag" + "fmt" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/manager" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "os" + "testing" +) + +var BaseUrl string +var OverlayUrl string + +func TestMain(m *testing.M) { + servIp := flag.String("ip", "127.0.0.1", "SDEWAN Central Controller IP Address") + flag.Parse() + OverlayUrl = "http://" + *servIp + ":9015/scc/v1/" + manager.OverlayCollection + IPBaseUrl := OverlayUrl + "/overlay1/" + manager.IPRangeCollection + BaseUrl = OverlayUrl + "/overlay1/" + manager.ProposalCollection + + var overlay_object = module.OverlayObject{ + Metadata: module.ObjectMetaData{"overlay1", "", "", ""}, + Specification: module.OverlayObjectSpec{}} + + var iprange_object1 = module.IPRangeObject{ + Metadata: module.ObjectMetaData{"ipr1", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.0.2", 10, 20}} + var iprange_object2 = module.IPRangeObject{ + Metadata: module.ObjectMetaData{"ipr2", "", "", ""}, + Specification: module.IPRangeObjectSpec{"192.168.2.2", 18, 20}} + + var proposal_object1 = module.ProposalObject{ + Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, + Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}} + var proposal_object2 = module.ProposalObject{ + Metadata: module.ObjectMetaData{"proposal2", "", "", ""}, + Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}} + + createControllerObject(OverlayUrl, &overlay_object, &module.OverlayObject{}) + createControllerObject(IPBaseUrl, &iprange_object1, &module.IPRangeObject{}) + createControllerObject(IPBaseUrl, &iprange_object2, &module.IPRangeObject{}) + createControllerObject(BaseUrl, &proposal_object1, &module.ProposalObject{}) + createControllerObject(BaseUrl, &proposal_object2, &module.ProposalObject{}) + + var ret = m.Run() + + deleteControllerObject(BaseUrl, "proposal1") + deleteControllerObject(BaseUrl, "proposal2") + deleteControllerObject(IPBaseUrl, "ipr1") + deleteControllerObject(IPBaseUrl, "ipr2") + deleteControllerObject(OverlayUrl, "overlay1") + + os.Exit(ret) +} + +func TestGetObjects(t *testing.T) { + url := BaseUrl + res, err := callRest("GET", url, "") + if err != nil { + printError(err) + t.Errorf("Test case GetObjects: can not get Objects") + return + } + + var objs []module.ProposalObject + err = json.Unmarshal([]byte(res), &objs) + + if len(objs) == 0 { + fmt.Printf("Test case GetObjects: no object found") + return + } + + p_data, _ := json.Marshal(objs) + fmt.Printf("%s\n", string(p_data)) +} + +func TestGetObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "Normal", + object_name: "proposal1", + }, + { + name: "GetFoolName", + object_name: "foo_name", + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := getControllerObject(BaseUrl, tcase.object_name, &module.ProposalObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestCreateObject(t *testing.T) { + tcases := []struct { + name string + url string + obj module.ProposalObject + expectedErr bool + expectedErrCode int + }{ + { + name: "EmptyName", + obj: module.ProposalObject{ + Metadata: module.ObjectMetaData{"", "object 1", "", ""}, + Specification: module.ProposalObjectSpec{}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "WrongOverlayName", + obj: module.ProposalObject{ + Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, + Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, + url: OverlayUrl + "/foooverlay/" + manager.ProposalCollection, + expectedErr: true, + expectedErrCode: 500, + }, + { + name: "DumplicateName", + obj: module.ProposalObject{ + Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, + Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, + url: BaseUrl, + expectedErr: true, + expectedErrCode: 409, + }, + } + + for _, tcase := range tcases { + _, err := createControllerObject(tcase.url, &tcase.obj, &module.ProposalObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestUpdateObject(t *testing.T) { + tcases := []struct { + name string + object_name string + obj module.ProposalObject + expectedErr bool + expectedErrCode int + }{ + { + name: "EmptyName", + object_name: "proposal1", + obj: module.ProposalObject{ + Metadata: module.ObjectMetaData{"", "object 1", "", ""}, + Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, + expectedErr: true, + expectedErrCode: 422, + }, + { + name: "MisMatchName", + object_name: "proposal2", + obj: module.ProposalObject{ + Metadata: module.ObjectMetaData{"proposal1", "", "", ""}, + Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}}, + expectedErr: true, + expectedErrCode: 500, + }, + } + + for _, tcase := range tcases { + _, err := updateControllerObject(BaseUrl, tcase.object_name, &tcase.obj, &module.ProposalObject{}) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestDeleteObject(t *testing.T) { + tcases := []struct { + name string + object_name string + expectedErr bool + expectedErrCode int + }{ + { + name: "FoolName", + object_name: "foo_name", + }, + } + + for _, tcase := range tcases { + _, err := deleteControllerObject(BaseUrl, tcase.object_name) + handleError(t, err, tcase.name, tcase.expectedErr, tcase.expectedErrCode) + } +} + +func TestHappyPath(t *testing.T) { + proposal_name := "my-proposal" + + obj := module.ProposalObject{ + Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""}, + Specification: module.ProposalObjectSpec{"aes256", "sha256", "modp4096"}} + + obj_update := module.ProposalObject{ + Metadata: module.ObjectMetaData{proposal_name, "object 1", "", ""}, + Specification: module.ProposalObjectSpec{"aes512", "sha512", "modp4096"}} + + ret_obj, err := createControllerObject(BaseUrl, &obj, &module.ProposalObject{}) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes256" { + t.Errorf("Test Case 'Happy Path' failed: create object") + return + } + + ret_obj, err = updateControllerObject(BaseUrl, proposal_name, &obj_update, &module.ProposalObject{}) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: update object") + return + } + + if ret_obj.(*module.ProposalObject).Specification.Encryption != "aes512" { + t.Errorf("Test Case 'Happy Path' failed: update object") + return + } + + _, err = deleteControllerObject(BaseUrl, proposal_name) + if err != nil { + printError(err) + t.Errorf("Test Case 'Happy Path' failed: delete object") + return + } +} diff --git a/central-controller/src/scc/test/utilis.go b/central-controller/src/scc/test/utilis.go index 516f103..e24351a 100644 --- a/central-controller/src/scc/test/utilis.go +++ b/central-controller/src/scc/test/utilis.go @@ -1,144 +1,144 @@ -package test - -import ( - "fmt" - "io/ioutil" - - "net/http" - - "bytes" - "reflect" - "testing" - "encoding/json" - "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" -) - -type TestError struct { - Code int - Message string -} - -func (e *TestError) Error() string { - return fmt.Sprintf("Error Code: %d, Error Message: %s", e.Code, e.Message) -} - -// Error handler -func handleError(t *testing.T, err error, name string, expectedErr bool, errorCode int) { - if (err != nil) { - if (expectedErr) { - switch err.(type) { - case *TestError: - if(errorCode != err.(*TestError).Code) { - t.Errorf("Test case '%s': expected '%d', but got '%d'", name, errorCode, err.(*TestError).Code) - } else { - fmt.Printf("%s\n", err.(*TestError).Message) - } - default: - t.Errorf("Test case '%s': expected openwrt.OpenwrtError, but got '%s'", name, reflect.TypeOf(err).String()) - } - } else { - t.Errorf("Test case '%s': expected success, but got '%s'", name, reflect.TypeOf(err).String()) - } - } else { - if (expectedErr) { - t.Errorf("Test case '%s': expected error code '%d', but success", name, errorCode) - } - } -} - -func printError(err error) { - switch err.(type) { - case *TestError: - fmt.Printf("%s\n", err.(*TestError).Message) - default: - fmt.Printf("%s\n", reflect.TypeOf(err).String()) - } -} - -func callRest(method string, url string, request string) (string, error) { - client := &http.Client{} - req_body := bytes.NewBuffer([]byte(request)) - req, _ := http.NewRequest(method, url, req_body) - - req.Header.Set("Cache-Control", "no-cache") - - resp, err := client.Do(req) - if err != nil { - return "", err - } - defer resp.Body.Close() - - body, _ := ioutil.ReadAll(resp.Body) - if resp.StatusCode >= 400 { - return "", &TestError{Code: resp.StatusCode, Message: string(body)} - } - - return string(body), nil -} - -func createControllerObject(baseUrl string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) { - url := baseUrl - obj_str, _ := json.Marshal(obj) - - res, err := callRest("POST", url, string(obj_str)) - if err != nil { - return retObj, err - } - - err = json.Unmarshal([]byte(res), retObj) - if err != nil { - return retObj, err - } - - return retObj, nil -} - -func getControllerObject(baseUrl string, name string, retObj module.ControllerObject) (module.ControllerObject, error) { - url := baseUrl + "/" + name - - res, err := callRest("GET", url, "") - if err != nil { - return retObj, err - } - - err = json.Unmarshal([]byte(res), retObj) - if err != nil { - return retObj, err - } - - return retObj, nil -} - -func updateControllerObject(baseUrl string, name string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) { - url := baseUrl + "/" + name - obj_str, _ := json.Marshal(obj) - - res, err := callRest("PUT", url, string(obj_str)) - if err != nil { - return retObj, err - } - - err = json.Unmarshal([]byte(res), retObj) - if err != nil { - return retObj, err - } - - return retObj, nil -} - -func deleteControllerObject(baseUrl string, name string) (bool, error) { - url := baseUrl + "/" + name - - _, err := callRest("DELETE", url, "") - if err != nil { - printError(err) - return false, err - } - - _, err = callRest("GET", url, "") - if err == nil { - return false, &TestError{Code: 500, Message: "Filed to delete object"} - } - - return true, nil -} \ No newline at end of file +package test + +import ( + "fmt" + "io/ioutil" + + "net/http" + + "bytes" + "encoding/json" + "github.com/akraino-edge-stack/icn-sdwan/central-controller/src/scc/pkg/module" + "reflect" + "testing" +) + +type TestError struct { + Code int + Message string +} + +func (e *TestError) Error() string { + return fmt.Sprintf("Error Code: %d, Error Message: %s", e.Code, e.Message) +} + +// Error handler +func handleError(t *testing.T, err error, name string, expectedErr bool, errorCode int) { + if err != nil { + if expectedErr { + switch err.(type) { + case *TestError: + if errorCode != err.(*TestError).Code { + t.Errorf("Test case '%s': expected '%d', but got '%d'", name, errorCode, err.(*TestError).Code) + } else { + fmt.Printf("%s\n", err.(*TestError).Message) + } + default: + t.Errorf("Test case '%s': expected openwrt.OpenwrtError, but got '%s'", name, reflect.TypeOf(err).String()) + } + } else { + t.Errorf("Test case '%s': expected success, but got '%s'", name, reflect.TypeOf(err).String()) + } + } else { + if expectedErr { + t.Errorf("Test case '%s': expected error code '%d', but success", name, errorCode) + } + } +} + +func printError(err error) { + switch err.(type) { + case *TestError: + fmt.Printf("%s\n", err.(*TestError).Message) + default: + fmt.Printf("%s\n", reflect.TypeOf(err).String()) + } +} + +func callRest(method string, url string, request string) (string, error) { + client := &http.Client{} + req_body := bytes.NewBuffer([]byte(request)) + req, _ := http.NewRequest(method, url, req_body) + + req.Header.Set("Cache-Control", "no-cache") + + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + if resp.StatusCode >= 400 { + return "", &TestError{Code: resp.StatusCode, Message: string(body)} + } + + return string(body), nil +} + +func createControllerObject(baseUrl string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) { + url := baseUrl + obj_str, _ := json.Marshal(obj) + + res, err := callRest("POST", url, string(obj_str)) + if err != nil { + return retObj, err + } + + err = json.Unmarshal([]byte(res), retObj) + if err != nil { + return retObj, err + } + + return retObj, nil +} + +func getControllerObject(baseUrl string, name string, retObj module.ControllerObject) (module.ControllerObject, error) { + url := baseUrl + "/" + name + + res, err := callRest("GET", url, "") + if err != nil { + return retObj, err + } + + err = json.Unmarshal([]byte(res), retObj) + if err != nil { + return retObj, err + } + + return retObj, nil +} + +func updateControllerObject(baseUrl string, name string, obj module.ControllerObject, retObj module.ControllerObject) (module.ControllerObject, error) { + url := baseUrl + "/" + name + obj_str, _ := json.Marshal(obj) + + res, err := callRest("PUT", url, string(obj_str)) + if err != nil { + return retObj, err + } + + err = json.Unmarshal([]byte(res), retObj) + if err != nil { + return retObj, err + } + + return retObj, nil +} + +func deleteControllerObject(baseUrl string, name string) (bool, error) { + url := baseUrl + "/" + name + + _, err := callRest("DELETE", url, "") + if err != nil { + printError(err) + return false, err + } + + _, err = callRest("GET", url, "") + if err == nil { + return false, &TestError{Code: 500, Message: "Filed to delete object"} + } + + return true, nil +}