重新初始化仓库
This commit is contained in:
22
transform/ITransform.go
Normal file
22
transform/ITransform.go
Normal 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
3
transform/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# 转换程序
|
||||
|
||||
作用 : 将其他配置中心的配置迁移至本服务
|
116
transform/apollo_migrate.go
Normal file
116
transform/apollo_migrate.go
Normal 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
29
transform/define.go
Normal 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
111
transform/migrate.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user