Skip to content

Commit

Permalink
fix: dop ci generate pipeline cms ns by workspace's main-branch (#2797)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfwn committed Nov 3, 2021
1 parent 901e1e7 commit 1b6ede0
Show file tree
Hide file tree
Showing 4 changed files with 417 additions and 55 deletions.
123 changes: 69 additions & 54 deletions modules/dop/services/pipeline/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,8 @@ func (p *Pipeline) ConvertPipelineToV2(pv1 *apistructs.PipelineCreateRequest) (*
}
}

// make config namespace
ns, err := p.makeNamespace(pv1.AppID, pv1.Branch, validBranch.Workspace)
if err != nil {
return nil, apierrors.ErrMakeConfigNamespace.InternalError(err)
}
// make config namespaces
ns := p.makeCmsNamespaces(pv1.AppID, validBranch.Workspace)
ns = append(ns, utils.MakeUserOrgPipelineCmsNs(pv1.UserID, app.OrgID))
pv2.ConfigManageNamespaces = append(pv2.ConfigManageNamespaces, ns...)

Expand Down Expand Up @@ -395,64 +392,82 @@ func (p *Pipeline) ConvertPipelineToV2(pv1 *apistructs.PipelineCreateRequest) (*
return pv2, nil
}

func (p *Pipeline) makeNamespace(appID uint64, branch string, workspace string) ([]string, error) {
ns, err := p.generatorPipelineNS(appID, branch, workspace)
if err != nil {
return nil, err
}
// workspace <-> main-branch mapping:
// DEV -> feature
// TEST -> develop
// STAGING -> release
// PROD -> master
var nsWorkspaceMainBranchMapping = map[string]string{
gitflowutil.DevWorkspace: gitflowutil.FEATURE_WITHOUT_SLASH,
gitflowutil.TestWorkspace: gitflowutil.DEVELOP,
gitflowutil.StagingWorkspace: gitflowutil.RELEASE_WITHOUT_SLASH,
gitflowutil.ProdWorkspace: gitflowutil.MASTER,
}

ws, err := generatorWorkspaceNS(appID, workspace)
if err != nil {
return nil, err
func getWorkspaceMainBranch(workspace string) string {
workspace = strutil.ToUpper(workspace)
if branch, ok := nsWorkspaceMainBranchMapping[workspace]; ok {
return branch
}
ns = append(ns, ws...)

return ns, err
return ""
}

func generatorWorkspaceNS(appID uint64, workspace string) ([]string, error) {
wsList := []string{
fmt.Sprintf("app-%d-%s", appID, strings.ToLower(string(apistructs.DefaultWorkspace))),
}
wsList = append(wsList, fmt.Sprintf("app-%d-%s", appID, strings.ToLower(workspace)))
func (p *Pipeline) makeCmsNamespaces(appID uint64, workspace string) []string {
var results []string

// branch-workspace level cms ns
results = append(results, makeBranchWorkspaceLevelCmsNs(appID, workspace)...)

// app-workspace level cms ns
results = append(results, makeAppWorkspaceLevelCmsNs(appID, workspace)...)

return wsList, nil
return results
}

func (p *Pipeline) generatorPipelineNS(appID uint64, branch string, workspace string) ([]string, error) {
var cmNamespaces []string
// 创建 default namespace
cmNamespaces = append(cmNamespaces, fmt.Sprintf("%s-%d-default", cms.PipelineAppConfigNameSpacePrefix, appID))
// makeBranchWorkspaceLevelCmsNs generate pipeline branch level cms namespaces
// for history reason, there is a mapping between workspace and branch, see nsWorkspaceMainBranchMapping
// history reason: we use branch-level namespace, but now we use workspace-level namespace, and use main-branch to represent workspace
//
// process:
// (branch) -> workspace(from project branch-rule) -> main-branch -> corresponding ns
// examples:
// master -> PROD -> master -> ${prefix}-master
// support/a -> PROD -> master -> ${prefix}-master
// release -> STAGING -> release -> ${prefix}-release
// hotfix/b -> STAGING -> release -> ${prefix}-release
// develop -> TEST -> develop -> ${prefix}-develop
// feature/c -> DEV -> feature -> ${prefix}-feature
func makeBranchWorkspaceLevelCmsNs(appID uint64, workspace string) []string {
var results []string

// branch-workspace level cms ns
// default need be added before custom
results = append(results, cms.MakeAppDefaultSecretNamespace(strutil.String(appID)))
// get main branch
mainBranch := getWorkspaceMainBranch(workspace)
if mainBranch != "" {
masterBranchNs := cms.MakeAppBranchPrefixSecretNamespaceByBranchPrefix(strutil.String(appID), mainBranch)
results = append(results, masterBranchNs)
}

return results
}

// TODO 直接使用workspace,不用映射 support hotfix
// hotfix support 兼容判断,如果有历史遗留参数,使用历史分支级配置 不用workspace
if gitflowutil.IsHotfix(branch) || gitflowutil.IsSupport(branch) {
branchPrefix, _ := gitflowutil.GetReferencePrefix(branch)
ns := fmt.Sprintf("%s-%d-%s", cms.PipelineAppConfigNameSpacePrefix, appID, branchPrefix)
configs, err := p.cms.GetCmsNsConfigs(utils.WithInternalClientContext(context.Background()),
&cmspb.CmsNsConfigsGetRequest{
Ns: ns,
PipelineSource: apistructs.PipelineSourceDice.String(),
})
if err == nil {
if len(configs.Data) > 0 {
cmNamespaces = append(cmNamespaces, ns)
}
}
} else {
workspaceConfig := map[string]string{
"PROD": "master",
"STAGING": "release",
"TEST": "develop",
"DEV": "feature",
}
// 创建 branch namespace
pipelineNs, ok := workspaceConfig[workspace]
if ok {
cmNamespaces = append(cmNamespaces, fmt.Sprintf("%s-%d-%s", cms.PipelineAppConfigNameSpacePrefix, appID, pipelineNs))
}
// makeAppWorkspaceLevelCmsNs generate app level cms namespaces, such as publisher, etc.
func makeAppWorkspaceLevelCmsNs(appID uint64, workspace string) []string {
// default need be added before custom
return []string{
makeAppDefaultCmsNs(appID),
makeAppWorkspaceCmsNs(appID, workspace),
}
return cmNamespaces, nil
}

func makeAppDefaultCmsNs(appID uint64) string {
return makeAppWorkspaceCmsNs(appID, "default")
}

func makeAppWorkspaceCmsNs(appID uint64, workspace string) string {
return fmt.Sprintf("app-%d-%s", appID, strutil.ToLower(workspace))
}

// GenerateV1UniquePipelineYmlName 为 v1 pipeline 返回 pipelineYmlName,该 name 在 source 下唯一
Expand Down
199 changes: 199 additions & 0 deletions modules/dop/services/pipeline/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import (
"github.com/stretchr/testify/assert"

"github.com/erda-project/erda/apistructs"
"github.com/erda-project/erda/modules/pipeline/providers/cms"
"github.com/erda-project/erda/modules/pipeline/providers/definition_client/deftype"
"github.com/erda-project/erda/modules/pkg/gitflowutil"
)

func TestGetBranch(t *testing.T) {
Expand Down Expand Up @@ -162,3 +164,200 @@ func TestPipeline_reportPipelineDefinition(t *testing.T) {
})
}
}

func Test_getWorkspaceMainBranch(t *testing.T) {
type args struct {
workspace string
}
tests := []struct {
name string
args args
want string
}{
{
name: "invalid workspace",
args: args{
workspace: "xxx",
},
want: "",
},
{
name: "dev",
args: args{
workspace: "dev",
},
want: "feature",
},
{
name: "Dev",
args: args{
workspace: "Dev",
},
want: "feature",
},
{
name: "test",
args: args{
workspace: "test",
},
want: "develop",
},
{
name: "staging",
args: args{
workspace: "staging",
},
want: "release",
},
{
name: "prOD",
args: args{
workspace: "prOD",
},
want: "master",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := getWorkspaceMainBranch(tt.args.workspace); got != tt.want {
t.Errorf("getWorkspaceMainBranch() = %v, want %v", got, tt.want)
}
})
}
}

func Test_makeAppDefaultCmsNs(t *testing.T) {
type args struct {
appID uint64
}
tests := []struct {
name string
args args
want string
}{
{
name: "app 1",
args: args{
appID: 1,
},
want: "app-1-default",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := makeAppDefaultCmsNs(tt.args.appID); got != tt.want {
t.Errorf("makeAppDefaultCmsNs() = %v, want %v", got, tt.want)
}
})
}
}

func Test_makeAppWorkspaceCmsNs(t *testing.T) {
type args struct {
appID uint64
workspace string
}
tests := []struct {
name string
args args
want string
}{
{
name: "app 1 dev",
args: args{
appID: 1,
workspace: gitflowutil.DevWorkspace,
},
want: "app-1-dev",
},
{
name: "app 1 prod",
args: args{
appID: 1,
workspace: gitflowutil.ProdWorkspace,
},
want: "app-1-prod",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := makeAppWorkspaceCmsNs(tt.args.appID, tt.args.workspace); got != tt.want {
t.Errorf("makeAppWorkspaceCmsNs() = %v, want %v", got, tt.want)
}
})
}
}

func Test_makeBranchWorkspaceLevelCmsNs(t *testing.T) {
type args struct {
appID uint64
workspace string
}
tests := []struct {
name string
args args
want []string
}{
{
name: "invalid workspace",
args: args{
appID: 1,
workspace: "xxx",
},
want: []string{cms.MakeAppDefaultSecretNamespace("1")},
},
{
name: "staging",
args: args{
appID: 1,
workspace: "STAGING",
},
want: []string{cms.MakeAppDefaultSecretNamespace("1"), cms.MakeAppBranchPrefixSecretNamespaceByBranchPrefix("1", "release")},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := makeBranchWorkspaceLevelCmsNs(tt.args.appID, tt.args.workspace); !reflect.DeepEqual(got, tt.want) {
t.Errorf("makeBranchWorkspaceLevelCmsNs() = %v, want %v", got, tt.want)
}
})
}
}

func Test_makeAppWorkspaceLevelCmsNs(t *testing.T) {
type args struct {
appID uint64
workspace string
}
tests := []struct {
name string
args args
want []string
}{
{
name: "invalid workspace",
args: args{
appID: 1,
workspace: "xxx",
},
want: []string{"app-1-default", "app-1-xxx"},
},
{
name: "staging",
args: args{
appID: 1,
workspace: "staging",
},
want: []string{"app-1-default", "app-1-staging"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := makeAppWorkspaceLevelCmsNs(tt.args.appID, tt.args.workspace); !reflect.DeepEqual(got, tt.want) {
t.Errorf("makeAppWorkspaceLevelCmsNs() = %v, want %v", got, tt.want)
}
})
}
}


6 changes: 5 additions & 1 deletion modules/pipeline/providers/cms/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@ func MakeAppBranchPrefixSecretNamespace(appID, branch string) (string, error) {
if err != nil {
return "", err
}
return fmt.Sprintf("%s-%s-%s", PipelineAppConfigNameSpacePrefix, appID, branchPrefix), nil
return MakeAppBranchPrefixSecretNamespaceByBranchPrefix(appID, branchPrefix), nil
}

func MakeAppBranchPrefixSecretNamespaceByBranchPrefix(appID, branchPrefix string) string {
return fmt.Sprintf("%s-%s-%s", PipelineAppConfigNameSpacePrefix, appID, branchPrefix)
}
Loading

0 comments on commit 1b6ede0

Please sign in to comment.