aboutsummaryrefslogtreecommitdiffstats
path: root/src/dcm
diff options
context:
space:
mode:
authorIgor D.C <igor.duarte.cardoso@intel.com>2020-09-25 22:31:11 +0000
committerIgor D.C <igor.duarte.cardoso@intel.com>2020-09-25 23:24:29 +0000
commit8c0cc1278cc4d84863b076b2014b9bc9d8805218 (patch)
tree6f2274560030252710464db5b6ae93da8a0dce2e /src/dcm
parent425795c7d4e6ce81932918aca2a1462384d4507f (diff)
Implement Terminate operation in DCM
Also makes minor changes to non-terminate code as a side-effect of supporting the new Terminate operation (such as including tagContext in the LogicalCloudClient implementation of LogicalCloudManager interface). These changes are/will also be leveraged by other operations. Issue-ID: MULTICLOUD-1143 Change-Id: Idbd2ec9f6cf0e5584a0f51cf4c16144db56d9fa0 Signed-off-by: Igor D.C <igor.duarte.cardoso@intel.com>
Diffstat (limited to 'src/dcm')
-rw-r--r--src/dcm/api/api.go4
-rw-r--r--src/dcm/api/logicalCloudHandler.go48
-rw-r--r--src/dcm/pkg/module/apply.go90
-rw-r--r--src/dcm/pkg/module/logicalcloud.go36
-rw-r--r--src/dcm/pkg/module/logicalcloud_test.go8
5 files changed, 179 insertions, 7 deletions
diff --git a/src/dcm/api/api.go b/src/dcm/api/api.go
index de1d5c97..0f68a517 100644
--- a/src/dcm/api/api.go
+++ b/src/dcm/api/api.go
@@ -44,6 +44,7 @@ func NewRouter(
quotaClient = module.NewQuotaClient()
}
+ // Set up Logical Cloud API
logicalCloudHandler := logicalCloudHandler{client: logicalCloudClient,
clusterClient: clusterClient,
quotaClient: quotaClient,
@@ -67,6 +68,9 @@ func NewRouter(
lcRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/apply",
logicalCloudHandler.applyHandler).Methods("POST")
+ lcRouter.HandleFunc(
+ "/logical-clouds/{logical-cloud-name}/terminate",
+ logicalCloudHandler.terminateHandler).Methods("POST")
// To Do
// get kubeconfig
/*lcRouter.HandleFunc(
diff --git a/src/dcm/api/logicalCloudHandler.go b/src/dcm/api/logicalCloudHandler.go
index 36ec4e05..2e1811b7 100644
--- a/src/dcm/api/logicalCloudHandler.go
+++ b/src/dcm/api/logicalCloudHandler.go
@@ -25,6 +25,7 @@ import (
"github.com/gorilla/mux"
"github.com/onap/multicloud-k8s/src/dcm/pkg/module"
+ pkgerrors "github.com/pkg/errors"
)
// logicalCloudHandler is used to store backend implementations objects
@@ -212,3 +213,50 @@ func (h logicalCloudHandler) applyHandler(w http.ResponseWriter, r *http.Request
return
}
+
+func (h logicalCloudHandler) terminateHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ name := vars["logical-cloud-name"]
+
+ // Get logical cloud
+ lc, err := h.client.Get(project, name)
+ if err != nil {
+ if err.Error() == "Logical Cloud does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
+ return
+ }
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ _, ctxVal, err := h.client.GetLogicalCloudContext(name)
+ if ctxVal == "" {
+ err = pkgerrors.New("Logical Cloud hasn't been applied yet")
+ http.Error(w, err.Error(), http.StatusConflict)
+ return
+ }
+
+ // Get Clusters
+ clusters, err := h.clusterClient.GetAllClusters(project, name)
+
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ //Get Quotas
+ quotas, err := h.quotaClient.GetAllQuotas(project, name)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ err = module.DestroyEtcdContext(lc, clusters, quotas)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ return
+}
diff --git a/src/dcm/pkg/module/apply.go b/src/dcm/pkg/module/apply.go
index dbcbf8ac..84eb7ef7 100644
--- a/src/dcm/pkg/module/apply.go
+++ b/src/dcm/pkg/module/apply.go
@@ -28,11 +28,16 @@ import (
"strings"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/grpc/installappclient"
log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/controller"
pkgerrors "github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
+// rsyncName denotes the name of the rsync controller
+const rsyncName = "rsync"
+
type Resource struct {
ApiVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
@@ -218,6 +223,45 @@ func createUserCSR(logicalcloud LogicalCloud) (string, error) {
}
+/*
+queryDBAndSetRsyncInfo queries the MCO db to find the record the sync controller
+and then sets the RsyncInfo global variable.
+*/
+func queryDBAndSetRsyncInfo() (installappclient.RsyncInfo, error) {
+ client := controller.NewControllerClient()
+ vals, _ := client.GetControllers()
+ for _, v := range vals {
+ if v.Metadata.Name == rsyncName {
+ log.Info("Initializing RPC connection to resource synchronizer", log.Fields{
+ "Controller": v.Metadata.Name,
+ })
+ rsyncInfo := installappclient.NewRsyncInfo(v.Metadata.Name, v.Spec.Host, v.Spec.Port)
+ return rsyncInfo, nil
+ }
+ }
+ return installappclient.RsyncInfo{}, pkgerrors.Errorf("queryRsyncInfoInMCODB Failed - Could not get find rsync by name : %v", rsyncName)
+}
+
+/*
+callRsyncUninstall method shall take in the app context id and invoke the rsync service via grpc
+*/
+func callRsyncUninstall(contextid interface{}) error {
+ rsyncInfo, err := queryDBAndSetRsyncInfo()
+ log.Info("Calling the Rsync ", log.Fields{
+ "RsyncName": rsyncInfo.RsyncName,
+ })
+ if err != nil {
+ return err
+ }
+
+ appContextID := fmt.Sprintf("%v", contextid)
+ err = installappclient.InvokeUninstallApp(appContextID)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
// TODO:
// Install istio
// Store user key for user creation
@@ -422,3 +466,49 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
return nil
}
+
+// TODO: rename these methods
+// DestroyEtcdContext remove from rsync then delete appcontext and all resources
+func DestroyEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
+ quotaList []Quota) error {
+
+ logicalCloudName := logicalcloud.MetaData.LogicalCloudName
+ // project := "test-project" // FIXME(igordc): temporary, need to do some rework in the LC structs
+
+ _, ctxVal, err := NewLogicalCloudClient().GetLogicalCloudContext(logicalCloudName)
+ if err != nil {
+ return pkgerrors.Wrapf(err, "Error finding AppContext for Logical Cloud: %v", logicalCloudName)
+ }
+
+ // call resource synchronizer to delete the CRs from every cluster of the logical cloud
+ err = callRsyncUninstall(ctxVal)
+ if err != nil {
+ return err
+ }
+
+ // TODO: status handling for logical cloud after terminate:
+ // rsync updates the status of the appcontext to Terminated
+ // dcm should launch thread to observe status of appcontext before concluding logical cloud is terminated
+ // dcm should somewhat mimic the status tracking of rsync
+ // logical cloud might be in a non-applied non-terminated state for a long period of time.........
+
+ // // remove the app context
+ // err = context.DeleteCompositeApp()
+ // if err != nil {
+ // return pkgerrors.Wrap(err, "Error deleting AppContext CompositeApp")
+ // }
+
+ // remove the app context field from the cluster db record
+ // lckey := LogicalCloudKey{
+ // LogicalCloudName: logicalcloud.MetaData.LogicalCloudName,
+ // Project: project,
+ // }
+ // err = db.DBconn.RemoveTag("orchestrator", lckey, "lccontext")
+ // if err != nil {
+ // log.Warn("Error removing AppContext from Logical Cloud", log.Fields{
+ // "logical-cloud": logicalCloudName,
+ // })
+ // }
+
+ return nil
+}
diff --git a/src/dcm/pkg/module/logicalcloud.go b/src/dcm/pkg/module/logicalcloud.go
index 7d3c806b..9b8ff703 100644
--- a/src/dcm/pkg/module/logicalcloud.go
+++ b/src/dcm/pkg/module/logicalcloud.go
@@ -17,6 +17,7 @@
package module
import (
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
@@ -72,6 +73,7 @@ type LogicalCloudManager interface {
GetAll(project string) ([]LogicalCloud, error)
Delete(project, name string) error
Update(project, name string, c LogicalCloud) (LogicalCloud, error)
+ GetLogicalCloudContext(name string) (appcontext.AppContext, string, error)
}
// Interface facilitates unit testing by mocking functions
@@ -87,9 +89,10 @@ type Utility interface {
// LogicalCloudClient implements the LogicalCloudManager
// It will also be used to maintain some localized state
type LogicalCloudClient struct {
- storeName string
- tagMeta string
- util Utility
+ storeName string
+ tagMeta string
+ tagContext string
+ util Utility
}
// Added for unit testing; implements Utility interface
@@ -227,6 +230,33 @@ func (v *LogicalCloudClient) Update(project, logicalCloudName string, c LogicalC
return c, nil
}
+// GetClusterContext returns the AppContext for corresponding provider and name
+func (v *LogicalCloudClient) GetLogicalCloudContext(name string) (appcontext.AppContext, string, error) {
+ //Construct key and tag to select the entry
+ key := LogicalCloudKey{
+ LogicalCloudName: name,
+ Project: "test-project", // FIXME(igordc): temporary, need to do some rework in the LC structs
+ }
+
+ value, err := db.DBconn.Find(v.storeName, key, v.tagContext)
+ if err != nil {
+ return appcontext.AppContext{}, "", pkgerrors.Wrap(err, "Get Logical Cloud Context")
+ }
+
+ //value is a byte array
+ if value != nil {
+ ctxVal := string(value[0])
+ var lcc appcontext.AppContext
+ _, err = lcc.LoadAppContext(ctxVal)
+ if err != nil {
+ return appcontext.AppContext{}, "", pkgerrors.Wrap(err, "Reinitializing Logical Cloud AppContext")
+ }
+ return lcc, ctxVal, nil
+ }
+
+ return appcontext.AppContext{}, "", pkgerrors.New("Error getting Logical Cloud AppContext")
+}
+
func (d DBService) DBInsert(storeName string, key db.Key, query interface{}, meta string, c interface{}) error {
err := db.DBconn.Insert(storeName, key, nil, meta, c)
diff --git a/src/dcm/pkg/module/logicalcloud_test.go b/src/dcm/pkg/module/logicalcloud_test.go
index fb205753..0a0e2f5d 100644
--- a/src/dcm/pkg/module/logicalcloud_test.go
+++ b/src/dcm/pkg/module/logicalcloud_test.go
@@ -78,7 +78,7 @@ func TestCreateLogicalCloud(t *testing.T) {
myMocks.On("DBInsert", "test_dcm", key, nil, "test_meta", lc).Return(nil)
myMocks.On("DBFind", "test_dcm", key, "test_meta").Return(data1, err1)
- lcClient := LogicalCloudClient{"test_dcm", "test_meta", myMocks}
+ lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
_, err := lcClient.Create("test_project", lc)
if err != nil {
t.Errorf("Some error occured!")
@@ -101,7 +101,7 @@ func TestGetLogicalCloud(t *testing.T) {
myMocks.On("DBFind", "test_dcm", key, "test_meta").Return(data1, nil)
myMocks.On("DBUnmarshal", data2).Return(nil)
- lcClient := LogicalCloudClient{"test_dcm", "test_meta", myMocks}
+ lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
_, err := lcClient.Get("test_project", "test_asdf")
if err != nil {
t.Errorf("Some error occured!")
@@ -119,7 +119,7 @@ func TestDeleteLogicalCloud(t *testing.T) {
myMocks.On("DBRemove", "test_dcm", key).Return(nil)
- lcClient := LogicalCloudClient{"test_dcm", "test_meta", myMocks}
+ lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
err := lcClient.Delete("test_project", "test_asdf")
if err != nil {
t.Errorf("Some error occured!")
@@ -148,7 +148,7 @@ func TestUpdateLogicalCloud(t *testing.T) {
myMocks.On("DBInsert", "test_dcm", key, nil, "test_meta", lc).Return(nil)
myMocks.On("DBFind", "test_dcm", key, "test_meta").Return(data1, nil)
myMocks.On("DBUnmarshal", data2).Return(nil)
- lcClient := LogicalCloudClient{"test_dcm", "test_meta", myMocks}
+ lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
_, err := lcClient.Update("test_project", "test_asdf", lc)
if err != nil {
t.Errorf("Some error occured!")