重新初始化仓库

This commit is contained in:
2021-11-30 17:50:21 +08:00
commit 6c31164c37
37 changed files with 3339 additions and 0 deletions

22
transform/ITransform.go Normal file
View File

@ -0,0 +1,22 @@
// Package transform ...
//
// Description : transform ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-11-30 3:52 下午
package transform
// ITransform 转换程序数据源处理的约束
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:56 下午 2021/11/30
type ITransform interface {
// GetNamespace 获取命名空间
GetNamespace() string
// GetSourceData 获取元数据
GetSourceData() (map[string]string, error)
// MigrateKeyFailCallback key 迁移失败之后的回调
MigrateKeyFailCallback(namespace string, key string, val string, err error)
}

3
transform/README.md Normal file
View File

@ -0,0 +1,3 @@
# 转换程序
作用 : 将其他配置中心的配置迁移至本服务

116
transform/apollo_migrate.go Normal file
View File

@ -0,0 +1,116 @@
// Package transform ...
//
// Description : transform ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-11-30 4:04 下午
package transform
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/ddliu/go-httpclient"
)
// NewApolloMigrate 从apollo迁移数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:06 下午 2021/11/30
func NewApolloMigrate(getAllApolloConfigURL string, appID string, env string, namespace string, cookie map[string]string, header map[string]string) ITransform {
if len(getAllApolloConfigURL) == 0 {
getAllApolloConfigURL = "http://test-apollo.portal.life.ke.com/apps/{APP_ID}/envs/{ENV}/clusters/default/namespaces/{NAMESPACE}/releases/active?page=0&size=1"
replaceMap := map[string]string{
"{APP_ID}": appID,
"{ENV}": env,
"{NAMESPACE}": namespace,
}
for k, v := range replaceMap {
getAllApolloConfigURL = strings.ReplaceAll(getAllApolloConfigURL, k, v)
}
}
if cookie == nil {
cookie = make(map[string]string)
header = make(map[string]string)
}
return &ApolloMigrate{
getDataURL: getAllApolloConfigURL,
cookie: cookie,
header: header,
appID: appID,
}
}
// ApolloMigrate 从apollo迁移数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:05 下午 2021/11/30
type ApolloMigrate struct {
getDataURL string
cookie map[string]string
header map[string]string
appID string
}
// GetNamespace 迁移之后,存储到哪一个命名空间
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:17 下午 2021/11/30
func (a *ApolloMigrate) GetNamespace() string {
return a.appID
}
// GetSourceData ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:18 下午 2021/11/30
func (a *ApolloMigrate) GetSourceData() (map[string]string, error) {
var (
err error
resp *httpclient.Response
responseData []byte
)
hc := httpclient.NewHttpClient()
cookieList := make([]*http.Cookie, 0)
for name, val := range a.cookie {
cookieList = append(cookieList, &http.Cookie{Name: name, Value: val})
}
resp, err = hc.WithHeaders(a.header).WithCookie(cookieList...).Get(a.getDataURL)
if nil != err {
return make(map[string]string), errors.New("apollo接口请求失败 : " + err.Error())
}
responseData, err = ioutil.ReadAll(resp.Body)
if nil != err {
return make(map[string]string), errors.New("apollo 响应数据读取失败 : " + err.Error())
}
var cfgList []ApolloData
if err = json.Unmarshal(responseData, &cfgList); nil != err {
return make(map[string]string), errors.New("apollo 数据解析失败 : " + err.Error())
}
if len(cfgList) == 0 {
return make(map[string]string), errors.New("当前apollo配置读取到的数据为空")
}
var realCfg map[string]string
if err = json.Unmarshal([]byte(cfgList[0].Configurations), &realCfg); nil != err {
return make(map[string]string), errors.New("真实配置文件解析失败 ")
}
return realCfg, nil
}
// MigrateKeyFailCallback ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:58 下午 2021/11/30
func (a *ApolloMigrate) MigrateKeyFailCallback(namespace string, key string, val string, err error) {
fmt.Println(namespace, key, val, err)
}

29
transform/define.go Normal file
View File

@ -0,0 +1,29 @@
// Package transform ...
//
// Description : transform ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-11-30 4:31 下午
package transform
// ApolloData apollo数据结构
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:32 下午 2021/11/30
type ApolloData struct {
ID int64 `json:"id"`
ReleaseKey string `json:"releaseKey"`
Name string `json:"name"`
AppID string `json:"appId"`
ClusterName string `json:"clusterName"`
NamespaceName string `json:"namespaceName"`
Configurations string `json:"configurations"`
Comment string `json:"comment"`
IsAbandoned bool `json:"isAbandoned"`
DataChangeCreatedBy string `json:"dataChangeCreatedBy"`
DataChangeLastModifiedBy string `json:"dataChangeLastModifiedBy"`
DataChangeCreatedTime string `json:"dataChangeCreatedTime"`
DataChangeLastModifiedTime string `json:"dataChangeLastModifiedTime"`
}

111
transform/migrate.go Normal file
View File

@ -0,0 +1,111 @@
// Package transform ...
//
// Description : 数据迁移
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-11-30 3:57 下午
package transform
import (
"errors"
"fmt"
"git.zhangdeman.cn/zhangdeman/center-config/define/form"
"git.zhangdeman.cn/zhangdeman/center-config/define/model"
"git.zhangdeman.cn/zhangdeman/center-config/manager"
)
// MigrateOption 迁移的配置选项
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 5:41 下午 2021/11/30
type MigrateOption struct {
Force bool // 强制迁移
}
// SetMigrateOption 设置迁移选项
type SetMigrateOption func(mo *MigrateOption)
// WithOptionForce 配置是否强制迁移
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 5:43 下午 2021/11/30
func WithOptionForce(force bool) SetMigrateOption {
return func(mo *MigrateOption) {
mo.Force = force
}
}
// Migrate 数据迁移
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:58 下午 2021/11/30
func Migrate(dataDriver ITransform, optionList ...SetMigrateOption) error {
if nil == dataDriver {
return errors.New("data driver is nil")
}
namespace := dataDriver.GetNamespace()
if len(namespace) == 0 {
return errors.New("数据驱动器中, 未设置namespace")
}
mo := &MigrateOption{}
for _, o := range optionList {
o(mo)
}
var (
sourceData map[string]string
err error
namespaceDetail *model.Namespace
)
if sourceData, err = dataDriver.GetSourceData(); nil != err {
return err
}
if namespaceDetail, err = manager.Namespace.GetNamespaceDetail(0, namespace); nil == err && nil != namespaceDetail {
if !mo.Force {
// 非强制迁移, 报错
return fmt.Errorf("当前命名空间 %s(%v) 已存在, 迁移存在风险, 若要强制迁移, 请使用force=true", namespace, namespaceDetail.ID)
}
// 强制迁移, 需要查询已有的key, 用于判断后续是
}
// 创建命名空间
if err = manager.Namespace.Create(&form.CreateNamespace{
Namespace: namespace,
Name: "apollo迁移-" + namespace,
Description: "从apollo迁移过来的配置",
CreateUserID: "migrate-script",
}); nil != err {
return errors.New("创建命名空间失败 : " + err.Error())
}
// 激活命名空间
if err = manager.Namespace.Active(&form.ActiveNamespace{
NamespaceID: 0,
Namespace: namespace,
UpdateUserID: "system-script",
}); nil != err {
return errors.New("激活命名空间失败 : " + err.Error())
}
// 迁移配置
for key, value := range sourceData {
if err = manager.Config.Create(&form.CreateOrUpdateConfig{
NamespaceID: 0,
Namespace: namespace,
Key: key,
Value: value,
OperateUserID: "system-script",
Description: fmt.Sprintf("从apollo-%s-%s迁移过来的配置", namespace, key),
}, namespaceDetail); nil != err {
dataDriver.MigrateKeyFailCallback(namespace, key, value, err)
}
}
return nil
}