-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add configCenter module, support aliyun mse instance and config query
- Loading branch information
liuxinwang
committed
Dec 6, 2023
1 parent
21564d8
commit 17606f7
Showing
9 changed files
with
633 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package handler | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
"horizon/service" | ||
) | ||
|
||
func ConfigCenterInstanceGet(c *gin.Context) { | ||
service.ConfigCenterInstanceSelectByList(c) | ||
} | ||
|
||
func ConfigCenterInstanceConfigGet(c *gin.Context) { | ||
service.ConfigCenterInstanceConfigSelectByList(c) | ||
} | ||
|
||
func ConfigCenterInstanceConfigDataGet(c *gin.Context) { | ||
service.ConfigCenterInstanceConfigSelectByData(c) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package model | ||
|
||
type ConfigCenterInstance struct { | ||
MseVersion string `json:"mseVersion"` | ||
InternetAddress string `json:"internetAddress"` | ||
ResourceGroupId string `json:"resourceGroupId"` | ||
InstanceId string `json:"instanceId"` | ||
ClusterId string `json:"clusterId"` | ||
CreateTime string `json:"createTime"` | ||
ClusterType string `json:"clusterType"` | ||
EndDate string `json:"endDate"` | ||
ClusterAliasName string `json:"clusterAliasName"` | ||
AppVersion string `json:"appVersion"` | ||
VersionCode string `json:"versionCode"` | ||
InstanceCount int `json:"instanceCount"` | ||
IntranetAddress string `json:"intranetAddress"` | ||
CanUpdate bool `json:"canUpdate"` | ||
VpcId string `json:"vpcId"` | ||
ChargeType string `json:"chargeType"` | ||
ClusterName string `json:"clusterName"` | ||
InitStatus string `json:"initStatus"` | ||
MaintenancePeriod struct { | ||
} `json:"maintenancePeriod"` | ||
IntranetDomain string `json:"intranetDomain"` | ||
Tags struct { | ||
AcsRmRgId string `json:"acs:rm:rgId"` | ||
} `json:"tags"` | ||
Namespaces []ConfigCenterNamespace `json:"namespaces"` | ||
} | ||
|
||
type ConfigCenterNamespace struct { | ||
Type int `json:"type"` | ||
Quota int `json:"quota"` | ||
ConfigCount int `json:"configCount"` | ||
SourceType string `json:"sourceType"` | ||
NamespaceShowName string `json:"namespaceShowName"` | ||
Namespace string `json:"namespace"` | ||
ServiceCount int `json:"serviceCount"` | ||
NamespaceId string `json:"namespaceId" form:"namespaceId"` | ||
} | ||
|
||
type ConfigCenterInstanceConfig struct { | ||
Group string `json:"group" form:"group"` | ||
Desc string `json:"desc" form:"desc"` | ||
Type string `json:"type" form:"type"` | ||
DataId string `json:"dataId" form:"dataId"` | ||
EncryptedDataKey string `json:"encryptedDataKey" form:"encryptedDataKey"` | ||
Content string `json:"content" form:"content"` | ||
AppName string `json:"appName" form:"appName"` | ||
Md5 string `json:"md5" form:"md5"` | ||
InstanceId string `json:"instanceId" form:"instanceId"` | ||
NamespaceId string `json:"namespaceId" form:"namespaceId"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package model | ||
|
||
import "time" | ||
|
||
type DataMigrateJob struct { | ||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"` | ||
Name string `gorm:"type:varchar(50);not null;comment:任务名称" json:"name"` | ||
SourceInstId string `gorm:"type:varchar(20);not null;comment:源实例ID" json:"sourceInstId"` | ||
SourceDb string `gorm:"type:varchar(20);not null;comment:源数据库" json:"sourceDb"` | ||
TargetInstId string `gorm:"type:varchar(20);not null;comment:目的实例ID" json:"targetInstId"` | ||
TargetDb string `gorm:"type:varchar(20);not null;comment:目的数据库" json:"targetDb"` | ||
Status string `gorm:"type:enum('Start', 'Stop', 'Running', 'Error', 'Finished');default:'Running';not null;comment:任务状态" json:"status"` | ||
CreatedAt time.Time `gorm:"type:datetime;not null;default:current_timestamp;comment:创建时间" json:"createdAt"` | ||
UpdatedAt time.Time `gorm:"type:datetime;not null;default:current_timestamp on update current_timestamp;comment:修改时间" json:"updatedAt"` | ||
} | ||
|
||
type DataMigrateJobDetail struct { | ||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"` | ||
TableName string `gorm:"type:varchar(50);not null;comment:表名称" json:"tableName"` | ||
Status string `gorm:"type:enum('Start', 'Stop', 'Running', 'Error');default:'Running';not null;comment:同步状态" json:"status"` | ||
CreatedAt time.Time `gorm:"type:datetime;not null;default:current_timestamp;comment:创建时间" json:"createdAt"` | ||
UpdatedAt time.Time `gorm:"type:datetime;not null;default:current_timestamp on update current_timestamp;comment:修改时间" json:"updatedAt"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
package service | ||
|
||
import ( | ||
"encoding/json" | ||
"github.com/gin-gonic/gin" | ||
"github.com/mitchellh/mapstructure" | ||
"gopkg.in/yaml.v3" | ||
"horizon/model" | ||
"horizon/utils" | ||
"math" | ||
"net/http" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// ConfigCenterInstanceSelectByList 查询实例列表 | ||
func ConfigCenterInstanceSelectByList(c *gin.Context) { | ||
// 变量初始化 | ||
pageNo, _ := strconv.Atoi(c.Query("pageNo")) | ||
pageSize, _ := strconv.Atoi(c.Query("pageSize")) | ||
clusterAliasName := c.Query("clusterAliasName") | ||
var configCenterInstances []model.ConfigCenterInstance | ||
var totalCount int64 | ||
data := gin.H{"totalCount": 0, "data": &[]model.ConfigCenterInstance{}, "pageNo": pageNo, "pageSize": pageSize, "totalPage": 0} | ||
|
||
clusters, err := utils.ListClusters(pageNo, pageSize, clusterAliasName) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": data, "err": err.Error()}) | ||
return | ||
} | ||
body := clusters["body"] | ||
if b, ok := body.(map[string]interface{}); ok { | ||
instanceData := b["Data"] | ||
if tc, isInt := b["TotalCount"].(json.Number); isInt { | ||
totalCount, _ = tc.Int64() | ||
} | ||
if d, ok2 := instanceData.([]interface{}); ok2 { | ||
for _, cluster := range d { | ||
var configCenterInstance model.ConfigCenterInstance | ||
err := mapstructure.Decode(cluster, &configCenterInstance) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": data, "err": err.Error()}) | ||
return | ||
} | ||
// 查询实例空间 | ||
namespaces, err := configCenterInstanceNamespaceSelectByList(configCenterInstance.InstanceId) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": data, "err": err.Error()}) | ||
return | ||
} | ||
configCenterInstance.Namespaces = namespaces | ||
configCenterInstances = append(configCenterInstances, configCenterInstance) | ||
} | ||
} | ||
} | ||
|
||
// 处理结果集并返回 | ||
totalPage := math.Ceil(float64(totalCount) / float64(pageSize)) | ||
if totalCount > 0 { | ||
data = gin.H{"totalCount": totalCount, "data": &configCenterInstances, "pageNo": pageNo, "pageSize": pageSize, "totalPage": totalPage} | ||
} | ||
c.JSON(http.StatusOK, gin.H{"code": 1, "msg": "success", "data": data, "err": ""}) | ||
} | ||
|
||
// configCenterInstanceNamespaceSelectByList 查询实例命名空间列表 | ||
func configCenterInstanceNamespaceSelectByList(instanceId string) ([]model.ConfigCenterNamespace, error) { | ||
var configCenterNamespaces []model.ConfigCenterNamespace | ||
namespaces, err := utils.ListEngineNamespaces(instanceId) | ||
if err != nil { | ||
return nil, err | ||
} | ||
body := namespaces["body"] | ||
if b, ok := body.(map[string]interface{}); ok { | ||
namespaceData := b["Data"] | ||
if d, ok2 := namespaceData.([]interface{}); ok2 { | ||
for _, namespace := range d { | ||
var configCenterNamespace model.ConfigCenterNamespace | ||
err := mapstructure.Decode(namespace, &configCenterNamespace) | ||
if err != nil { | ||
return nil, err | ||
} | ||
configCenterNamespace.NamespaceId = configCenterNamespace.NamespaceShowName | ||
configCenterNamespaces = append(configCenterNamespaces, configCenterNamespace) | ||
} | ||
} | ||
} | ||
return configCenterNamespaces, nil | ||
} | ||
|
||
// ConfigCenterInstanceConfigSelectByList 查询实例配置列表 | ||
func ConfigCenterInstanceConfigSelectByList(c *gin.Context) { | ||
// 变量初始化 | ||
pageNo, _ := strconv.Atoi(c.Query("pageNo")) | ||
pageSize, _ := strconv.Atoi(c.Query("pageSize")) | ||
instanceId := c.Query("instanceId") | ||
namespaceId := c.Query("namespaceId") | ||
dataId := c.Query("dataId") | ||
var configCenterInstanceConfigs []model.ConfigCenterInstanceConfig | ||
var totalCount int64 | ||
data := gin.H{"totalCount": 0, "data": &[]model.ConfigCenterInstanceConfig{}, "pageNo": pageNo, "pageSize": pageSize, "totalPage": 0} | ||
|
||
configs, err := utils.ListNacosConfigs(pageNo, pageSize, instanceId, namespaceId, dataId) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": data, "err": err.Error()}) | ||
return | ||
} | ||
body := configs["body"] | ||
if b, ok := body.(map[string]interface{}); ok { | ||
instanceConfigData := b["Configurations"] | ||
if tc, isInt := b["TotalCount"].(json.Number); isInt { | ||
totalCount, _ = tc.Int64() | ||
} | ||
if d, ok2 := instanceConfigData.([]interface{}); ok2 { | ||
for _, config := range d { | ||
var configCenterInstanceConfig model.ConfigCenterInstanceConfig | ||
err := mapstructure.Decode(config, &configCenterInstanceConfig) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": data, "err": err.Error()}) | ||
return | ||
} | ||
configCenterInstanceConfig.InstanceId = instanceId | ||
configCenterInstanceConfig.NamespaceId = namespaceId | ||
configCenterInstanceConfigs = append(configCenterInstanceConfigs, configCenterInstanceConfig) | ||
} | ||
} | ||
} | ||
|
||
// 处理结果集并返回 | ||
totalPage := math.Ceil(float64(totalCount) / float64(pageSize)) | ||
if totalCount > 0 { | ||
data = gin.H{"totalCount": totalCount, "data": &configCenterInstanceConfigs, "pageNo": pageNo, "pageSize": pageSize, "totalPage": totalPage} | ||
} | ||
c.JSON(http.StatusOK, gin.H{"code": 1, "msg": "success", "data": data, "err": ""}) | ||
} | ||
|
||
// ConfigCenterInstanceConfigSelectByData 查看实例配置详情 | ||
func ConfigCenterInstanceConfigSelectByData(c *gin.Context) { | ||
var configCenterInstanceConfig model.ConfigCenterInstanceConfig | ||
err := c.ShouldBind(&configCenterInstanceConfig) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": "", "err": err.Error()}) | ||
return | ||
} | ||
config, err := utils.GetNacosConfig( | ||
configCenterInstanceConfig.InstanceId, | ||
configCenterInstanceConfig.NamespaceId, | ||
configCenterInstanceConfig.DataId, | ||
configCenterInstanceConfig.Group) | ||
|
||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": nil, "err": err.Error()}) | ||
return | ||
} | ||
body := config["body"] | ||
if b, ok := body.(map[string]interface{}); ok { | ||
instanceConfigData := b["Configuration"] | ||
err := mapstructure.Decode(instanceConfigData, &configCenterInstanceConfig) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": nil, "err": err.Error()}) | ||
return | ||
} | ||
} | ||
desensitizedContent, err := desensitizedYamlConfig(configCenterInstanceConfig.Content) | ||
if err != nil { | ||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "fail", "data": nil, "err": err.Error()}) | ||
return | ||
} | ||
configCenterInstanceConfig.Content = strings.ReplaceAll(desensitizedContent, " ", " ") | ||
// 返回结果集 | ||
c.JSON(http.StatusOK, gin.H{"code": 1, "msg": "success", "data": &configCenterInstanceConfig, "err": ""}) | ||
} | ||
|
||
func desensitizedYamlConfig(content string) (string, error) { | ||
var dataNode yaml.Node | ||
err := yaml.Unmarshal([]byte(content), &dataNode) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
flag := 0 | ||
iterNode(&dataNode, &flag) | ||
marshal, err := yaml.Marshal(&dataNode) | ||
if err != nil { | ||
return "", err | ||
} | ||
return string(marshal), err | ||
} | ||
|
||
func iterNode(node *yaml.Node, flag *int) { | ||
if node.Content != nil && len(node.Content) > 0 { | ||
for _, n := range node.Content { | ||
iterNode(n, flag) | ||
} | ||
} else { | ||
if node.Value == "password" || node.Value == "appSecret" { | ||
*flag = 1 | ||
return | ||
} | ||
if *flag == 1 { | ||
desensitizedNode(node) | ||
*flag = 0 | ||
} | ||
} | ||
} | ||
|
||
func desensitizedNode(node *yaml.Node) { | ||
node.Value = "******" | ||
} |
Oops, something went wrong.