diff --git a/README.md b/README.md index 88c90fc..c7a19eb 100644 --- a/README.md +++ b/README.md @@ -70,8 +70,7 @@ the [`local-config.yaml`][config] can be used to set the variables. | `UPDATE_JOB_INTERVAL_MINUTES` | `15` | Interval in minutes for refreshing the metadata repository cache. | | `UPDATE_JOB_TIMEOUT_SECONDS` | `30` | Timeout in seconds when fetching the Git repository. | | | | | -| `ALERT_TARGET_PREFIX` | | Validates the alert target to either match the prefix or suffix. | -| `ALERT_TARGET_SUFFIX` | | | +| `ALERT_TARGET_REGEX` | | Validates the alert target to match the regular expression. | | | | | | `OWNER_ALIAS_PERMITTED_REGEX` | `^[a-z](-?[a-z0-9]+)*$` | Regular expression to control the owner aliases that are permitted to be be created. | | `OWNER_ALIAS_PROHIBITED_REGEX` | `^$` | Regular expression to control the owner aliases that are prohibited to be be created. | diff --git a/internal/acorn/config/customconfigint.go b/internal/acorn/config/customconfigint.go index 748ef0e..21c7e06 100644 --- a/internal/acorn/config/customconfigint.go +++ b/internal/acorn/config/customconfigint.go @@ -40,8 +40,7 @@ type CustomConfiguration interface { UpdateJobIntervalCronPart() string UpdateJobTimeoutSeconds() uint16 - AlertTargetPrefix() string - AlertTargetSuffix() string + AlertTargetRegex() *regexp.Regexp ElasticApmEnabled() bool @@ -98,10 +97,6 @@ const ( KeyBitbucketReviewerFallback = "BITBUCKET_REVIEWER_FALLBACK" KeyGitCommitterName = "GIT_COMMITTER_NAME" KeyGitCommitterEmail = "GIT_COMMITTER_EMAIL" - KeyKafkaUsername = "KAFKA_USERNAME" - KeyKafkaPassword = "KAFKA_PASSWORD" - KeyKafkaTopic = "KAFKA_TOPIC" - KeyKafkaSeedBrokers = "KAFKA_SEED_BROKERS" KeyKafkaGroupIdOverride = "KAFKA_GROUP_ID_OVERRIDE" KeyAuthOidcKeySetUrl = "AUTH_OIDC_KEY_SET_URL" KeyAuthOidcTokenAudience = "AUTH_OIDC_TOKEN_AUDIENCE" @@ -110,8 +105,7 @@ const ( KeyMetadataRepoMainline = "METADATA_REPO_MAINLINE" KeyUpdateJobIntervalMinutes = "UPDATE_JOB_INTERVAL_MINUTES" KeyUpdateJobTimeoutSeconds = "UPDATE_JOB_TIMEOUT_SECONDS" - KeyAlertTargetPrefix = "ALERT_TARGET_PREFIX" - KeyAlertTargetSuffix = "ALERT_TARGET_SUFFIX" + KeyAlertTargetRegex = "ALERT_TARGET_REGEX" KeyElasticApmDisabled = "ELASTIC_APM_DISABLED" KeyOwnerAliasPermittedRegex = "OWNER_ALIAS_PERMITTED_REGEX" KeyOwnerAliasProhibitedRegex = "OWNER_ALIAS_PROHIBITED_REGEX" diff --git a/internal/repository/config/accessors.go b/internal/repository/config/accessors.go index 19c1230..8ecd556 100644 --- a/internal/repository/config/accessors.go +++ b/internal/repository/config/accessors.go @@ -93,12 +93,8 @@ func (c *CustomConfigImpl) UpdateJobTimeoutSeconds() uint16 { return c.VUpdateJobTimeoutSeconds } -func (c *CustomConfigImpl) AlertTargetPrefix() string { - return c.VAlertTargetPrefix -} - -func (c *CustomConfigImpl) AlertTargetSuffix() string { - return c.VAlertTargetSuffix +func (c *CustomConfigImpl) AlertTargetRegex() *regexp.Regexp { + return c.VAlertTargetRegex } func (c *CustomConfigImpl) ElasticApmEnabled() bool { diff --git a/internal/repository/config/config.go b/internal/repository/config/config.go index f227e39..2b0a589 100644 --- a/internal/repository/config/config.go +++ b/internal/repository/config/config.go @@ -1,10 +1,11 @@ package config import ( + "math" + "github.com/Interhyp/metadata-service/internal/acorn/config" auconfigapi "github.com/StephanHCB/go-autumn-config-api" auconfigenv "github.com/StephanHCB/go-autumn-config-env" - "math" ) var CustomConfigItems = []auconfigapi.ConfigItem{ @@ -156,16 +157,10 @@ var CustomConfigItems = []auconfigapi.ConfigItem{ Validate: auconfigenv.ObtainUintRangeValidator(10, 60), }, { - Key: config.KeyAlertTargetPrefix, - EnvName: config.KeyAlertTargetPrefix, - Default: "", - Validate: auconfigenv.ObtainPatternValidator("^((http|https)://|)[a-z0-9-.]+.[a-z]{2,3}/$"), - }, - { - Key: config.KeyAlertTargetSuffix, - EnvName: config.KeyAlertTargetSuffix, + Key: config.KeyAlertTargetRegex, + EnvName: config.KeyAlertTargetRegex, Default: "", - Validate: auconfigenv.ObtainPatternValidator("^@[a-z0-9-]+.[a-z]{2,3}$"), + Validate: auconfigenv.ObtainIsRegexValidator(), }, { Key: config.KeyElasticApmDisabled, diff --git a/internal/repository/config/plumbing.go b/internal/repository/config/plumbing.go index 12d2971..a855b44 100644 --- a/internal/repository/config/plumbing.go +++ b/internal/repository/config/plumbing.go @@ -17,12 +17,6 @@ import ( "github.com/StephanHCB/go-backend-service-common/repository/vault" ) -const ( - allowedNotificationTypeService = "Service" - allowedNotificationTypeOwner = "Owner" - allowedNotificationTypeRepository = "Repository" -) - type CustomConfigImpl struct { VBasicAuthUsername string VBasicAuthPassword string @@ -45,8 +39,7 @@ type CustomConfigImpl struct { VMetadataRepoMainline string VUpdateJobIntervalCronPart string VUpdateJobTimeoutSeconds uint16 - VAlertTargetPrefix string - VAlertTargetSuffix string + VAlertTargetRegex *regexp.Regexp VElasticApmDisabled bool VOwnerAliasPermittedRegex *regexp.Regexp VOwnerAliasProhibitedRegex *regexp.Regexp @@ -109,8 +102,7 @@ func (c *CustomConfigImpl) Obtain(getter func(key string) string) { c.VMetadataRepoMainline = getter(config.KeyMetadataRepoMainline) c.VUpdateJobIntervalCronPart = getter(config.KeyUpdateJobIntervalMinutes) c.VUpdateJobTimeoutSeconds = toUint16(getter(config.KeyUpdateJobTimeoutSeconds)) - c.VAlertTargetPrefix = getter(config.KeyAlertTargetPrefix) - c.VAlertTargetSuffix = getter(config.KeyAlertTargetSuffix) + c.VAlertTargetRegex, _ = regexp.Compile(getter(config.KeyAlertTargetRegex)) c.VElasticApmDisabled, _ = strconv.ParseBool(getter(config.KeyElasticApmDisabled)) c.VOwnerAliasPermittedRegex, _ = regexp.Compile(getter(config.KeyOwnerAliasPermittedRegex)) c.VOwnerAliasProhibitedRegex, _ = regexp.Compile(getter(config.KeyOwnerAliasProhibitedRegex)) diff --git a/internal/repository/config/validation_test.go b/internal/repository/config/validation_test.go index 5ae1b0e..68fc364 100644 --- a/internal/repository/config/validation_test.go +++ b/internal/repository/config/validation_test.go @@ -3,9 +3,10 @@ package config import ( "bytes" "context" - "github.com/Interhyp/metadata-service/internal/acorn/config" "testing" + "github.com/Interhyp/metadata-service/internal/acorn/config" + auconfigenv "github.com/StephanHCB/go-autumn-config-env" goauzerolog "github.com/StephanHCB/go-autumn-logging-zerolog" librepo "github.com/StephanHCB/go-backend-service-common/acorns/repository" @@ -78,7 +79,7 @@ func TestValidate_LotsOfErrors(t *testing.T) { _, err := tstSetupCutAndLogRecorder(t, "invalid-config-values.yaml") require.NotNil(t, err) - require.Contains(t, err.Error(), "some configuration values failed to validate or parse. There were 28 error(s). See details above") + require.Contains(t, err.Error(), "some configuration values failed to validate or parse. There were 26 error(s). See details above") actualLog := goauzerolog.RecordedLogForTesting.String() @@ -91,12 +92,6 @@ func TestValidate_LotsOfErrors(t *testing.T) { expectedPart3 := "METRICS_PORT: value -12387192873invalid is not a valid integer" require.Contains(t, actualLog, expectedPart3) - expectedPart4 := "failed to validate configuration field ALERT_TARGET_PREFIX: must match ^((http|https)://|)[a-z0-9-.]+.[a-z]{2,3}/$" - require.Contains(t, actualLog, expectedPart4) - - expectedPart5 := "failed to validate configuration field ALERT_TARGET_SUFFIX: must match ^@[a-z0-9-]+.[a-z]{2,3}$" - require.Contains(t, actualLog, expectedPart5) - expectedPart6 := "failed to validate configuration field VAULT_ENABLED: value what is not a valid boolean value" require.Contains(t, actualLog, expectedPart6) @@ -139,8 +134,7 @@ func TestAccessors(t *testing.T) { require.Equal(t, "git://metadata", config.Custom(cut).SSHMetadataRepositoryUrl()) require.Equal(t, "5", config.Custom(cut).UpdateJobIntervalCronPart()) require.Equal(t, uint16(30), config.Custom(cut).UpdateJobTimeoutSeconds()) - require.Equal(t, "https://some-domain.com/", config.Custom(cut).AlertTargetPrefix()) - require.Equal(t, "@some-domain.com", config.Custom(cut).AlertTargetSuffix()) + require.Equal(t, "(^https://domain[.]com/)|(@domain[.]com$)", config.Custom(cut).AlertTargetRegex().String()) require.Equal(t, "[a-z][0-1]+", config.Custom(cut).OwnerAliasPermittedRegex().String()) require.Equal(t, "[a-z][0-2]+", config.Custom(cut).OwnerAliasProhibitedRegex().String()) require.Equal(t, uint16(1), config.Custom(cut).OwnerAliasMaxLength()) diff --git a/internal/service/services/services.go b/internal/service/services/services.go index ec71593..42297b6 100644 --- a/internal/service/services/services.go +++ b/internal/service/services/services.go @@ -4,9 +4,10 @@ import ( "context" "errors" "fmt" + "strings" + "github.com/Interhyp/metadata-service/internal/acorn/repository" auzerolog "github.com/StephanHCB/go-autumn-logging-zerolog" - "strings" "github.com/Interhyp/metadata-service/api" "github.com/Interhyp/metadata-service/internal/acorn/config" @@ -531,7 +532,7 @@ func (s *Impl) validateAlertTarget(messages []string, alertTarget string) []stri messages = append(messages, "field alertTarget is mandatory") } else { if !s.validAlertTarget(alertTarget) { - messages = append(messages, "field alertTarget must either be an email address @some-organisation.com or a Teams webhook") + messages = append(messages, fmt.Sprintf("field alertTarget must match %s", s.CustomConfiguration.AlertTargetRegex().String())) } } return messages @@ -552,8 +553,7 @@ func validateDescription(messages []string, description *string) []string { } func (s *Impl) validAlertTarget(candidate string) bool { - return strings.HasPrefix(candidate, s.CustomConfiguration.AlertTargetPrefix()) || - strings.HasSuffix(candidate, s.CustomConfiguration.AlertTargetSuffix()) + return s.CustomConfiguration.AlertTargetRegex().MatchString(candidate) } func (s *Impl) validRepoKey(ctx context.Context, candidate string, serviceName string) error { diff --git a/internal/service/services/services_test.go b/internal/service/services/services_test.go index 4bf4f1c..e93b618 100644 --- a/internal/service/services/services_test.go +++ b/internal/service/services/services_test.go @@ -352,7 +352,7 @@ func TestValidate_AlertTarget(t *testing.T) { AlertTarget: p("somethingother"), } - expectedMessage := "validation error: field alertTarget must either be an email address @some-organisation.com or a Teams webhook" + expectedMessage := "validation error: field alertTarget must match @some-organisation[.]com$" tstValidationTestcaseAllOps(t, expectedMessage, data, create, patch) } diff --git a/local-config.template.yaml b/local-config.template.yaml index 3e0e728..0692c28 100644 --- a/local-config.template.yaml +++ b/local-config.template.yaml @@ -45,8 +45,7 @@ SSH_METADATA_REPO_URL: ssh://git@github.com/Interhyp/service-metadata-example.gi UPDATE_JOB_INTERVAL_MINUTES: 15 UPDATE_JOB_TIMEOUT_SECONDS: 30 -ALERT_TARGET_PREFIX: https://domain.com/ -ALERT_TARGET_SUFFIX: '@domain.com' +ALERT_TARGET_REGEX: '(^https://domain[.]com/)|(@domain[.]com$)' OWNER_ALIAS_FILTER_REGEX: '.*' diff --git a/test/mock/configmock/configmock.go b/test/mock/configmock/configmock.go index d684190..b47829b 100644 --- a/test/mock/configmock/configmock.go +++ b/test/mock/configmock/configmock.go @@ -158,12 +158,8 @@ func (c *MockConfig) UpdateJobTimeoutSeconds() uint16 { panic("implement me") } -func (c *MockConfig) AlertTargetPrefix() string { - return "https://some-domain.com/" -} - -func (c *MockConfig) AlertTargetSuffix() string { - return "@some-organisation.com" +func (c *MockConfig) AlertTargetRegex() *regexp.Regexp { + return regexp.MustCompile("@some-organisation[.]com$") } func (c *MockConfig) ElasticApmEnabled() bool { diff --git a/test/resources/valid-config-unique.yaml b/test/resources/valid-config-unique.yaml index a464416..acd2b19 100644 --- a/test/resources/valid-config-unique.yaml +++ b/test/resources/valid-config-unique.yaml @@ -25,8 +25,7 @@ METADATA_REPO_URL: http://metadata UPDATE_JOB_INTERVAL_MINUTES: 5 UPDATE_JOB_TIMEOUT_SECONDS: 30 -ALERT_TARGET_PREFIX: https://some-domain.com/ -ALERT_TARGET_SUFFIX: '@some-domain.com' +ALERT_TARGET_REGEX: '(^https://domain[.]com/)|(@domain[.]com$)' OWNER_ALIAS_PERMITTED_REGEX: '[a-z][0-1]+' OWNER_ALIAS_PROHIBITED_REGEX: '[a-z][0-2]+'