Alerting: Support Jira Integration (#100480)
This commit is contained in:
@@ -71,7 +71,7 @@ require (
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // @grafana/grafana-backend-group
|
||||
github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
|
||||
github.com/gorilla/websocket v1.5.3 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0 // @grafana/alerting-backend
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb // @grafana/alerting-backend
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 // @grafana/identity-access-team
|
||||
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
|
||||
|
||||
@@ -1511,8 +1511,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0 h1:LGH+tVzHCDrR9hsltmkP4jmNRg5IreQw5CNFbJKlnts=
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb h1:WfCsiuZXhGXIdzImQ9/Kjfn9M4e6f7z5mddcSKCRxmI=
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 h1:NTMmow+74I3Jb033xhbRgWQS7A//5TDhiM4tl7bsVP4=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7/go.mod h1:T3X4z0ejGfJOiOmZLFeKCRT/yxWJq/RtclAc/PHj/w4=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 h1:EokLC5grHwLPs4tXW8T6E8187H1e5G9AP0QQ5B60HbA=
|
||||
|
||||
@@ -91,6 +91,13 @@ func ContactPointToContactPointExport(cp definitions.ContactPoint) (notify.APIRe
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Jira {
|
||||
el, err := marshallIntegration(j, "jira", i, i.DisableResolveMessage)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Kafka {
|
||||
el, err := marshallIntegration(j, "kafka", i, i.DisableResolveMessage)
|
||||
if err != nil {
|
||||
@@ -271,6 +278,11 @@ func parseIntegration(json jsoniter.API, result *definitions.ContactPoint, recei
|
||||
if err = json.Unmarshal(data, &integration); err == nil {
|
||||
result.Googlechat = append(result.Googlechat, integration)
|
||||
}
|
||||
case "jira":
|
||||
integration := definitions.JiraIntegration{DisableResolveMessage: disable}
|
||||
if err = json.Unmarshal(data, &integration); err == nil {
|
||||
result.Jira = append(result.Jira, integration)
|
||||
}
|
||||
case "kafka":
|
||||
integration := definitions.KafkaIntegration{DisableResolveMessage: disable}
|
||||
if err = json.Unmarshal(data, &integration); err == nil {
|
||||
|
||||
@@ -62,6 +62,29 @@ type GooglechatIntegration struct {
|
||||
Message *string `json:"message,omitempty" yaml:"message,omitempty" hcl:"message"`
|
||||
}
|
||||
|
||||
type JiraIntegration struct {
|
||||
DisableResolveMessage *bool `json:"-" yaml:"-" hcl:"disable_resolve_message"`
|
||||
|
||||
URL string `yaml:"api_url,omitempty" json:"api_url,omitempty" hcl:"api_url"`
|
||||
Project string `yaml:"project,omitempty" json:"project,omitempty" hcl:"project"`
|
||||
IssueType string `yaml:"issue_type,omitempty" json:"issue_type,omitempty" hcl:"issue_type"`
|
||||
|
||||
Summary *string `yaml:"summary,omitempty" json:"summary,omitempty" hcl:"summary"`
|
||||
Description *string `yaml:"description,omitempty" json:"description,omitempty" hcl:"description"`
|
||||
Labels *[]string `yaml:"labels,omitempty" json:"labels,omitempty" hcl:"labels"`
|
||||
Priority *string `yaml:"priority,omitempty" json:"priority,omitempty" hcl:"priority"`
|
||||
ReopenTransition *string `yaml:"reopen_transition,omitempty" json:"reopen_transition,omitempty" hcl:"reopen_transition"`
|
||||
ResolveTransition *string `yaml:"resolve_transition,omitempty" json:"resolve_transition,omitempty" hcl:"resolve_transition"`
|
||||
WontFixResolution *string `yaml:"wont_fix_resolution,omitempty" json:"wont_fix_resolution,omitempty" hcl:"wont_fix_resolution"`
|
||||
ReopenDuration *string `yaml:"reopen_duration,omitempty" json:"reopen_duration,omitempty" hcl:"reopen_duration"`
|
||||
DedupKeyFieldName *string `yaml:"dedup_key_field,omitempty" json:"dedup_key_field,omitempty" hcl:"dedup_key_field"`
|
||||
Fields *map[string]any `yaml:"fields,omitempty" json:"fields,omitempty" hcl:"fields"`
|
||||
|
||||
User *Secret `yaml:"user,omitempty" json:"user,omitempty" hcl:"user"`
|
||||
Password *Secret `yaml:"password,omitempty" json:"password,omitempty" hcl:"password"`
|
||||
Token *Secret `yaml:"api_token,omitempty" json:"api_token,omitempty" hcl:"api_token"`
|
||||
}
|
||||
|
||||
type KafkaIntegration struct {
|
||||
DisableResolveMessage *bool `json:"-" yaml:"-" hcl:"disable_resolve_message"`
|
||||
|
||||
@@ -321,6 +344,7 @@ type ContactPoint struct {
|
||||
Discord []DiscordIntegration `json:"discord" yaml:"discord" hcl:"discord,block"`
|
||||
Email []EmailIntegration `json:"email" yaml:"email" hcl:"email,block"`
|
||||
Googlechat []GooglechatIntegration `json:"googlechat" yaml:"googlechat" hcl:"googlechat,block"`
|
||||
Jira []JiraIntegration `json:"jira" yaml:"jira" hcl:"jira,block"`
|
||||
Kafka []KafkaIntegration `json:"kafka" yaml:"kafka" hcl:"kafka,block"`
|
||||
Line []LineIntegration `json:"line" yaml:"line" hcl:"line,block"`
|
||||
Mqtt []MqttIntegration `json:"mqtt" yaml:"mqtt" hcl:"mqtt,block"`
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/alerting/receivers/jira"
|
||||
alertingMqtt "github.com/grafana/alerting/receivers/mqtt"
|
||||
alertingOpsgenie "github.com/grafana/alerting/receivers/opsgenie"
|
||||
alertingPagerduty "github.com/grafana/alerting/receivers/pagerduty"
|
||||
@@ -365,7 +366,7 @@ func GetAvailableNotifiers() []*NotifierPlugin {
|
||||
InputType: InputTypeText,
|
||||
PropertyName: "details",
|
||||
},
|
||||
{ //New in 11.1
|
||||
{ // New in 11.1
|
||||
Label: "URL",
|
||||
Description: "The URL to send API requests to",
|
||||
Element: ElementTypeInput,
|
||||
@@ -1708,6 +1709,154 @@ func GetAvailableNotifiers() []*NotifierPlugin {
|
||||
},
|
||||
},
|
||||
},
|
||||
{ // Since Grafana 11.6
|
||||
Type: "jira",
|
||||
Name: "Jira",
|
||||
Description: "Creates Jira issues from alerts",
|
||||
Heading: "Jira settings",
|
||||
Options: []NotifierOption{
|
||||
{
|
||||
Label: "API URL of Jira instance, including version of API",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "https://grafana.atlassian.net/rest/api/3",
|
||||
PropertyName: "api_url",
|
||||
Description: "Supported v2 or v3 APIs",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Label: "HTTP Basic Authentication - Username",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
PropertyName: "user",
|
||||
Description: "Username to use for Jira authentication.",
|
||||
Secure: true,
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "HTTP Basic Authentication - Password",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypePassword,
|
||||
PropertyName: "password",
|
||||
// Go to https://id.atlassian.com/manage-profile/security/api-tokens to obtain a token.
|
||||
Description: "Password to use for Jira authentication.",
|
||||
Secure: true,
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "Authorization Header - Personal Access Token",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypePassword,
|
||||
PropertyName: "api_token",
|
||||
// Go to https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html for how to obtain a token.
|
||||
Description: "Personal Access Token that is used as a bearer authorization header.",
|
||||
Secure: true,
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "Project Key",
|
||||
Description: "The project key associated with the relevant Jira project",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "Grafana",
|
||||
PropertyName: "project",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Label: "Issue Type",
|
||||
Description: "The type of the Jira issue (e.g., Bug, Task, Story). You can use templates to customize this field.",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "Task",
|
||||
Required: true,
|
||||
PropertyName: "issue_type",
|
||||
},
|
||||
{
|
||||
Label: "Summary",
|
||||
Description: fmt.Sprintf("The summary of the Jira issue. You can use templates to customize this field. Maximum length is %d characters.", jira.MaxSummaryLenRunes),
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: jira.DefaultSummary,
|
||||
PropertyName: "summary",
|
||||
},
|
||||
{
|
||||
Label: "Description",
|
||||
Description: fmt.Sprintf("The description of the Jira issue. You can use templates to customize this field. Maximum length is %d characters.", jira.MaxDescriptionLenRunes),
|
||||
Element: ElementTypeTextArea,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: jira.DefaultDescription,
|
||||
PropertyName: "description",
|
||||
},
|
||||
{
|
||||
Label: "Labels",
|
||||
Description: "Labels to assign to the Jira issue. You can use templates to customize this field.",
|
||||
Element: ElementStringArray,
|
||||
Placeholder: "",
|
||||
PropertyName: "labels",
|
||||
},
|
||||
{
|
||||
Label: "Priority",
|
||||
Description: "The priority of the Jira issue (e.g., High, Medium, Low). You can use templates to customize this field.",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: jira.DefaultPriority,
|
||||
PropertyName: "priority",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "Resolve Transition",
|
||||
Description: `Name of the workflow transition to resolve an issue. The target status must have the category "done". If not set, the issue will not be resolved.`,
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "",
|
||||
PropertyName: "resolve_transition",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "Reopen Transition",
|
||||
Description: `Name of the workflow transition to resolve an issue. The target status must not have the category "done". If not set, the issue will not be reopened.`,
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "",
|
||||
PropertyName: "reopen_transition",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "Reopen Duration",
|
||||
Description: "Reopen the issue when it is not older than this value in minutes. Otherwise, create a new issue.",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "10m",
|
||||
PropertyName: "reopen_duration",
|
||||
},
|
||||
{
|
||||
Label: "\"Won't fix\" Transition",
|
||||
Description: `If reopen transition is defined, ignore issues with that resolution.`,
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "",
|
||||
PropertyName: "wont_fix_resolution",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Label: "Custom field ID for deduplication",
|
||||
Description: "Id of the custom field where the deduplication key should be stored. Otherwise, it is added to labels in format 'ALERT($KEY).'",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "10000",
|
||||
ValidationRule: "^[0-9]+$",
|
||||
PropertyName: "dedup_key_field",
|
||||
},
|
||||
{
|
||||
Label: "Custom Field Data",
|
||||
Description: "Custom field data to set on the Jira issue.",
|
||||
Element: ElementTypeKeyValueMap,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "",
|
||||
PropertyName: "fields",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,20 +27,38 @@ func TestGetSecretKeysForContactPointType(t *testing.T) {
|
||||
{receiverType: "prometheus-alertmanager", expectedSecretFields: []string{"basicAuthPassword"}},
|
||||
{receiverType: "discord", expectedSecretFields: []string{"url"}},
|
||||
{receiverType: "googlechat", expectedSecretFields: []string{"url"}},
|
||||
{receiverType: "line", expectedSecretFields: []string{"token"}},
|
||||
{receiverType: "LINE", expectedSecretFields: []string{"token"}},
|
||||
{receiverType: "threema", expectedSecretFields: []string{"api_secret"}},
|
||||
{receiverType: "opsgenie", expectedSecretFields: []string{"apiKey"}},
|
||||
{receiverType: "webex", expectedSecretFields: []string{"bot_token"}},
|
||||
{receiverType: "sns", expectedSecretFields: []string{"sigv4.access_key", "sigv4.secret_key"}},
|
||||
{receiverType: "mqtt", expectedSecretFields: []string{"password", "tlsConfig.caCertificate", "tlsConfig.clientCertificate", "tlsConfig.clientKey"}},
|
||||
{receiverType: "jira", expectedSecretFields: []string{"user", "password", "api_token"}},
|
||||
}
|
||||
n := GetAvailableNotifiers()
|
||||
allTypes := make(map[string]struct{}, len(n))
|
||||
for _, plugin := range n {
|
||||
allTypes[plugin.Type] = struct{}{}
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
delete(allTypes, testCase.receiverType)
|
||||
t.Run(testCase.receiverType, func(t *testing.T) {
|
||||
got, err := GetSecretKeysForContactPointType(testCase.receiverType)
|
||||
require.NoError(t, err)
|
||||
t.Logf("got secret fields: %#v", got)
|
||||
require.ElementsMatch(t, testCase.expectedSecretFields, got)
|
||||
})
|
||||
}
|
||||
|
||||
for integrationType := range allTypes {
|
||||
t.Run(integrationType, func(t *testing.T) {
|
||||
got, err := GetSecretKeysForContactPointType(integrationType)
|
||||
require.NoError(t, err)
|
||||
require.Emptyf(t, got, "secret keys for %s should be empty", integrationType)
|
||||
})
|
||||
}
|
||||
|
||||
require.Emptyf(t, allTypes, "not all types are covered: %s", allTypes)
|
||||
}
|
||||
|
||||
func Test_getSecretFields(t *testing.T) {
|
||||
|
||||
@@ -45,6 +45,8 @@ const (
|
||||
ElementTypeSubform = "subform"
|
||||
// ElementSubformArray will render a multiple sub-forms with schema defined in SubformOptions
|
||||
ElementSubformArray = "subform_array"
|
||||
// ElementStringArray will render a set of fields to manage an array of strings.
|
||||
ElementStringArray = "string_array"
|
||||
)
|
||||
|
||||
// InputType is the type of input that can be rendered in the frontend.
|
||||
|
||||
@@ -423,6 +423,9 @@ func TestRemoveSecretsForContactPoint(t *testing.T) {
|
||||
"webhook": func(settings map[string]any) { // add additional field to the settings because valid config does not allow it to be specified along with password
|
||||
settings["authorization_credentials"] = "test-authz-creds"
|
||||
},
|
||||
"jira": func(settings map[string]any) { // add additional field to the settings because valid config does not allow it to be specified along with password
|
||||
settings["api_token"] = "test-token"
|
||||
},
|
||||
}
|
||||
|
||||
configs := notify.AllKnownConfigsForTesting
|
||||
|
||||
@@ -192,7 +192,7 @@ require (
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb // indirect
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 // indirect
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||
github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 // indirect
|
||||
|
||||
@@ -566,8 +566,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0 h1:LGH+tVzHCDrR9hsltmkP4jmNRg5IreQw5CNFbJKlnts=
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb h1:WfCsiuZXhGXIdzImQ9/Kjfn9M4e6f7z5mddcSKCRxmI=
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 h1:NTMmow+74I3Jb033xhbRgWQS7A//5TDhiM4tl7bsVP4=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7/go.mod h1:T3X4z0ejGfJOiOmZLFeKCRT/yxWJq/RtclAc/PHj/w4=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 h1:EokLC5grHwLPs4tXW8T6E8187H1e5G9AP0QQ5B60HbA=
|
||||
|
||||
@@ -117,7 +117,7 @@ require (
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb // indirect
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect
|
||||
github.com/grafana/grafana-aws-sdk v0.31.5 // indirect
|
||||
|
||||
@@ -397,8 +397,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
||||
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0 h1:LGH+tVzHCDrR9hsltmkP4jmNRg5IreQw5CNFbJKlnts=
|
||||
github.com/grafana/alerting v0.0.0-20250219153626-c475b1a572b0/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb h1:WfCsiuZXhGXIdzImQ9/Kjfn9M4e6f7z5mddcSKCRxmI=
|
||||
github.com/grafana/alerting v0.0.0-20250220212119-4baca04e46bb/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 h1:NTMmow+74I3Jb033xhbRgWQS7A//5TDhiM4tl7bsVP4=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7/go.mod h1:T3X4z0ejGfJOiOmZLFeKCRT/yxWJq/RtclAc/PHj/w4=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 h1:EokLC5grHwLPs4tXW8T6E8187H1e5G9AP0QQ5B60HbA=
|
||||
|
||||
@@ -1392,9 +1392,15 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||
t.Run("should return secrets in secureFields but not settings", func(t *testing.T) {
|
||||
for _, integration := range get.Spec.Integrations {
|
||||
t.Run(integration.Type, func(t *testing.T) {
|
||||
expected := notify.AllKnownConfigsForTesting[strings.ToLower(integration.Type)]
|
||||
var fields map[string]any
|
||||
require.NoError(t, json.Unmarshal([]byte(expected.Config), &fields))
|
||||
secretFields, err := channels_config.GetSecretKeysForContactPointType(integration.Type)
|
||||
require.NoError(t, err)
|
||||
for _, field := range secretFields {
|
||||
if _, ok := fields[field]; !ok { // skip field that is not in the original setting
|
||||
continue
|
||||
}
|
||||
assert.Contains(t, integration.SecureFields, field)
|
||||
assert.Truef(t, integration.SecureFields[field], "secure field should be always true")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user