Skip to content

Commit 3ec956b

Browse files
committed
Add Priority and Urgency filters for PD plugin.
1 parent 17837c0 commit 3ec956b

File tree

12 files changed

+365
-4
lines changed

12 files changed

+365
-4
lines changed

backend/plugins/pagerduty/api/blueprint_v200.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ func makePipelinePlanV200(
6464
}
6565

6666
scope, scopeConfig := scopeDetail.Scope, scopeDetail.ScopeConfig
67-
// construct task options for circleci
67+
// construct task options for pagerduty
6868
task, err := api.MakePipelinePlanTask(
6969
"pagerduty",
7070
subtaskMetas,
7171
scopeConfig.Entities,
7272
tasks.PagerDutyOptions{
73-
ConnectionId: connection.ID,
74-
ServiceId: scope.Id,
73+
ConnectionId: connection.ID,
74+
ServiceId: scope.Id,
75+
ScopeConfigId: scopeConfig.ID,
7576
},
7677
)
7778
if err != nil {
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package api
19+
20+
import (
21+
"github.com/apache/incubator-devlake/core/errors"
22+
"github.com/apache/incubator-devlake/core/plugin"
23+
)
24+
25+
// CreateScopeConfig create scope config for PagerDuty
26+
// @Summary create scope config for PagerDuty
27+
// @Description create scope config for PagerDuty
28+
// @Tags plugins/pagerduty
29+
// @Accept application/json
30+
// @Param connectionId path int true "connectionId"
31+
// @Param scopeConfig body models.PagerdutyScopeConfig true "scope config"
32+
// @Success 200 {object} models.PagerdutyScopeConfig
33+
// @Failure 400 {object} shared.ApiBody "Bad Request"
34+
// @Failure 500 {object} shared.ApiBody "Internal Error"
35+
// @Router /plugins/pagerduty/connections/{connectionId}/scope-configs [POST]
36+
func CreateScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
37+
return dsHelper.ScopeConfigApi.Post(input)
38+
}
39+
40+
// PatchScopeConfig update scope config for PagerDuty
41+
// @Summary update scope config for PagerDuty
42+
// @Description update scope config for PagerDuty
43+
// @Tags plugins/pagerduty
44+
// @Accept application/json
45+
// @Param id path int true "id"
46+
// @Param connectionId path int true "connectionId"
47+
// @Param scopeConfig body models.PagerdutyScopeConfig true "scope config"
48+
// @Success 200 {object} models.PagerdutyScopeConfig
49+
// @Failure 400 {object} shared.ApiBody "Bad Request"
50+
// @Failure 500 {object} shared.ApiBody "Internal Error"
51+
// @Router /plugins/pagerduty/connections/{connectionId}/scope-configs/{id} [PATCH]
52+
func PatchScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
53+
return dsHelper.ScopeConfigApi.Patch(input)
54+
}
55+
56+
// GetScopeConfig return one scope config
57+
// @Summary return one scope config
58+
// @Description return one scope config
59+
// @Tags plugins/pagerduty
60+
// @Param id path int true "id"
61+
// @Param connectionId path int true "connectionId"
62+
// @Success 200 {object} models.PagerdutyScopeConfig
63+
// @Failure 400 {object} shared.ApiBody "Bad Request"
64+
// @Failure 500 {object} shared.ApiBody "Internal Error"
65+
// @Router /plugins/pagerduty/connections/{connectionId}/scope-configs/{id} [GET]
66+
func GetScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
67+
return dsHelper.ScopeConfigApi.GetDetail(input)
68+
}
69+
70+
// GetScopeConfigList return all scope configs
71+
// @Summary return all scope configs
72+
// @Description return all scope configs
73+
// @Tags plugins/pagerduty
74+
// @Param connectionId path int true "connectionId"
75+
// @Param pageSize query int false "page size, default 50"
76+
// @Param page query int false "page size, default 1"
77+
// @Success 200 {object} []models.PagerdutyScopeConfig
78+
// @Failure 400 {object} shared.ApiBody "Bad Request"
79+
// @Failure 500 {object} shared.ApiBody "Internal Error"
80+
// @Router /plugins/pagerduty/connections/{connectionId}/scope-configs [GET]
81+
func GetScopeConfigList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
82+
return dsHelper.ScopeConfigApi.GetAll(input)
83+
}
84+
85+
// GetServicesByScopeConfig return services details related by scope config
86+
// @Summary return all related services
87+
// @Description return all related services
88+
// @Tags plugins/pagerduty
89+
// @Param id path int true "id"
90+
// @Param scopeConfigId path int true "scopeConfigId"
91+
// @Success 200 {object} models.ServiceScopeOutput
92+
// @Failure 400 {object} shared.ApiBody "Bad Request"
93+
// @Failure 500 {object} shared.ApiBody "Internal Error"
94+
// @Router /plugins/pagerduty/scope-config/{scopeConfigId}/projects [GET]
95+
func GetServicesByScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
96+
return dsHelper.ScopeConfigApi.GetProjectsByScopeConfig(input)
97+
}
98+
99+
// DeleteScopeConfig delete a scope config
100+
// @Summary delete a scope config
101+
// @Description delete a scope config
102+
// @Tags plugins/pagerduty
103+
// @Param id path int true "id"
104+
// @Param connectionId path int true "connectionId"
105+
// @Success 200
106+
// @Failure 400 {object} shared.ApiBody "Bad Request"
107+
// @Failure 500 {object} shared.ApiBody "Internal Error"
108+
// @Router /plugins/pagerduty/connections/{connectionId}/scope-configs/{id} [DELETE]
109+
func DeleteScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
110+
return dsHelper.ScopeConfigApi.Delete(input)
111+
}

backend/plugins/pagerduty/impl/impl.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (p PagerDuty) Scope() plugin.ToolLayerScope {
7070
}
7171

7272
func (p PagerDuty) ScopeConfig() dal.Tabler {
73-
return nil
73+
return &models.PagerdutyScopeConfig{}
7474
}
7575

7676
func (p PagerDuty) SubTaskMetas() []plugin.SubTaskMeta {
@@ -109,6 +109,21 @@ func (p PagerDuty) PrepareTaskData(taskCtx plugin.TaskContext, options map[strin
109109
return nil, errors.Default.Wrap(err, "unable to get Pagerduty connection by the given connection ID")
110110
}
111111

112+
// Load ScopeConfig from database if only ScopeConfigId is provided
113+
if op.ScopeConfig == nil && op.ScopeConfigId != 0 {
114+
var scopeConfig models.PagerdutyScopeConfig
115+
db := taskCtx.GetDal()
116+
err = db.First(&scopeConfig, dal.Where("id = ?", op.ScopeConfigId))
117+
if err != nil && !db.IsErrorNotFound(err) {
118+
return nil, errors.BadInput.Wrap(err, "fail to get scopeConfig")
119+
}
120+
op.ScopeConfig = &scopeConfig
121+
}
122+
// Initialize empty ScopeConfig if none provided
123+
if op.ScopeConfig == nil {
124+
op.ScopeConfig = new(models.PagerdutyScopeConfig)
125+
}
126+
112127
client, err := helper.NewApiClientFromConnection(taskCtx.GetContext(), taskCtx, connection)
113128

114129
if err != nil {
@@ -168,6 +183,18 @@ func (p PagerDuty) ApiResources() map[string]map[string]plugin.ApiResourceHandle
168183
"connections/:connectionId/scopes/:scopeId/latest-sync-state": {
169184
"GET": api.GetScopeLatestSyncState,
170185
},
186+
"connections/:connectionId/scope-configs": {
187+
"POST": api.CreateScopeConfig,
188+
"GET": api.GetScopeConfigList,
189+
},
190+
"connections/:connectionId/scope-configs/:scopeConfigId": {
191+
"PATCH": api.PatchScopeConfig,
192+
"GET": api.GetScopeConfig,
193+
"DELETE": api.DeleteScopeConfig,
194+
},
195+
"scope-config/:scopeConfigId/projects": {
196+
"GET": api.GetServicesByScopeConfig,
197+
},
171198
}
172199
}
173200

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package migrationscripts
19+
20+
import (
21+
"github.com/apache/incubator-devlake/core/context"
22+
"github.com/apache/incubator-devlake/core/errors"
23+
"github.com/apache/incubator-devlake/core/plugin"
24+
)
25+
26+
var _ plugin.MigrationScript = (*addFilterFieldsToPagerDutyScopeConfig20251003)(nil)
27+
28+
type PagerDutyScopeConfig20251003 struct {
29+
PriorityFilter []string `mapstructure:"priorityFilter" json:"priorityFilter" gorm:"type:text;serializer:json"`
30+
UrgencyFilter []string `mapstructure:"urgencyFilter" json:"urgencyFilter" gorm:"type:text;serializer:json"`
31+
}
32+
33+
func (o PagerDutyScopeConfig20251003) TableName() string {
34+
return "_tool_pagerduty_scope_configs"
35+
}
36+
37+
type addFilterFieldsToPagerDutyScopeConfig20251003 struct{}
38+
39+
func (script *addFilterFieldsToPagerDutyScopeConfig20251003) Up(basicRes context.BasicRes) errors.Error {
40+
return basicRes.GetDal().AutoMigrate(&PagerDutyScopeConfig20251003{})
41+
}
42+
43+
func (*addFilterFieldsToPagerDutyScopeConfig20251003) Version() uint64 {
44+
return 20251003000000
45+
}
46+
47+
func (script *addFilterFieldsToPagerDutyScopeConfig20251003) Name() string {
48+
return "add priority_filter and urgency_filter fields to table _tool_pagerduty_scope_configs"
49+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package migrationscripts
19+
20+
import (
21+
"github.com/apache/incubator-devlake/core/context"
22+
"github.com/apache/incubator-devlake/core/errors"
23+
"github.com/apache/incubator-devlake/core/plugin"
24+
)
25+
26+
var _ plugin.MigrationScript = (*addScopeConfigIdToServices20251003)(nil)
27+
28+
type service20251003 struct {
29+
ScopeConfigId uint64 `gorm:"column:scope_config_id"`
30+
}
31+
32+
func (service20251003) TableName() string {
33+
return "_tool_pagerduty_services"
34+
}
35+
36+
type addScopeConfigIdToServices20251003 struct{}
37+
38+
func (script *addScopeConfigIdToServices20251003) Up(basicRes context.BasicRes) errors.Error {
39+
return basicRes.GetDal().AutoMigrate(&service20251003{})
40+
}
41+
42+
func (*addScopeConfigIdToServices20251003) Version() uint64 {
43+
return 20251003000001
44+
}
45+
46+
func (script *addScopeConfigIdToServices20251003) Name() string {
47+
return "add scope_config_id to _tool_pagerduty_services"
48+
}

backend/plugins/pagerduty/models/migrationscripts/register.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,7 @@ func All() []plugin.MigrationScript {
3434
new(addIncidentPriority),
3535
new(addPagerDutyScopeConfig20231214),
3636
new(addPagerDutyScopeConfig20240614),
37+
new(addFilterFieldsToPagerDutyScopeConfig20251003),
38+
new(addScopeConfigIdToServices20251003),
3739
}
3840
}

backend/plugins/pagerduty/models/scope_config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323

2424
type PagerdutyScopeConfig struct {
2525
common.ScopeConfig `mapstructure:",squash" json:",inline" gorm:"embedded"`
26+
PriorityFilter []string `mapstructure:"priorityFilter" json:"priorityFilter" gorm:"type:text;serializer:json"`
27+
UrgencyFilter []string `mapstructure:"urgencyFilter" json:"urgencyFilter" gorm:"type:text;serializer:json"`
2628
}
2729

2830
func (p PagerdutyScopeConfig) TableName() string {

backend/plugins/pagerduty/tasks/incidents_collector.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ func CollectIncidents(taskCtx plugin.SubTaskContext) errors.Error {
9999
query.Set("limit", fmt.Sprintf("%d", reqData.Pager.Size))
100100
query.Set("offset", fmt.Sprintf("%d", reqData.Pager.Skip))
101101
query.Set("total", "true")
102+
103+
// Apply Priority filters if configured
104+
if data.Options.ScopeConfig != nil && len(data.Options.ScopeConfig.PriorityFilter) > 0 {
105+
for _, priority := range data.Options.ScopeConfig.PriorityFilter {
106+
query.Add("priorities[]", priority)
107+
}
108+
}
109+
110+
// Apply Urgency filters if configured
111+
if data.Options.ScopeConfig != nil && len(data.Options.ScopeConfig.UrgencyFilter) > 0 {
112+
for _, urgency := range data.Options.ScopeConfig.UrgencyFilter {
113+
query.Add("urgencies[]", urgency)
114+
}
115+
}
116+
102117
return query, nil
103118
},
104119
ResponseParser: func(res *http.Response) ([]json.RawMessage, errors.Error) {

config-ui/src/plugins/components/scope-config-form/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { AzureTransformation } from '@/plugins/register/azure';
3434
import { TapdTransformation } from '@/plugins/register/tapd';
3535
import { BambooTransformation } from '@/plugins/register/bamboo';
3636
import { CircleCITransformation } from '@/plugins/register/circleci';
37+
import { PagerDutyTransformation } from '@/plugins/register/pagerduty';
3738
import { DOC_URL } from '@/release';
3839
import { operator } from '@/utils';
3940

@@ -285,6 +286,13 @@ export const ScopeConfigForm = ({
285286
setTransformation={setTransformation}
286287
/>
287288
)}
289+
290+
{plugin === 'pagerduty' && (
291+
<PagerDutyTransformation
292+
transformation={transformation}
293+
setTransformation={setTransformation}
294+
/>
295+
)}
288296
</Form>
289297
</Card>
290298
<Flex justify="flex-end" gap="small">

config-ui/src/plugins/register/pagerduty/config.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,11 @@ export const PagerDutyConfig: IPluginConfig = {
5555
dataScope: {
5656
title: 'Services',
5757
},
58+
scopeConfig: {
59+
entities: ['TICKET'],
60+
transformation: {
61+
priorityFilter: [],
62+
urgencyFilter: [],
63+
},
64+
},
5865
};

0 commit comments

Comments
 (0)