Skip to content

Commit

Permalink
chore: add aws-pod-identity e2e tests (kedacore#3685)
Browse files Browse the repository at this point in the history
* chore: add aws-pod-identity e2e tests

Signed-off-by: Jorge Turrado <[email protected]>
  • Loading branch information
JorTurFer authored Sep 27, 2022
1 parent f666fca commit 9d97bcb
Show file tree
Hide file tree
Showing 16 changed files with 1,332 additions and 16 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in
$(KUSTOMIZE) edit add label --force azure.workload.identity/use:true; \
$(KUSTOMIZE) edit add annotation --force azure.workload.identity/client-id:${AZURE_SP_APP_ID} azure.workload.identity/tenant-id:${AZURE_SP_TENANT}; \
fi
if [ "$(AWS_RUN_IDENTITY_TESTS)" = true ]; then \
cd config/service_account && \
$(KUSTOMIZE) edit add annotation --force eks.amazonaws.com/role-arn:arn:aws:iam::${AWS_ACCOUNT_ID}:role/${TEST_CLUSTER_NAME}; \
fi
# Need this workaround to mitigate a problem with inserting labels into selectors,
# until this issue is solved: https://github.com/kubernetes-sigs/kustomize/issues/1009
@sed -i".out" -e 's@version:[ ].*@version: $(VERSION)@g' config/default/kustomize-config/metadataLabelTransformer.yaml
Expand Down
5 changes: 5 additions & 0 deletions tests/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@ import (

const (
AzureWorkloadIdentityNamespace = "azure-workload-identity-system"
AwsIdentityNamespace = "aws-identity-system"
KEDANamespace = "keda"
KEDAOperator = "keda-operator"
KEDAMetricsAPIServer = "keda-metrics-apiserver"

DefaultHTTPTimeOut = 3000

StringFalse = "false"
StringTrue = "true"
)

var _ = godotenv.Load()
Expand All @@ -47,6 +51,7 @@ var random = rand.New(rand.NewSource(time.Now().UnixNano()))
var (
AzureADTenantID = os.Getenv("AZURE_SP_TENANT")
AzureRunWorkloadIdentityTests = os.Getenv("AZURE_RUN_WORKLOAD_IDENTITY_TESTS")
AwsIdentityTests = os.Getenv("AWS_RUN_IDENTITY_TESTS")
)

var (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

// Load environment variables from .env file
var _ = godotenv.Load("../../.env")
var _ = godotenv.Load("../../../.env")

const (
testName = "aws-cloudwatch-test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

// Load environment variables from .env file
var _ = godotenv.Load("../../.env")
var _ = godotenv.Load("../../../.env")

const (
testName = "aws-cloudwatch-expression-test"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
//go:build e2e
// +build e2e

package aws_cloudwatch_pod_identity_test

import (
"context"
"encoding/base64"
"fmt"
"os"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
"k8s.io/client-go/kubernetes"

. "github.com/kedacore/keda/v2/tests/helper"
)

// Load environment variables from .env file
var _ = godotenv.Load("../../../.env")

const (
testName = "aws-cloudwatch-pod-identity-test"
)

type templateData struct {
TestNamespace string
DeploymentName string
ScaledObjectName string
SecretName string
AwsAccessKeyID string
AwsSecretAccessKey string
AwsRegion string
CloudWatchMetricName string
CloudWatchMetricNamespace string
CloudWatchMetricDimensionName string
CloudWatchMetricDimensionValue string
}

const (
triggerAuthenticationTemplate = `apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-trigger-auth-aws-credentials
namespace: {{.TestNamespace}}
spec:
podIdentity:
provider: aws-eks
`

deploymentTemplate = `
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.DeploymentName}}
namespace: {{.TestNamespace}}
labels:
app: {{.DeploymentName}}
spec:
replicas: 0
selector:
matchLabels:
app: {{.DeploymentName}}
template:
metadata:
labels:
app: {{.DeploymentName}}
spec:
serviceAccountName: default
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
`

scaledObjectTemplate = `
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: {{.ScaledObjectName}}
namespace: {{.TestNamespace}}
labels:
app: {{.DeploymentName}}
spec:
scaleTargetRef:
name: {{.DeploymentName}}
maxReplicaCount: 2
minReplicaCount: 0
cooldownPeriod: 1
triggers:
- type: aws-cloudwatch
authenticationRef:
name: keda-trigger-auth-aws-credentials
metadata:
awsRegion: {{.AwsRegion}}
namespace: {{.CloudWatchMetricNamespace}}
dimensionName: {{.CloudWatchMetricDimensionName}}
dimensionValue: {{.CloudWatchMetricDimensionValue}}
metricName: {{.CloudWatchMetricName}}
targetMetricValue: "1"
activationTargetMetricValue: "5"
minMetricValue: "0"
metricCollectionTime: "120"
metricStatPeriod: "30"
identityOwner: operator
`
)

var (
testNamespace = fmt.Sprintf("%s-ns", testName)
deploymentName = fmt.Sprintf("%s-deployment", testName)
scaledObjectName = fmt.Sprintf("%s-so", testName)
secretName = fmt.Sprintf("%s-secret", testName)
cloudwatchMetricName = fmt.Sprintf("%s-keda-metric-%d", testName, GetRandomNumber())
awsAccessKeyID = os.Getenv("AWS_ACCESS_KEY")
awsSecretAccessKey = os.Getenv("AWS_SECRET_KEY")
awsRegion = os.Getenv("AWS_REGION")
cloudwatchMetricNamespace = "KEDA"
cloudwatchMetricDimensionName = "dimensionName"
cloudwatchMetricDimensionValue = "dimensionValue"
maxReplicaCount = 2
minReplicaCount = 0
)

func TestCloudWatchScaler(t *testing.T) {
// setup cloudwatch
cloudwatchClient := createCloudWatchClient()
setCloudWatchCustomMetric(t, cloudwatchClient, 0)

// Create kubernetes resources
kc := GetKubernetesClient(t)
data, templates := getTemplateData()
CreateKubernetesResources(t, kc, testNamespace, data, templates)

assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 1),
"replica count should be %d after 1 minute", minReplicaCount)

// test scaling
testActivation(t, kc, cloudwatchClient)
testScaleUp(t, kc, cloudwatchClient)
testScaleDown(t, kc, cloudwatchClient)

// cleanup
DeleteKubernetesResources(t, kc, testNamespace, data, templates)

setCloudWatchCustomMetric(t, cloudwatchClient, 0)
}

func testActivation(t *testing.T, kc *kubernetes.Clientset, cloudwatchClient *cloudwatch.CloudWatch) {
t.Log("--- testing activation ---")
setCloudWatchCustomMetric(t, cloudwatchClient, 3)

AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, minReplicaCount, 60)
}

func testScaleUp(t *testing.T, kc *kubernetes.Clientset, cloudwatchClient *cloudwatch.CloudWatch) {
t.Log("--- testing scale up ---")
setCloudWatchCustomMetric(t, cloudwatchClient, 10)

assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3),
"replica count should be %d after 3 minutes", maxReplicaCount)
}

func testScaleDown(t *testing.T, kc *kubernetes.Clientset, cloudwatchClient *cloudwatch.CloudWatch) {
t.Log("--- testing scale down ---")

setCloudWatchCustomMetric(t, cloudwatchClient, 0)

assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3),
"replica count should be %d after 3 minutes", minReplicaCount)
}

func setCloudWatchCustomMetric(t *testing.T, cloudwatchClient *cloudwatch.CloudWatch, value float64) {
_, err := cloudwatchClient.PutMetricDataWithContext(context.Background(), &cloudwatch.PutMetricDataInput{
MetricData: []*cloudwatch.MetricDatum{
{
MetricName: aws.String(cloudwatchMetricName),
Dimensions: []*cloudwatch.Dimension{
{
Name: aws.String(cloudwatchMetricDimensionName),
Value: aws.String(cloudwatchMetricDimensionValue),
},
},
Unit: aws.String("None"),
Value: aws.Float64(value),
},
},
Namespace: aws.String(cloudwatchMetricNamespace),
})
assert.NoErrorf(t, err, "failed to set cloudwatch metric - %s", err)
}

func createCloudWatchClient() *cloudwatch.CloudWatch {
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(awsRegion),
}))

return cloudwatch.New(sess, &aws.Config{
Region: aws.String(awsRegion),
Credentials: credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, ""),
})
}

func getTemplateData() (templateData, []Template) {
return templateData{
TestNamespace: testNamespace,
DeploymentName: deploymentName,
ScaledObjectName: scaledObjectName,
SecretName: secretName,
AwsAccessKeyID: base64.StdEncoding.EncodeToString([]byte(awsAccessKeyID)),
AwsSecretAccessKey: base64.StdEncoding.EncodeToString([]byte(awsSecretAccessKey)),
AwsRegion: awsRegion,
CloudWatchMetricName: cloudwatchMetricName,
CloudWatchMetricNamespace: cloudwatchMetricNamespace,
CloudWatchMetricDimensionName: cloudwatchMetricDimensionName,
CloudWatchMetricDimensionValue: cloudwatchMetricDimensionValue,
}, []Template{
{Name: "triggerAuthenticationTemplate", Config: triggerAuthenticationTemplate},
{Name: "deploymentTemplate", Config: deploymentTemplate},
{Name: "scaledObjectTemplate", Config: scaledObjectTemplate},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
)

// Load environment variables from .env file
var _ = godotenv.Load("../../.env")
var _ = godotenv.Load("../../../.env")

const (
testName = "aws-dynamodb-test"
Expand Down
Loading

0 comments on commit 9d97bcb

Please sign in to comment.