Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dop ci generate pipeline cms ns by workspace's main-branch #2797

Merged
merged 1 commit into from
Nov 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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