diff --git a/README.md b/README.md index d715fbabd..57d55086d 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ Only the latest version gets security updates. We won't support older versions. * `AWS/QuickSight` - QuickSight (Business Intelligence) * `AWS/RDS` - Relational Database Service * `AWS/Redshift` - Redshift Database + * `AWS/Redshift-Serverless` - Redshift Serverless * `AWS/Route53` - Route53 Health Checks * `AWS/Route53Resolver` - Route53 Resolver * `AWS/RUM` - Real User Monitoring diff --git a/examples/redshift-serverless.yml b/examples/redshift-serverless.yml new file mode 100644 index 000000000..e06919fd4 --- /dev/null +++ b/examples/redshift-serverless.yml @@ -0,0 +1,21 @@ +apiVersion: v1alpha1 +discovery: + jobs: + - type: AWS/Redshift-Serverless + regions: + - us-east-1 + period: 300 + length: 300 + metrics: + - name: DatabaseConnections + statistics: [Average] + - name: ComputeCapacity + statistics: [Average] + - name: QueryRuntimeBreakdown + statistics: [Average] + - name: QueriesRunning + statistics: [Average] + - name: QueriesQueued + statistics: [Average] + - name: QueryDuration + statistics: [Average] diff --git a/pkg/config/services.go b/pkg/config/services.go index 3361e72fe..d79cc2a27 100644 --- a/pkg/config/services.go +++ b/pkg/config/services.go @@ -760,6 +760,14 @@ var SupportedServices = serviceConfigs{ regexp.MustCompile(":cluster:(?P[^/]+)"), }, }, + { + Namespace: "AWS/Redshift-Serverless", + Alias: "redshift", + ResourceFilters: []*string{ + aws.String("redshift-serverless:workgroup"), + aws.String("redshift-serverless:namespace"), + }, + }, { Namespace: "AWS/Route53Resolver", Alias: "route53-resolver", diff --git a/pkg/job/maxdimassociator/associator_redshift_serverless_test.go b/pkg/job/maxdimassociator/associator_redshift_serverless_test.go new file mode 100644 index 000000000..646fa7283 --- /dev/null +++ b/pkg/job/maxdimassociator/associator_redshift_serverless_test.go @@ -0,0 +1,81 @@ +// Copyright 2024 The Prometheus Authors +// 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 maxdimassociator + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/config" + "github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/logging" + "github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/model" +) + +var workgroup = &model.TaggedResource{ + ARN: "arn:aws:redshift-serverless:us-east-1:123456789012:workgroup/my-workgroup1", + Namespace: "AWS/Redshift-Serverless", +} + +var namespace = &model.TaggedResource{ + ARN: "arn:aws:redshift-serverless:us-east-1:123456789012:namespace/my-namespace1", + Namespace: "AWS/Redshift-Serverless", +} + +var redshiftResources = []*model.TaggedResource{ + workgroup, + namespace, +} + +func TestAssociatorRedshiftServerless(t *testing.T) { + type args struct { + dimensionRegexps []model.DimensionsRegexp + resources []*model.TaggedResource + metric *model.Metric + } + + type testCase struct { + name string + args args + expectedSkip bool + expectedResource *model.TaggedResource + } + + testcases := []testCase{ + { + name: "should not match nor skip with any workgroup none ARN dimension", + args: args{ + dimensionRegexps: config.SupportedServices.GetService("AWS/Redshift-Serverless").ToModelDimensionsRegexp(), + resources: redshiftResources, + metric: &model.Metric{ + MetricName: "ComputeSeconds", + Namespace: "AWS/Redshift-Serverless", + Dimensions: []model.Dimension{ + {Name: "ResourceArn", Value: "my-nonexistant-workgroup-test1"}, + }, + }, + }, + expectedSkip: false, + expectedResource: nil, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + associator := NewAssociator(logging.NewNopLogger(), tc.args.dimensionRegexps, tc.args.resources) + res, skip := associator.AssociateMetricToResource(tc.args.metric) + require.Equal(t, tc.expectedSkip, skip) + require.Equal(t, tc.expectedResource, res) + }) + } +}