diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/ha-api.iml b/.idea/ha-api.iml new file mode 100644 index 0000000000000000000000000000000000000000..5e764c4f0b9a64bb78a5babfdd583713b2df47bf --- /dev/null +++ b/.idea/ha-api.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..8150a2729f28c2c62a9eb98917d40d75a96d05ca --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/controllers/cluster.go b/controllers/cluster.go index e6885c0c33de12141ae68327dc9f1ec1b078336d..ba08b7e63e0abe38194d0c1b01051fc13868c1f6 100644 --- a/controllers/cluster.go +++ b/controllers/cluster.go @@ -42,6 +42,14 @@ type ClusterDestroyController struct { web.Controller } +type ClustersStatusController struct { + web.Controller +} + +type ClusterRemoveController struct { + web.Controller +} + func (mcc *MultipleClustersController) Post() { logs.Debug("Handle post request in MultipleClustersController.") result := map[string]interface{}{} @@ -105,6 +113,13 @@ func (cc *ClustersController) Get() { cc.ServeJSON() } +func (csc *ClustersStatusController) Get() { + logs.Debug("handle get request in ClustersController.") + result := models.GetClusterInfo() + csc.Data["json"] = &result + csc.ServeJSON() +} + func (cc *ClustersController) Post() { logs.Debug("handle post request in ClustersController.") cc.ServeJSON() @@ -118,6 +133,24 @@ func (cd *ClusterDestroyController) Post() { cd.ServeJSON() } +func (crc *ClusterRemoveController) Post() { + logs.Debug("handle post request in ClustersController.") + var Result models.RemoveRet + var ReqData models.RemoveData + body := crc.Ctx.Input.RequestBody + err := json.Unmarshal(body, &ReqData) + if err != nil { + Result.Action = false + Result.Error = "invalid input data" + crc.Data["json"] = &Result + crc.ServeJSON() + } else { + Result2 := models.ClusterRemove(ReqData) + crc.Data["json"] = Result2 + crc.ServeJSON() + } +} + func (cc *ClustersController) Put() { logs.Debug("handle put request in ClustersController.") result := map[string]interface{}{} diff --git a/models/manage_clusters.go b/models/manage_clusters.go index ef64e9ff49f1ac9cec0e2bced2cdbec7fa6fcb9e..b8ca4b507cbed3a84bda382524fc0276922930e8 100644 --- a/models/manage_clusters.go +++ b/models/manage_clusters.go @@ -14,6 +14,17 @@ import ( var clustersFileName = "/usr/share/heartbeat-gui/ha-api/ClustersInfo.conf" var port = 8088 +type RemoveData struct { + Cluster_name []string +} + +type RemoveRet struct { + Action bool `json:"action,omitempty"` + Error string `json:"error,omitempty"` + Faild_cluster []string `json:"faild_cluster,omitempty"` + Data []bool `json:"data,omitempty"` +} + // ClusterInfo is a structure representing information about clusters. type ClusterInfo struct { Text map[string]interface{} @@ -96,10 +107,21 @@ func (ci *ClusterInfo) SetVersion(version int) { ci.Version = version } +func (ci *ClusterInfo) DeleteCluster(clusterNameJson string) bool { + for i, c := range ci.Clusters { + cV := c.(map[string]interface{}) + if cV["cluster_name"] == clusterNameJson { + ci.Clusters = append(ci.Clusters[:i], ci.Clusters[i+1:]...) + return true + } + } + return false +} + // localClusterInfo retrieves the cluster information locally and returns it as a map. // If no cluster exists, an empty map is returned. func localClusterInfo() map[string]interface{} { - allInfo := getClusterInfo() + allInfo := GetClusterInfo() if allInfo["cluster_exist"] == true { clusterInfo := clusterInfoParse(allInfo) return clusterInfo @@ -172,6 +194,7 @@ func readFile(filename string) map[string]interface{} { return newDict } +// comment out due to type error as localconf could not be {}, it should be of type *ClusterInfo // SyncConfig synchronizes the local configuration with remote configuration. // Returns appropriate results indicating the synchronization status. func SyncConfig(remoteConf map[string]interface{}) map[string]interface{} { @@ -341,16 +364,23 @@ func ClusterSetup(clusterInfo map[string]interface{}) map[string]interface{} { } } -func ClustersDestroy() map[string]interface{} { - res := map[string]interface{}{} - cmd := "pcs cluster destroy --all" - out, err := utils.RunCommand(cmd) - if err != nil { - res["action"] = false - res["error"] = string(out) - return res +func ClusterRemove(RemoveInfo RemoveData) *RemoveRet { + clusters := RemoveInfo.Cluster_name + localConf := getLocalConf() + removeRes := make([]bool, 0) + faildCluster := make([]string, 0) + for _, cluster := range clusters { + res := localConf.DeleteCluster(cluster) + removeRes = append(removeRes, res) + if res == false { + faildCluster = append(faildCluster, cluster) + } + localConf.Save() + syncClusterConfFile(localConf) } - res["action"] = true - res["message"] = string(out) - return res + var RetData RemoveRet + RetData.Action = true + RetData.Faild_cluster = faildCluster + RetData.Data = removeRes + return &RetData } diff --git a/models/nodes_management.go b/models/nodes_management.go index 3329b679128291764b897b6c926ade456276b5c0..9b3b3ab8248cac9635a8e1e86d492e456f283629 100644 --- a/models/nodes_management.go +++ b/models/nodes_management.go @@ -49,7 +49,7 @@ func getClusterName() map[string]interface{} { // getClusterInfo retrieves cluster information, including cluster nodes and their properties. // Returns the cluster information in a structured map. -func getClusterInfo() map[string]interface{} { +func GetClusterInfo() map[string]interface{} { _, currentNode := utils.RunCommand("cat /etc/hostname") currentNodeStr := strings.ReplaceAll(fmt.Sprintf("%s", currentNode), "\n", "") @@ -168,6 +168,20 @@ func generateNodeCmdStr(nodesInfo []interface{}) string { return cmd.String() } +func ClustersDestroy() map[string]interface{} { + res := map[string]interface{}{} + cmd := "pcs cluster destroy --all" + out, err := utils.RunCommand(cmd) + if err != nil { + res["action"] = false + res["error"] = string(out) + return res + } + res["action"] = true + res["message"] = string(out) + return res +} + // isIPv4 checks if the provided string is a valid IPv4 address. // Returns true if the string is a valid IPv4 address, false otherwise. func isIPv4(ip string) bool { diff --git a/routers/router.go b/routers/router.go index 83fa75f7590ce6c6e9ba8eb6db0d510354119ce8..772a50375f8e0d71719b3fc823befe9eed22831b 100644 --- a/routers/router.go +++ b/routers/router.go @@ -32,12 +32,14 @@ func init() { ns := web.NewNamespace("/api/v1", web.NSRouter("/haclusters/1", &controllers.ClustersController{}), + web.NSRouter("/haclusters/1/cluster_status", &controllers.ClustersStatusController{}), web.NSRouter("/login", &controllers.LoginController{}), web.NSRouter("/logout", &controllers.LogoutController{}), web.NSRouter("/managec/cluster_add", &controllers.MultipleClustersController{}), web.NSRouter("/managec/sync_config", &controllers.Sync_configController{}), web.NSRouter("/managec/cluster_setup", &controllers.ClusterSetupController{}), web.NSRouter("/managec/cluster_destroy", &controllers.ClusterDestroyController{}), + web.NSRouter("/managec/cluster_remove", &controllers.ClusterRemoveController{}), web.NSRouter("/haclusters/1/resources", &controllers.ResourceController{}), web.NSRouter("/haclusters/1/resources/:rscID/:action", &controllers.ResourceActionController{}),