diff --git a/modules/dop/endpoints/endpoints.go b/modules/dop/endpoints/endpoints.go index 051fef6be34..82c06bc3e8d 100644 --- a/modules/dop/endpoints/endpoints.go +++ b/modules/dop/endpoints/endpoints.go @@ -227,6 +227,7 @@ func (e *Endpoints) Routes() []httpserver.Endpoint { // project pipeline {Path: "/api/cicds-project", Method: http.MethodPost, Handler: e.projectPipelineCreate}, + {Path: "/api/cicds-project/actions/pipeline-detail", Method: http.MethodGet, Handler: e.projectPipelineDetail}, // cms {Path: "/api/cicds/configs", Method: http.MethodPost, Handler: e.createOrUpdateCmsNsConfigs}, diff --git a/modules/dop/endpoints/pipeline.go b/modules/dop/endpoints/pipeline.go index 56b4c16c9f3..f78df626343 100644 --- a/modules/dop/endpoints/pipeline.go +++ b/modules/dop/endpoints/pipeline.go @@ -30,8 +30,10 @@ import ( cmspb "github.com/erda-project/erda-proto-go/core/pipeline/cms/pb" "github.com/erda-project/erda/apistructs" + "github.com/erda-project/erda/bundle" "github.com/erda-project/erda/modules/dop/conf" "github.com/erda-project/erda/modules/dop/services/apierrors" + "github.com/erda-project/erda/modules/dop/services/permission" "github.com/erda-project/erda/modules/dop/services/pipeline" "github.com/erda-project/erda/modules/dop/utils" "github.com/erda-project/erda/modules/pipeline/spec" @@ -145,25 +147,25 @@ func (e *Endpoints) pipelineDetail(ctx context.Context, r *http.Request, vars ma return apierrors.ErrGetUser.InvalidParameter(err).ToResp(), nil } - // obtain pipeline information according to pipelineID - p, err := e.bdl.GetPipeline(req.PipelineID) + result, err := getPipelineDetailAndCheckPermission(e.bdl, e.permission, req, identityInfo) if err != nil { return errorresp.ErrResp(err) } - if err := e.permission.CheckRuntimeBranch(identityInfo, p.ApplicationID, p.Branch, apistructs.OperateAction); err != nil { - return errorresp.ErrResp(err) - } + return httpserver.OkResp(result) +} - result, err := e.bdl.GetPipelineV2(apistructs.PipelineDetailRequest{ - PipelineID: req.PipelineID, - SimplePipelineBaseResult: req.SimplePipelineBaseResult, +func getPipelineDetailAndCheckPermission(bdl *bundle.Bundle, permission *permission.Permission, req apistructs.CICDPipelineDetailRequest, identityInfo apistructs.IdentityInfo) (*apistructs.PipelineDetailDTO, error) { + result, err := bdl.GetPipelineV2(apistructs.PipelineDetailRequest{ + PipelineID: req.PipelineID, }) if err != nil { - return errorresp.ErrResp(err) + return nil, err } - - return httpserver.OkResp(result) + if err := permission.CheckRuntimeBranch(identityInfo, result.ApplicationID, result.Branch, apistructs.OperateAction); err != nil { + return nil, err + } + return result, nil } func (e *Endpoints) pipelineList(ctx context.Context, r *http.Request, vars map[string]string) ( diff --git a/modules/dop/endpoints/pipeline_test.go b/modules/dop/endpoints/pipeline_test.go index 19a76f02963..00b9eb5b65c 100644 --- a/modules/dop/endpoints/pipeline_test.go +++ b/modules/dop/endpoints/pipeline_test.go @@ -23,6 +23,7 @@ import ( "github.com/erda-project/erda/apistructs" "github.com/erda-project/erda/bundle" + "github.com/erda-project/erda/modules/dop/services/permission" ) func Test_shouldCheckPermission(t *testing.T) { @@ -87,3 +88,71 @@ func TestUpdateCmsNsConfigsWhenUserNotExist(t *testing.T) { e := New() assert.Equal(t, "the member is not exist", e.UpdateCmsNsConfigs("1", 1).Error()) } + +func TestEndpoints_pipelineDetail(t *testing.T) { + +} + +func Test_getPipelineDetailAndCheckPermission(t *testing.T) { + type args struct { + req apistructs.CICDPipelineDetailRequest + identityInfo apistructs.IdentityInfo + result apistructs.PipelineDetailDTO + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "test", + args: args{ + req: apistructs.CICDPipelineDetailRequest{ + PipelineID: 1, + SimplePipelineBaseResult: false, + }, + result: apistructs.PipelineDetailDTO{ + PipelineDTO: apistructs.PipelineDTO{ + ID: 1, + ApplicationID: 1, + Branch: "master", + }, + }, + identityInfo: apistructs.IdentityInfo{ + UserID: "1", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + var bdl = &bundle.Bundle{} + patch := monkey.PatchInstanceMethod(reflect.TypeOf(bdl), "GetPipelineV2", func(bdl *bundle.Bundle, req apistructs.PipelineDetailRequest) (*apistructs.PipelineDetailDTO, error) { + assert.Equal(t, req.PipelineID, tt.args.req.PipelineID) + assert.Equal(t, req.SimplePipelineBaseResult, tt.args.req.SimplePipelineBaseResult) + + return &tt.args.result, nil + }) + + defer patch.Unpatch() + + var permissionChecker = &permission.Permission{} + patch1 := monkey.PatchInstanceMethod(reflect.TypeOf(permissionChecker), "CheckRuntimeBranch", func(p *permission.Permission, identityInfo apistructs.IdentityInfo, appID uint64, branch string, action string) error { + assert.Equal(t, tt.args.identityInfo, identityInfo) + assert.Equal(t, tt.args.result.ApplicationID, appID) + assert.Equal(t, tt.args.result.Branch, branch) + return nil + }) + defer patch1.Unpatch() + + got, err := getPipelineDetailAndCheckPermission(bdl, permissionChecker, tt.args.req, tt.args.identityInfo) + if (err != nil) != tt.wantErr { + t.Errorf("getPipelineDetailAndCheckPermission() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.NotNil(t, got) + assert.Equal(t, got.ID, tt.args.result.ID) + }) + } +} diff --git a/modules/dop/endpoints/project_pipeline.go b/modules/dop/endpoints/project_pipeline.go index 6097bf99955..82d0f1ea521 100644 --- a/modules/dop/endpoints/project_pipeline.go +++ b/modules/dop/endpoints/project_pipeline.go @@ -113,3 +113,32 @@ func (e *Endpoints) projectPipelineCreate(ctx context.Context, r *http.Request, return httpserver.OkResp(resp) } + +func (e *Endpoints) projectPipelineDetail(ctx context.Context, r *http.Request, vars map[string]string) ( + httpserver.Responser, error) { + + var req apistructs.CICDPipelineDetailRequest + err := e.queryStringDecoder.Decode(&req, r.URL.Query()) + if err != nil { + return apierrors.ErrGetPipeline.InvalidParameter(err).ToResp(), nil + } + + identityInfo, err := user.GetIdentityInfo(r) + if err != nil { + return apierrors.ErrGetUser.InvalidParameter(err).ToResp(), nil + } + + if !identityInfo.IsInternalClient() { + return errorresp.ErrResp(apierrors.ErrCheckPermission.InternalError(fmt.Errorf("external users cannot call the internal interface\n"))) + } + + result, err := e.bdl.GetPipelineV2(apistructs.PipelineDetailRequest{ + PipelineID: req.PipelineID, + SimplePipelineBaseResult: req.SimplePipelineBaseResult, + }) + if err != nil { + return errorresp.ErrResp(err) + } + + return httpserver.OkResp(result) +} diff --git a/modules/dop/endpoints/project_pipeline_test.go b/modules/dop/endpoints/project_pipeline_test.go new file mode 100644 index 00000000000..938bf450979 --- /dev/null +++ b/modules/dop/endpoints/project_pipeline_test.go @@ -0,0 +1,111 @@ +// Copyright (c) 2021 Terminus, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package endpoints + +import ( + "context" + "net/http" + "net/url" + "reflect" + "testing" + + "bou.ke/monkey" + "github.com/gorilla/schema" + "github.com/stretchr/testify/assert" + + "github.com/erda-project/erda/apistructs" + "github.com/erda-project/erda/bundle" + "github.com/erda-project/erda/pkg/http/httpserver" +) + +func TestEndpoints_projectPipelineDetail(t *testing.T) { + type fields struct { + result apistructs.PipelineDetailDTO + request apistructs.PipelineDetailRequest + assertUserID uint64 + } + type args struct { + ctx context.Context + r *http.Request + vars map[string]string + } + tests := []struct { + name string + fields fields + args args + want httpserver.Responser + wantErr bool + }{ + { + name: "test", + fields: fields{ + request: apistructs.PipelineDetailRequest{ + PipelineID: 1, + SimplePipelineBaseResult: false, + }, + assertUserID: 1, + result: apistructs.PipelineDetailDTO{ + PipelineDTO: apistructs.PipelineDTO{ + ID: 1, + ApplicationID: 1, + Branch: "master", + }, + }, + }, + args: args{ + r: &http.Request{ + URL: &url.URL{ + RawQuery: "pipelineID=1&simplePipelineBaseResult=false", + }, + Header: http.Header{ + "USER-ID": []string{"1"}, + "Internal-Client": []string{"pipeline"}, + }, + }, + }, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &Endpoints{} + + queryStringDecoder := schema.NewDecoder() + queryStringDecoder.IgnoreUnknownKeys(true) + e.queryStringDecoder = queryStringDecoder + + var bdl = &bundle.Bundle{} + monkey.PatchInstanceMethod(reflect.TypeOf(bdl), "GetPipelineV2", func(d *bundle.Bundle, req apistructs.PipelineDetailRequest) (*apistructs.PipelineDetailDTO, error) { + assert.Equal(t, req.PipelineID, tt.fields.request.PipelineID) + assert.Equal(t, req.SimplePipelineBaseResult, tt.fields.request.SimplePipelineBaseResult) + + return &tt.fields.result, nil + }) + e.bdl = bdl + + got, err := e.projectPipelineDetail(tt.args.ctx, tt.args.r, tt.args.vars) + if (err != nil) != tt.wantErr { + t.Errorf("pipelineDetail() error = %v, wantErr %v", err, tt.wantErr) + return + } + + assert.NotNil(t, got) + assert.Equal(t, got.GetContent().(httpserver.Resp).Data.(*apistructs.PipelineDetailDTO).ID, tt.fields.result.ID) + assert.Equal(t, got.GetContent().(httpserver.Resp).Data.(*apistructs.PipelineDetailDTO).Branch, tt.fields.result.Branch) + assert.Equal(t, got.GetContent().(httpserver.Resp).Data.(*apistructs.PipelineDetailDTO).ApplicationID, tt.fields.result.ApplicationID) + }) + } +} diff --git a/modules/openapi/api/apis/dop/adaptor_cicd_project_detail.go b/modules/openapi/api/apis/dop/adaptor_cicd_project_detail.go new file mode 100644 index 00000000000..55a90a81ec4 --- /dev/null +++ b/modules/openapi/api/apis/dop/adaptor_cicd_project_detail.go @@ -0,0 +1,32 @@ +// Copyright (c) 2021 Terminus, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dop + +import ( + "net/http" + + "github.com/erda-project/erda/modules/openapi/api/apis" +) + +var ADAPTOR_CICD_PROJECT_DETAIL = apis.ApiSpec{ + Path: "/api/cicds-project/actions/pipeline-detail", + BackendPath: "/api/cicds-project/actions/pipeline-detail", + Host: "dop.marathon.l4lb.thisdcos.directory:9527", + Scheme: "http", + Method: http.MethodGet, + IsOpenAPI: true, + CheckLogin: true, + CheckToken: true, +}