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

feat: check pipelines' tokens before executing/creating pipeline (#8055) #8069

Merged
merged 17 commits into from
Sep 30, 2024
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
9 changes: 9 additions & 0 deletions backend/core/models/blueprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,12 @@ type SyncPolicy struct {
TimeAfter *time.Time `json:"timeAfter"`
TriggerSyncPolicy
}

type ConnectionTokenCheckResult struct {
PluginName string `json:"pluginName" mapstructure:"pluginName"`
ConnectionID uint64 `json:"connectionId" mapstructure:"connectionId"`
Success bool `json:"success" mapstructure:"success"`
Message string `json:"message" mapstructure:"message"`
}

type ApiBlueprintConnectionTokenCheck []ConnectionTokenCheckResult
4 changes: 4 additions & 0 deletions backend/core/plugin/plugin_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ type PluginApi interface {
ApiResources() map[string]map[string]ApiResourceHandler
}

type PluginTestConnectionAPI interface {
TestConnection(id uint64) errors.Error
}

const wrapResponseError = "WRAP_RESPONSE_ERROR"

func WrapTestConnectionErrResp(basicRes context.BasicRes, err errors.Error) errors.Error {
Expand Down
10 changes: 10 additions & 0 deletions backend/core/plugin/plugin_blueprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ type ProjectMapper interface {
MapProject(projectName string, scopes []Scope) (models.PipelinePlan, errors.Error)
}

type ProjectTokenCheckerConnection struct {
PluginName string
ConnectionId uint64
}

// ProjectTokenChecker is implemented by the plugin org, which generate a task tp check all connection's tokens
type ProjectTokenChecker interface {
MakePipeline(skipCollectors bool, projectName string, scopes []ProjectTokenCheckerConnection) (models.PipelinePlan, errors.Error)
}

// CompositeDataSourcePluginBlueprintV200 is for unit test
type CompositeDataSourcePluginBlueprintV200 interface {
PluginMeta
Expand Down
10 changes: 10 additions & 0 deletions backend/helpers/pluginhelper/api/misc_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ limitations under the License.
package api

import (
"fmt"
"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/models"
"github.com/apache/incubator-devlake/core/plugin"
)

// CallDB wraps DB calls with this signature, and handles the case if the struct is wrapped in a models.DynamicTabler.
Expand All @@ -31,3 +33,11 @@ func CallDB(f func(any, ...dal.Clause) errors.Error, x any, clauses ...dal.Claus
}
return f(x, clauses...)
}

func GenerateTestingConnectionApiResourceInput(connectionID uint64) *plugin.ApiResourceInput {
return &plugin.ApiResourceInput{
Params: map[string]string{
"connectionId": fmt.Sprintf("%d", connectionID),
},
}
}
5 changes: 5 additions & 0 deletions backend/plugins/ae/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ func (p AE) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p AE) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p AE) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/azuredevops_go/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ func (p Azuredevops) ApiResources() map[string]map[string]plugin.ApiResourceHand
}
}

func (p Azuredevops) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Azuredevops) MakeDataSourcePipelinePlanV200(
connectionId uint64,
scopes []*coreModels.BlueprintScope,
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/bamboo/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ func (p Bamboo) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Bamboo) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Bamboo) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/bitbucket/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ func (p Bitbucket) MakeDataSourcePipelinePlanV200(
return api.MakeDataSourcePipelinePlanV200(p.SubTaskMetas(), connectionId, scopes, skipCollectors)
}

func (p Bitbucket) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Bitbucket) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/bitbucket_server/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ func (p BitbucketServer) MakeDataSourcePipelinePlanV200(
return api.MakeDataSourcePipelinePlanV200(p.SubTaskMetas(), connectionId, scopes, skipCollectors)
}

func (p BitbucketServer) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p BitbucketServer) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"connections/:connectionId/test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/circleci/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ func (p Circleci) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Circleci) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Circleci) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
4 changes: 4 additions & 0 deletions backend/plugins/customize/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,7 @@ func (p Customize) ApiResources() map[string]map[string]plugin.ApiResourceHandle
},
}
}

func (p Customize) TestConnection(id uint64) errors.Error {
return nil
}
4 changes: 4 additions & 0 deletions backend/plugins/dbt/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,7 @@ func (p Dbt) RootPkgPath() string {
func (p Dbt) Name() string {
return "dbt"
}

func (p Dbt) TestConnection(id uint64) errors.Error {
return nil
}
5 changes: 4 additions & 1 deletion backend/plugins/dora/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package impl

import (
"encoding/json"

"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
coreModels "github.com/apache/incubator-devlake/core/models"
Expand Down Expand Up @@ -168,3 +167,7 @@ func (p Dora) MakeMetricPluginPipelinePlanV200(projectName string, options json.
}
return plan, nil
}

func (p Dora) TestConnection(id uint64) errors.Error {
return nil
}
5 changes: 5 additions & 0 deletions backend/plugins/feishu/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ func (p Feishu) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Feishu) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Feishu) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/gitee/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ func (p Gitee) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Gitee) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Gitee) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
4 changes: 4 additions & 0 deletions backend/plugins/gitextractor/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,7 @@ func (p GitExtractor) Close(taskCtx plugin.TaskContext) errors.Error {
func (p GitExtractor) RootPkgPath() string {
return "github.com/apache/incubator-devlake/plugins/gitextractor"
}

func (p GitExtractor) TestConnection(id uint64) errors.Error {
return nil
}
42 changes: 42 additions & 0 deletions backend/plugins/github/api/shared.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 api

import (
"context"
"fmt"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
)

func TestExistingConnectionForTokenCheck(input *plugin.ApiResourceInput) errors.Error {
connection, err := dsHelper.ConnApi.GetMergedConnection(input)
if err != nil {
return err
}
testConnectionResult, testConnectionErr := testExistingConnection(context.TODO(), connection.GithubConn)
if testConnectionErr != nil {
return testConnectionErr
}
for _, token := range testConnectionResult.Tokens {
if !token.Success {
return errors.Default.New(fmt.Sprintf("token %s failed with msg: %s", token.Token, token.Message))
}
}
return nil
}
4 changes: 4 additions & 0 deletions backend/plugins/github/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ func (p Github) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Github) TestConnection(id uint64) errors.Error {
return api.TestExistingConnectionForTokenCheck(helper.GenerateTestingConnectionApiResourceInput(id))
}

func (p Github) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/gitlab/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ func (p Gitlab) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Gitlab) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Gitlab) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
4 changes: 4 additions & 0 deletions backend/plugins/icla/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ func (p Icla) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return nil
}

func (p Icla) TestConnection(id uint64) errors.Error {
return nil
}

func (p Icla) Close(taskCtx plugin.TaskContext) errors.Error {
data, ok := taskCtx.GetData().(*tasks.IclaTaskData)
if !ok {
Expand Down
5 changes: 4 additions & 1 deletion backend/plugins/issue_trace/impl/enricher.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package impl

import (
"encoding/json"

"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
Expand Down Expand Up @@ -151,6 +150,10 @@ func (p IssueTrace) GetTablesInfo() []dal.Tabler {
}
}

func (p IssueTrace) TestConnection(id uint64) errors.Error {
return nil
}

func (p IssueTrace) MakeMetricPluginPipelinePlanV200(projectName string, options json.RawMessage) (coreModels.PipelinePlan, errors.Error) {
op := &tasks.Options{}
if options != nil && string(options) != "\"\"" {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/jenkins/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ func (p Jenkins) MakeDataSourcePipelinePlanV200(
return api.MakeDataSourcePipelinePlanV200(p.SubTaskMetas(), connectionId, scopes, skipCollectors)
}

func (p Jenkins) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Jenkins) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
5 changes: 5 additions & 0 deletions backend/plugins/jira/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ func (p Jira) MigrationScripts() []plugin.MigrationScript {
return migrationscripts.All()
}

func (p Jira) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Jira) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
4 changes: 4 additions & 0 deletions backend/plugins/linker/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,7 @@ func (p Linker) MakeMetricPluginPipelinePlanV200(projectName string, options jso
}
return plan, nil
}

func (p Linker) TestConnection(id uint64) errors.Error {
return nil
}
5 changes: 5 additions & 0 deletions backend/plugins/opsgenie/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ func (p Opsgenie) Close(taskCtx plugin.TaskContext) errors.Error {
return nil
}

func (p Opsgenie) TestConnection(id uint64) errors.Error {
_, err := api.TestExistingConnection(helper.GenerateTestingConnectionApiResourceInput(id))
return err
}

func (p Opsgenie) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
return map[string]map[string]plugin.ApiResourceHandler{
"test": {
Expand Down
22 changes: 22 additions & 0 deletions backend/plugins/org/impl/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,33 @@ func (p Org) Name() string {

func (p Org) SubTaskMetas() []plugin.SubTaskMeta {
return []plugin.SubTaskMeta{
tasks.TaskCheckTokenMeta,
tasks.ConnectUserAccountsExactMeta,
tasks.SetProjectMappingMeta,
}
}

func (p Org) MakePipeline(skipCollectors bool, projectName string, connections []plugin.ProjectTokenCheckerConnection) (coreModels.PipelinePlan, errors.Error) {
var plan coreModels.PipelinePlan
var stage coreModels.PipelineStage

// construct task options for Org
options := make(map[string]interface{})
if !skipCollectors {
options["projectConnections"] = connections
}

stage = append(stage, &coreModels.PipelineTask{
Plugin: p.Name(),
Subtasks: []string{
tasks.TaskCheckTokenMeta.Name,
},
Options: options,
})
plan = append(plan, stage)
return plan, nil
}

func (p Org) MapProject(projectName string, scopes []plugin.Scope) (coreModels.PipelinePlan, errors.Error) {
var plan coreModels.PipelinePlan
var stage coreModels.PipelineStage
Expand Down
Loading
Loading