diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e713823d52..e256f99ea10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,7 +43,8 @@ - **Kafka Scaler:** allow flag `topic` to be optional, where lag of all topics within the consumer group will be used for scaling ([#2409](https://github.com/kedacore/keda/pull/2409)) - **General:** fail fast on `buildScalers` when not able to resolve a secret that a deployment is relying on ([#2394](https://github.com/kedacore/keda/pull/2394)) - **CPU Scaler:** Adding e2e test for the cpu scaler ([#2441](https://github.com/kedacore/keda/pull/2441)) -- **AWS SQS Scaler**: allow using simple queue name instead of URL ([#2457](https://github.com/kedacore/keda/pull/2457)) +- **AWS SQS Scaler:** allow using simple queue name instead of URL ([#2457](https://github.com/kedacore/keda/pull/2457)) +- **AWS Scalers:** Support temporary AWS credentials using session tokens ([#2573](https://github.com/kedacore/keda/pull/2573)) ### Breaking Changes diff --git a/pkg/scalers/aws_cloudwatch_scaler.go b/pkg/scalers/aws_cloudwatch_scaler.go index fb68e43cc86..3a1eb57d54b 100644 --- a/pkg/scalers/aws_cloudwatch_scaler.go +++ b/pkg/scalers/aws_cloudwatch_scaler.go @@ -112,7 +112,7 @@ func createCloudwatchClient(metadata *awsCloudwatchMetadata) *cloudwatch.CloudWa var cloudwatchClient *cloudwatch.CloudWatch if metadata.awsAuthorization.podIdentityOwner { - creds := credentials.NewStaticCredentials(metadata.awsAuthorization.awsAccessKeyID, metadata.awsAuthorization.awsSecretAccessKey, "") + creds := credentials.NewStaticCredentials(metadata.awsAuthorization.awsAccessKeyID, metadata.awsAuthorization.awsSecretAccessKey, metadata.awsAuthorization.awsSessionToken) if metadata.awsAuthorization.awsRoleArn != "" { creds = stscreds.NewCredentials(sess, metadata.awsAuthorization.awsRoleArn) diff --git a/pkg/scalers/aws_cloudwatch_test.go b/pkg/scalers/aws_cloudwatch_test.go index 72c1c034d22..f03cd439d51 100644 --- a/pkg/scalers/aws_cloudwatch_test.go +++ b/pkg/scalers/aws_cloudwatch_test.go @@ -17,6 +17,7 @@ const ( testAWSCloudwatchRoleArn = "none" testAWSCloudwatchAccessKeyID = "none" testAWSCloudwatchSecretAccessKey = "none" + testAWSCloudwatchSessionToken = "none" testAWSCloudwatchErrorMetric = "Error" testAWSCloudwatchNoValueMetric = "NoValue" ) @@ -127,7 +128,7 @@ var testAWSCloudwatchMetadata = []parseAWSCloudwatchMetadataTestData{ testAWSAuthentication, true, "Missing metricName"}, - // with "aws_credentials" from TriggerAuthentication + // with static "aws_credentials" from TriggerAuthentication {map[string]string{ "namespace": "AWS/SQS", "dimensionName": "QueueName", @@ -145,6 +146,25 @@ var testAWSCloudwatchMetadata = []parseAWSCloudwatchMetadataTestData{ }, false, "with AWS Credentials from TriggerAuthentication"}, + // with temporary "aws_credentials" from TriggerAuthentication + {map[string]string{ + "namespace": "AWS/SQS", + "dimensionName": "QueueName", + "dimensionValue": "keda", + "metricName": "ApproximateNumberOfMessagesVisible", + "targetMetricValue": "2", + "minMetricValue": "0", + "metricCollectionTime": "300", + "metricStat": "Average", + "metricStatPeriod": "300", + "awsRegion": "eu-west-1"}, + map[string]string{ + "awsAccessKeyId": testAWSCloudwatchAccessKeyID, + "awsSecretAccessKey": testAWSCloudwatchSecretAccessKey, + "awsSessionToken": testAWSCloudwatchSessionToken, + }, + false, + "with AWS Credentials from TriggerAuthentication"}, // with "aws_role" from TriggerAuthentication {map[string]string{ "namespace": "AWS/SQS", diff --git a/pkg/scalers/aws_iam_authorization.go b/pkg/scalers/aws_iam_authorization.go index 83162952351..b8e15c0c34d 100644 --- a/pkg/scalers/aws_iam_authorization.go +++ b/pkg/scalers/aws_iam_authorization.go @@ -7,6 +7,7 @@ type awsAuthorizationMetadata struct { awsAccessKeyID string awsSecretAccessKey string + awsSessionToken string podIdentityOwner bool } @@ -27,6 +28,7 @@ func getAwsAuthorization(authParams, metadata, resolvedEnv map[string]string) (a meta.awsAccessKeyID = authParams["awsAccessKeyId"] } meta.awsSecretAccessKey = authParams["awsSecretAccessKey"] + meta.awsSessionToken = authParams["awsSessionToken"] default: if metadata["awsAccessKeyID"] != "" { meta.awsAccessKeyID = metadata["awsAccessKeyID"] diff --git a/pkg/scalers/aws_kinesis_stream_scaler.go b/pkg/scalers/aws_kinesis_stream_scaler.go index 4a4c6db059c..3ffedcecb4a 100644 --- a/pkg/scalers/aws_kinesis_stream_scaler.go +++ b/pkg/scalers/aws_kinesis_stream_scaler.go @@ -99,7 +99,7 @@ func createKinesisClient(metadata *awsKinesisStreamMetadata) *kinesis.Kinesis { var kinesisClinent *kinesis.Kinesis if metadata.awsAuthorization.podIdentityOwner { - creds := credentials.NewStaticCredentials(metadata.awsAuthorization.awsAccessKeyID, metadata.awsAuthorization.awsSecretAccessKey, "") + creds := credentials.NewStaticCredentials(metadata.awsAuthorization.awsAccessKeyID, metadata.awsAuthorization.awsSecretAccessKey, metadata.awsAuthorization.awsSessionToken) if metadata.awsAuthorization.awsRoleArn != "" { creds = stscreds.NewCredentials(sess, metadata.awsAuthorization.awsRoleArn) diff --git a/pkg/scalers/aws_kinesis_stream_test.go b/pkg/scalers/aws_kinesis_stream_test.go index df5392ff2f4..332884b5fdb 100644 --- a/pkg/scalers/aws_kinesis_stream_test.go +++ b/pkg/scalers/aws_kinesis_stream_test.go @@ -17,6 +17,7 @@ const ( testAWSKinesisRoleArn = "none" testAWSKinesisAccessKeyID = "none" testAWSKinesisSecretAccessKey = "none" + testAWSKinesisSessionToken = "none" testAWSKinesisStreamName = "test" testAWSRegion = "eu-west-1" testAWSKinesisErrorStream = "Error" @@ -161,7 +162,7 @@ var testAWSKinesisMetadata = []parseAWSKinesisMetadataTestData{ }, expected: &awsKinesisStreamMetadata{}, isError: true, - comment: "with AWS Credentials from TriggerAuthentication, missing Access Key Id", + comment: "with AWS static credentials from TriggerAuthentication, missing Access Key Id", scalerIndex: 5, }, {metadata: map[string]string{ @@ -174,7 +175,62 @@ var testAWSKinesisMetadata = []parseAWSKinesisMetadataTestData{ }, expected: &awsKinesisStreamMetadata{}, isError: true, - comment: "with AWS Credentials from TriggerAuthentication, missing Secret Access Key", + comment: "with AWS static credentials from TriggerAuthentication, missing Secret Access Key", + scalerIndex: 6, + }, + { + metadata: map[string]string{ + "streamName": testAWSKinesisStreamName, + "shardCount": "2", + "awsRegion": testAWSRegion}, + authParams: map[string]string{ + "awsAccessKeyID": testAWSKinesisAccessKeyID, + "awsSecretAccessKey": testAWSKinesisSecretAccessKey, + "awsSessionToken": testAWSKinesisSessionToken, + }, + expected: &awsKinesisStreamMetadata{ + targetShardCount: 2, + streamName: testAWSKinesisStreamName, + awsRegion: testAWSRegion, + awsAuthorization: awsAuthorizationMetadata{ + awsAccessKeyID: testAWSKinesisAccessKeyID, + awsSecretAccessKey: testAWSKinesisSecretAccessKey, + awsSessionToken: testAWSKinesisSessionToken, + podIdentityOwner: true, + }, + scalerIndex: 5, + }, + isError: false, + comment: "with AWS temporary credentials from TriggerAuthentication", + scalerIndex: 5, + }, + { + metadata: map[string]string{ + "streamName": testAWSKinesisStreamName, + "shardCount": "2", + "awsRegion": testAWSRegion}, + authParams: map[string]string{ + "awsAccessKeyID": "", + "awsSecretAccessKey": testAWSKinesisSecretAccessKey, + "awsSessionToken": testAWSKinesisSessionToken, + }, + expected: &awsKinesisStreamMetadata{}, + isError: true, + comment: "with AWS temporary credentials from TriggerAuthentication, missing Access Key Id", + scalerIndex: 5, + }, + {metadata: map[string]string{ + "streamName": testAWSKinesisStreamName, + "shardCount": "2", + "awsRegion": testAWSRegion}, + authParams: map[string]string{ + "awsAccessKeyID": testAWSKinesisAccessKeyID, + "awsSecretAccessKey": "", + "awsSessionToken": testAWSKinesisSessionToken, + }, + expected: &awsKinesisStreamMetadata{}, + isError: true, + comment: "with AWS temporary credentials from TriggerAuthentication, missing Secret Access Key", scalerIndex: 6, }, {metadata: map[string]string{ diff --git a/pkg/scalers/aws_sqs_queue_scaler.go b/pkg/scalers/aws_sqs_queue_scaler.go index df24d604978..419229c26fe 100644 --- a/pkg/scalers/aws_sqs_queue_scaler.go +++ b/pkg/scalers/aws_sqs_queue_scaler.go @@ -122,7 +122,7 @@ func createSqsClient(metadata *awsSqsQueueMetadata) *sqs.SQS { var sqsClient *sqs.SQS if metadata.awsAuthorization.podIdentityOwner { - creds := credentials.NewStaticCredentials(metadata.awsAuthorization.awsAccessKeyID, metadata.awsAuthorization.awsSecretAccessKey, "") + creds := credentials.NewStaticCredentials(metadata.awsAuthorization.awsAccessKeyID, metadata.awsAuthorization.awsSecretAccessKey, metadata.awsAuthorization.awsSessionToken) if metadata.awsAuthorization.awsRoleArn != "" { creds = stscreds.NewCredentials(sess, metadata.awsAuthorization.awsRoleArn) diff --git a/pkg/scalers/aws_sqs_queue_test.go b/pkg/scalers/aws_sqs_queue_test.go index 550b816187d..b3cc43b56e1 100644 --- a/pkg/scalers/aws_sqs_queue_test.go +++ b/pkg/scalers/aws_sqs_queue_test.go @@ -16,6 +16,7 @@ const ( testAWSSQSRoleArn = "none" testAWSSQSAccessKeyID = "none" testAWSSQSSecretAccessKey = "none" + testAWSSQSSessionToken = "none" testAWSSQSProperQueueURL = "https://sqs.eu-west-1.amazonaws.com/account_id/DeleteArtifactQ" testAWSSQSImproperQueueURL1 = "https://sqs.eu-west-1.amazonaws.com/account_id" @@ -125,7 +126,38 @@ var testAWSSQSMetadata = []parseAWSSQSMetadataTestData{ "awsSecretAccessKey": testAWSSQSSecretAccessKey, }, false, - "with AWS Credentials from TriggerAuthentication"}, + "with AWS static credentials from TriggerAuthentication"}, + {map[string]string{ + "queueURL": testAWSSQSProperQueueURL, + "queueLength": "1", + "awsRegion": "eu-west-1"}, + map[string]string{ + "awsAccessKeyId": testAWSSQSAccessKeyID, + "awsSecretAccessKey": testAWSSQSSecretAccessKey, + "awsSessionToken": testAWSSQSSessionToken, + }, + false, + "with AWS temporary credentials from TriggerAuthentication"}, + {map[string]string{ + "queueURL": testAWSSQSProperQueueURL, + "queueLength": "1", + "awsRegion": "eu-west-1"}, + map[string]string{ + "awsAccessKeyId": "", + "awsSecretAccessKey": testAWSSQSSecretAccessKey, + }, + true, + "with AWS static credentials from TriggerAuthentication, missing Access Key Id"}, + {map[string]string{ + "queueURL": testAWSSQSProperQueueURL, + "queueLength": "1", + "awsRegion": "eu-west-1"}, + map[string]string{ + "awsAccessKeyId": testAWSSQSAccessKeyID, + "awsSecretAccessKey": "", + }, + true, + "with AWS temporary credentials from TriggerAuthentication, missing Secret Access Key"}, {map[string]string{ "queueURL": testAWSSQSProperQueueURL, "queueLength": "1", @@ -133,9 +165,10 @@ var testAWSSQSMetadata = []parseAWSSQSMetadataTestData{ map[string]string{ "awsAccessKeyId": "", "awsSecretAccessKey": testAWSSQSSecretAccessKey, + "awsSessionToken": testAWSSQSSessionToken, }, true, - "with AWS Credentials from TriggerAuthentication, missing Access Key Id"}, + "with AWS temporary credentials from TriggerAuthentication, missing Access Key Id"}, {map[string]string{ "queueURL": testAWSSQSProperQueueURL, "queueLength": "1", @@ -143,9 +176,10 @@ var testAWSSQSMetadata = []parseAWSSQSMetadataTestData{ map[string]string{ "awsAccessKeyId": testAWSSQSAccessKeyID, "awsSecretAccessKey": "", + "awsSessionToken": testAWSSQSSessionToken, }, true, - "with AWS Credentials from TriggerAuthentication, missing Secret Access Key"}, + "with AWS static credentials from TriggerAuthentication, missing Secret Access Key"}, {map[string]string{ "queueURL": testAWSSQSProperQueueURL, "queueLength": "1",