diff --git a/.github/workflows/dotnet-eks-canary.yml b/.github/workflows/dotnet-eks-canary.yml new file mode 100644 index 000000000..e77e2ffca --- /dev/null +++ b/.github/workflows/dotnet-eks-canary.yml @@ -0,0 +1,37 @@ +## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +## SPDX-License-Identifier: Apache-2.0 + +## This workflow aims to run the Application Signals DotNet end-to-end tests as a canary to +## test the artifacts for Application Signals enablement. It will deploy a sample app and remote +## service onto an EKS cluster, call the APIs, and validate the generated telemetry, +## including logs, metrics, and traces. +name: Dotnet EKS Enablement Canary Testing +on: + schedule: + - cron: '*/15 * * * *' # run the workflow every 15 minutes + workflow_dispatch: # be able to run the workflow on demand + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +permissions: + id-token: write + contents: read + + +jobs: + eks: + strategy: + fail-fast: false + matrix: + aws-region: ['af-south-1','ap-east-1','ap-northeast-1','ap-northeast-2','ap-northeast-3','ap-south-1','ap-south-2','ap-southeast-1', + 'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1', + 'eu-south-1','eu-south-2','eu-west-1','eu-west-2','eu-west-3','il-central-1','me-central-1','me-south-1', 'sa-east-1', + 'us-east-1','us-east-2', 'us-west-1', 'us-west-2'] + uses: ./.github/workflows/dotnet-eks-retry.yml + secrets: inherit + with: + aws-region: ${{ matrix.aws-region }} + test-cluster-name: 'e2e-dotnet-canary-test' + caller-workflow-name: 'appsignals-dotnet-e2e-eks-canary-test' \ No newline at end of file diff --git a/.github/workflows/dotnet-eks-retry.yml b/.github/workflows/dotnet-eks-retry.yml new file mode 100644 index 000000000..1da349702 --- /dev/null +++ b/.github/workflows/dotnet-eks-retry.yml @@ -0,0 +1,66 @@ +## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +## SPDX-License-Identifier: Apache-2.0 + +# This is a reusable workflow for running the Enablement test for App Signals. +# It is meant to be called from another workflow. +# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview +name: Dotnet EKS Retry +on: + workflow_call: + inputs: + aws-region: + required: true + type: string + test-cluster-name: + required: true + type: string + caller-workflow-name: + required: true + type: string + +concurrency: + group: 'dotnet-eks-${{ inputs.aws-region }}-${{ github.ref_name }}' + cancel-in-progress: false + +permissions: + id-token: write + contents: read + +jobs: + dotnet-eks-attempt-1: + uses: ./.github/workflows/dotnet-eks-test.yml + secrets: inherit + with: + aws-region: ${{ inputs.aws-region }} + test-cluster-name: ${{ inputs.test-cluster-name }} + caller-workflow-name: ${{ inputs.caller-workflow-name }} + + dotnet-eks-attempt-2: + needs: [ dotnet-eks-attempt-1 ] + if: ${{ needs.dotnet-eks-attempt-1.outputs.job-started != 'true' }} + uses: ./.github/workflows/dotnet-eks-test.yml + secrets: inherit + with: + aws-region: ${{ inputs.aws-region }} + test-cluster-name: ${{ inputs.test-cluster-name }} + caller-workflow-name: ${{ inputs.caller-workflow-name }} + + publish-metric-attempt-1: + needs: [ dotnet-eks-attempt-1, dotnet-eks-attempt-2 ] + if: always() + uses: ./.github/workflows/enablement-test-publish-result.yml + secrets: inherit + with: + aws-region: ${{ inputs.aws-region }} + caller-workflow-name: ${{ inputs.caller-workflow-name }} + validation-result: ${{ needs.dotnet-eks-attempt-1.outputs.validation-result || needs.dotnet-eks-attempt-2.outputs.validation-result }} + + publish-metric-attempt-2: + needs: [ dotnet-eks-attempt-1, dotnet-eks-attempt-2, publish-metric-attempt-1 ] + if: ${{ always() && needs.publish-metric-attempt-1.outputs.job-started != 'true' }} + uses: ./.github/workflows/enablement-test-publish-result.yml + secrets: inherit + with: + aws-region: ${{ inputs.aws-region }} + caller-workflow-name: ${{ inputs.caller-workflow-name }} + validation-result: ${{ needs.dotnet-eks-attempt-1.outputs.validation-result || needs.dotnet-eks-attempt-2.outputs.validation-result }} \ No newline at end of file diff --git a/.github/workflows/dotnet-eks-test.yml b/.github/workflows/dotnet-eks-test.yml new file mode 100644 index 000000000..26e20627d --- /dev/null +++ b/.github/workflows/dotnet-eks-test.yml @@ -0,0 +1,442 @@ +## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +## SPDX-License-Identifier: Apache-2.0 + +# This is a reusable workflow for running the Enablement test for Application Signals. +# It is meant to be called from another workflow. +# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview +name: DotNet EKS Use Case +on: + workflow_call: + inputs: + aws-region: + required: true + type: string + test-cluster-name: + required: true + type: string + adot-image-name: + required: false + type: string + cw-agent-operator-tag: + required: false + type: string + caller-workflow-name: + required: true + type: string + outputs: + job-started: + value: ${{ jobs.dotnet-eks.outputs.job-started }} + validation-result: + value: ${{ jobs.dotnet-eks.outputs.validation-result }} + +permissions: + id-token: write + contents: read + +env: + E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }} + E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} + E2E_TEST_AWS_REGION: ${{ inputs.aws-region }} + CLUSTER_NAME: ${{ inputs.test-cluster-name }} + METRIC_NAMESPACE: ApplicationSignals + LOG_GROUP_NAME: /aws/application-signals/data + TEST_RESOURCES_FOLDER: ${GITHUB_WORKSPACE} + ADOT_IMAGE_NAME: ${{ inputs.adot-image-name }} + CW_AGENT_OPERATOR_TAG: ${{ inputs.cw-agent-operator-tag }} + +jobs: + dotnet-eks: + runs-on: ubuntu-latest + timeout-minutes: 30 + outputs: + job-started: ${{ steps.job-started.outputs.job-started }} + validation-result: ${{ steps.validation-result.outputs.validation-result }} + steps: + - name: Check if the job started + id: job-started + run: echo "job-started=true" >> $GITHUB_OUTPUT + + - uses: actions/checkout@v4 + with: + repository: 'aws-observability/aws-application-signals-test-framework' + ref: ${{ inputs.caller-workflow-name == 'main-build' && 'main' || github.ref }} + fetch-depth: 0 + + - name: Initiate Gradlew Daemon + id: initiate-gradlew + uses: ./.github/workflows/actions/execute_and_retry + continue-on-error: true + with: + command: "./gradlew" + cleanup: "./gradlew clean" + max_retry: 3 + sleep_time: 60 + + - name: Download enablement script + uses: ./.github/workflows/actions/execute_and_retry + with: + pre-command: "mkdir enablement-script && cd enablement-script" + command: "wget https://raw.githubusercontent.com/aws-observability/application-signals-demo/main/scripts/eks/appsignals/enable-app-signals.sh + && wget https://raw.githubusercontent.com/aws-observability/application-signals-demo/main/scripts/eks/appsignals/clean-app-signals.sh" + cleanup: "rm -f enable-app-signals.sh && rm -f clean-app-signals.sh" + post-command: "chmod +x enable-app-signals.sh && chmod +x clean-app-signals.sh" + + - name: Remove log group deletion command + if: always() + working-directory: enablement-script + run: | + delete_log_group="aws logs delete-log-group --log-group-name '${{ env.LOG_GROUP_NAME }}' --region \$REGION" + sed -i "s#$delete_log_group##g" clean-app-signals.sh + + - name: Generate testing id and dotnet sample app namespace + run: | + echo TESTING_ID="${{ env.E2E_TEST_AWS_REGION }}-${{ github.run_id }}-${{ github.run_number }}" >> $GITHUB_ENV + echo DOTNET_SAMPLE_APP_NAMESPACE="ns-${{ github.run_id }}-${{ github.run_number }}" >> $GITHUB_ENV + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: us-east-1 + + - name: Retrieve account + uses: aws-actions/aws-secretsmanager-get-secrets@v1 + with: + secret-ids: | + ACCOUNT_ID, region-account/${{ env.E2E_TEST_AWS_REGION }} + DOTNET_MAIN_SAMPLE_APP_IMAGE, e2e-test/dotnet-main-sample-app-image + DOTNET_REMOTE_SAMPLE_APP_IMAGE, e2e-test/dotnet-remote-sample-app-image + + # ADOT_E2E_TEST_ROLE_ARN is used to access main build e2e test cluster + # E2E_TEST_ROLE_ARN is used to access canary e2e test cluster + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: ${{ env.E2E_TEST_AWS_REGION }} + + # local directory to store the kubernetes config + - name: Create kubeconfig directory + run: mkdir -p ${{ github.workspace }}/.kube + + - name: Set KUBECONFIG environment variable + run: echo KUBECONFIG="${{ github.workspace }}/.kube/config" >> $GITHUB_ENV + + - name: Set up kubeconfig + run: aws eks update-kubeconfig --name ${{ env.CLUSTER_NAME }} --region ${{ env.E2E_TEST_AWS_REGION }} + + - name: Download and install eksctl + uses: ./.github/workflows/actions/execute_and_retry + with: + pre-command: 'mkdir ${{ github.workspace }}/eksctl' + command: 'curl -sLO "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz" + && tar -xzf eksctl_Linux_amd64.tar.gz -C ${{ github.workspace }}/eksctl && rm eksctl_Linux_amd64.tar.gz' + cleanup: 'rm -f eksctl_Linux_amd64.tar.gz' + + - name: Add eksctl to Github Path + run: | + echo "${{ github.workspace }}/eksctl" >> $GITHUB_PATH + + # This step deletes lingering resources from previous test runs + - name: Delete all sample app namespaces + continue-on-error: true + timeout-minutes: 5 + run: kubectl get namespace | awk '/^ns-[0-9]+-[0-9]+/{print $1}' | xargs -r kubectl delete namespace + + - name: Create role for AWS access from the sample app + id: create_service_account + uses: ./.github/workflows/actions/execute_and_retry + with: + command: "eksctl create iamserviceaccount \ + --name service-account-${{ env.TESTING_ID }} \ + --namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} \ + --cluster ${{ inputs.test-cluster-name }} \ + --role-name eks-s3-access-${{ env.TESTING_ID }} \ + --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \ + --region ${{ env.E2E_TEST_AWS_REGION }} \ + --approve" + cleanup: "eksctl delete iamserviceaccount \ + --name service-account-${{ env.TESTING_ID }} \ + --namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} \ + --cluster ${{ inputs.test-cluster-name }} \ + --region ${{ env.E2E_TEST_AWS_REGION }}" + sleep_time: 60 + + - name: Set up terraform + uses: ./.github/workflows/actions/execute_and_retry + with: + command: "wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg" + post-command: 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list + && sudo apt update && sudo apt install terraform' + sleep_time: 60 + + - name: Initiate Terraform + uses: ./.github/workflows/actions/execute_and_retry + with: + command: "cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/dotnet/eks/linux && terraform init && terraform validate" + cleanup: "rm -rf .terraform && rm -rf .terraform.lock.hcl" + max_retry: 6 + sleep_time: 60 + + - name: Set Sample App Image + run: | + echo MAIN_SAMPLE_APP_IMAGE_ARN="${{ env.ACCOUNT_ID }}.dkr.ecr.${{ env.E2E_TEST_AWS_REGION }}.amazonaws.com/${{ env.DOTNET_MAIN_SAMPLE_APP_IMAGE }}" >> $GITHUB_ENV + echo REMOTE_SAMPLE_APP_IMAGE_ARN="${{ env.ACCOUNT_ID }}.dkr.ecr.${{ env.E2E_TEST_AWS_REGION }}.amazonaws.com/${{ env.DOTNET_REMOTE_SAMPLE_APP_IMAGE }}" >> $GITHUB_ENV + + - name: Deploy sample app via terraform and wait for the endpoint to come online + id: deploy-dotnet-app + working-directory: ./terraform/dotnet/eks/linux + run: | + # Attempt to deploy the sample app on an EKS instance and wait for its endpoint to come online. + # There may be occasional failures due to transitivity issues, so try up to 2 times. + # deployment_failed of 0 indicates that both the terraform deployment and the endpoint are running, while 1 indicates + # that it failed at some point + retry_counter=0 + max_retry=2 + while [ $retry_counter -lt $max_retry ]; do + echo "Attempt $retry_counter" + deployment_failed=0 + terraform apply -auto-approve \ + -var="test_id=${{ env.TESTING_ID }}" \ + -var="aws_region=${{ env.E2E_TEST_AWS_REGION }}" \ + -var="kube_directory_path=${{ github.workspace }}/.kube" \ + -var="eks_cluster_name=${{ env.CLUSTER_NAME }}" \ + -var="eks_cluster_context_name=$(kubectl config current-context)" \ + -var="test_namespace=${{ env.DOTNET_SAMPLE_APP_NAMESPACE }}" \ + -var="service_account_aws_access=service-account-${{ env.TESTING_ID }}" \ + -var="dotnet_app_image=${{ env.MAIN_SAMPLE_APP_IMAGE_ARN }}" \ + -var="dotnet_remote_app_image=${{ env.REMOTE_SAMPLE_APP_IMAGE_ARN }}" \ + -var='account_id=${{ env.ACCOUNT_ID }}' \ + || deployment_failed=$? + + if [ $deployment_failed -ne 0 ]; then + echo "Terraform deployment was unsuccessful. Will attempt to retry deployment." + fi + + # If the deployment_failed is still 0, then the terraform deployment succeeded and now try to connect to the endpoint + # after installing App Signals. Attempts to connect will be made for up to 10 minutes + if [ $deployment_failed -eq 0 ]; then + . ${{ env.TEST_RESOURCES_FOLDER }}/.github/workflows/util/execute_and_retry.sh + execute_and_retry 3 \ + "${{ env.TEST_RESOURCES_FOLDER }}/enablement-script/enable-app-signals.sh \ + ${{ env.CLUSTER_NAME }} \ + ${{ env.E2E_TEST_AWS_REGION }} \ + ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }}" \ + "${{ env.TEST_RESOURCES_FOLDER }}/enablement-script/clean-app-signals.sh \ + ${{ env.CLUSTER_NAME }} \ + ${{ env.E2E_TEST_AWS_REGION }} \ + ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} && \ + aws eks update-kubeconfig --name ${{ env.CLUSTER_NAME }} --region ${{ env.E2E_TEST_AWS_REGION }}" \ + 60 + + aws eks update-kubeconfig --region ${{ env.E2E_TEST_AWS_REGION }} --name ${{ env.CLUSTER_NAME }} + + execute_and_retry 2 "kubectl delete pods --all -n ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }}" "" 60 + execute_and_retry 2 "kubectl wait --for=condition=Ready --timeout=5m --request-timeout '5m' pod --all -n ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }}" "" 10 + fi + + # If the deployment_failed is 1 then either the terraform deployment or the endpoint connection failed, so first destroy the + # resources created from terraform and try again. + if [ $deployment_failed -eq 1 ]; then + echo "Cleaning up App Signal" + ${{ env.TEST_RESOURCES_FOLDER }}/enablement-script/clean-app-signals.sh \ + ${{ env.CLUSTER_NAME }} \ + ${{ env.E2E_TEST_AWS_REGION }} \ + ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + + # Running clean-app-signal.sh removes the current cluster from the config. Update the cluster again for subsequent runs. + aws eks update-kubeconfig --name ${{ env.CLUSTER_NAME }} --region ${{ env.E2E_TEST_AWS_REGION }} + + echo "Destroying terraform" + terraform destroy -auto-approve \ + -var="test_id=${{ env.TESTING_ID }}" \ + -var="aws_region=${{ env.E2E_TEST_AWS_REGION }}" \ + -var="kube_directory_path=${{ github.workspace }}/.kube" \ + -var="eks_cluster_name=${{ env.CLUSTER_NAME }}" \ + -var="eks_cluster_context_name=$(kubectl config current-context)" \ + -var="test_namespace=${{ env.DOTNET_SAMPLE_APP_NAMESPACE }}" \ + -var="service_account_aws_access=service-account-${{ env.TESTING_ID }}" \ + -var="dotnet_app_image=${{ env.MAIN_SAMPLE_APP_IMAGE_ARN }}" \ + -var="dotnet_remote_app_image=${{ env.REMOTE_SAMPLE_APP_IMAGE_ARN }}" + + retry_counter=$(($retry_counter+1)) + else + # If deployment succeeded, then exit the loop + break + fi + + if [ $retry_counter -ge $max_retry ]; then + echo "Max retry reached, failed to deploy terraform and connect to the endpoint. Exiting code" + exit 1 + fi + done + + - name: Get ECR to Patch + run: | + if [ "${{ github.event.repository.name }}" = "amazon-cloudwatch-agent" ]; then + echo PATCH_IMAGE_ARN="${{ secrets.AWS_ECR_PRIVATE_REGISTRY }}/cwagent-integration-test:${{ github.sha }}" >> $GITHUB_ENV + elif [ "${{ github.event.repository.name }}" = "amazon-cloudwatch-agent-operator" ]; then + echo PATCH_IMAGE_ARN="${{ vars.ECR_OPERATOR_STAGING_REPO }}:${{ env.CW_AGENT_OPERATOR_TAG }}" >> $GITHUB_ENV + elif [ "${{ github.event.repository.name }}" = "aws-otel-dotnet-instrumentation" ]; then + echo PATCH_IMAGE_ARN="${{ env.ADOT_IMAGE_NAME }}" >> $GITHUB_ENV + fi + + - name: Patch Image and Check Diff + id: patch-image + uses: ./.github/workflows/actions/patch_image_and_check_diff + with: + repository: ${{ github.event.repository.name }} + patch-image-arn: ${{ env.PATCH_IMAGE_ARN }} + sample-app-namespace: ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + + - name: Log Artifact Versions + run: | + echo "ADOT Image: Previous Version is: ${{ steps.patch-image.outputs.default-adot-image }}, Updated Version is: ${{ steps.patch-image.outputs.latest-adot-image }}"; + echo "CW Agent Image: Previous Version is: ${{ steps.patch-image.outputs.default-cw-agent-image }}, Updated Version is: ${{ steps.patch-image.outputs.latest-cw-agent-image }}"; + echo "CW Agent Operator Image: Previous Version is: ${{ steps.patch-image.outputs.default-cw-agent-operator-image }}, Updated Version is: ${{ steps.patch-image.outputs.latest-cw-agent-operator-image }}"; + echo "Fluent Bit Image: Version is: ${{ steps.patch-image.outputs.fluent-bit-image }}"; + + - name: Get Remote Service Deployment Name + uses: ./.github/workflows/actions/execute_and_retry + with: + command: echo "REMOTE_SERVICE_DEPLOYMENT_NAME=$(kubectl get deployments -n ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} --selector=app=remote-app -o jsonpath='{.items[0].metadata.name}')" >> $GITHUB_ENV + max_retry: 3 + sleep_time: 30 + + - name: Get Remote Service IP + uses: ./.github/workflows/actions/execute_and_retry + with: + command: echo "REMOTE_SERVICE_POD_IP=$(kubectl get pods -n ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} --selector=app=remote-app -o jsonpath='{.items[0].status.podIP}')" >> $GITHUB_ENV + max_retry: 3 + sleep_time: 30 + + - name: Get Sample App Endpoint + uses: ./.github/workflows/actions/execute_and_retry + with: + command: echo "APP_ENDPOINT=$(kubectl get pods -n ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} --selector=app=dotnet-app -o jsonpath='{.items[0].status.podIP}'):8080" >> $GITHUB_ENV + max_retry: 3 + sleep_time: 30 + + - name: Set endpoints for the traffic generator + uses: ./.github/workflows/actions/execute_and_retry + with: + command: kubectl set env -n ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} deployment/traffic-generator MAIN_ENDPOINT=${{ env.APP_ENDPOINT }} REMOTE_ENDPOINT=${{ env.REMOTE_SERVICE_POD_IP }} + max_retry: 3 + sleep_time: 30 + + - name: Initiate Gradlew Daemon + if: steps.initiate-gradlew == 'failure' + uses: ./.github/workflows/actions/execute_and_retry + continue-on-error: true + with: + command: "./gradlew" + cleanup: "./gradlew clean" + max_retry: 3 + sleep_time: 60 + + # Validation for application signals telemetry data + - name: Call endpoint and validate generated EMF logs + id: log-validation + if: steps.deploy-dotnet-app.outcome == 'success' && !cancelled() + run: ./gradlew validator:run --args='-c dotnet/eks/linux/log-validation.yml + --testing-id ${{ env.TESTING_ID }} + --endpoint http://${{ env.APP_ENDPOINT }} + --region ${{ env.E2E_TEST_AWS_REGION }} + --account-id ${{ env.ACCOUNT_ID }} + --metric-namespace ${{ env.METRIC_NAMESPACE }} + --log-group ${{ env.LOG_GROUP_NAME }} + --app-namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + --platform-info ${{ inputs.test-cluster-name }} + --service-name dotnet-application-${{ env.TESTING_ID }} + --remote-service-deployment-name ${{ env.REMOTE_SERVICE_DEPLOYMENT_NAME }} + --query-string ip=${{ env.REMOTE_SERVICE_POD_IP }}&testingId=${{ env.TESTING_ID }} + --rollup' + + - name: Call endpoints and validate generated metrics + id: metric-validation + if: (steps.deploy-dotnet-app.outcome == 'success' || steps.log-validation.outcome == 'failure') && !cancelled() + run: ./gradlew validator:run --args='-c dotnet/eks/linux/metric-validation.yml + --testing-id ${{ env.TESTING_ID }} + --endpoint http://${{ env.APP_ENDPOINT }} + --region ${{ env.E2E_TEST_AWS_REGION }} + --account-id ${{ env.ACCOUNT_ID }} + --metric-namespace ${{ env.METRIC_NAMESPACE }} + --log-group ${{ env.LOG_GROUP_NAME }} + --app-namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + --platform-info ${{ inputs.test-cluster-name }} + --service-name dotnet-application-${{ env.TESTING_ID }} + --remote-service-name dotnet-remote-application-${{ env.TESTING_ID }} + --remote-service-deployment-name ${{ env.REMOTE_SERVICE_DEPLOYMENT_NAME }} + --query-string ip=${{ env.REMOTE_SERVICE_POD_IP }}&testingId=${{ env.TESTING_ID }} + --rollup' + + - name: Call endpoints and validate generated traces + id: trace-validation + if: (steps.deploy-dotnet-app.outcome == 'success' || steps.log-validation.outcome == 'failure' || steps.metric-validation.outcome == 'failure') && !cancelled() + run: ./gradlew validator:run --args='-c dotnet/eks/linux/trace-validation.yml + --testing-id ${{ env.TESTING_ID }} + --endpoint http://${{ env.APP_ENDPOINT }} + --region ${{ env.E2E_TEST_AWS_REGION }} + --account-id ${{ env.ACCOUNT_ID }} + --log-group ${{ env.LOG_GROUP_NAME }} + --app-namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + --platform-info ${{ inputs.test-cluster-name }} + --service-name dotnet-application-${{ env.TESTING_ID }} + --remote-service-deployment-name ${{ env.REMOTE_SERVICE_DEPLOYMENT_NAME }} + --query-string ip=${{ env.REMOTE_SERVICE_POD_IP }}&testingId=${{ env.TESTING_ID }} + --rollup' + + - name: Save test results + if: always() + id: validation-result + run: | + if [ "${{ steps.log-validation.outcome }}" = "success" ] && [ "${{ steps.metric-validation.outcome }}" = "success" ] && [ "${{ steps.trace-validation.outcome }}" = "success" ]; then + echo "validation-result=success" >> $GITHUB_OUTPUT + else + echo "validation-result=failure" >> $GITHUB_OUTPUT + fi + + # Clean up Procedures + + - name: Clean Up Application Signals + if: always() + continue-on-error: true + working-directory: enablement-script + run: | + ./clean-app-signals.sh \ + ${{ inputs.test-cluster-name }} \ + ${{ env.E2E_TEST_AWS_REGION }} \ + ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + + # This step also deletes lingering resources from previous test runs + - name: Delete all sample app resources + if: always() + continue-on-error: true + timeout-minutes: 10 + run: kubectl delete namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} + + - name: Terraform destroy + if: always() + continue-on-error: true + timeout-minutes: 5 + working-directory: terraform/dotnet/eks/linux + run: | + terraform destroy -auto-approve \ + -var="test_id=${{ env.TESTING_ID }}" \ + -var="aws_region=${{ env.E2E_TEST_AWS_REGION }}" \ + -var="kube_directory_path=${{ github.workspace }}/.kube" \ + -var="eks_cluster_name=${{ inputs.test-cluster-name }}" \ + -var="test_namespace=${{ env.DOTNET_SAMPLE_APP_NAMESPACE }}" \ + -var="service_account_aws_access=service-account-${{ env.TESTING_ID }}" \ + -var="dotnet_app_image=${{ env.ACCOUNT_ID }}.dkr.ecr.${{ env.E2E_TEST_AWS_REGION }}.amazonaws.com/${{ secrets.APP_SIGNALS_DOTNET_E2E_FE_SA_IMG }}" \ + -var="dotnet_remote_app_image=${{ env.ACCOUNT_ID }}.dkr.ecr.${{ env.E2E_TEST_AWS_REGION }}.amazonaws.com/${{ secrets.APP_SIGNALS_DOTNET_E2E_RE_SA_IMG }}" + + - name: Remove aws access service account + if: always() + continue-on-error: true + run: | + eksctl delete iamserviceaccount \ + --name service-account-${{ env.TESTING_ID }} \ + --namespace ${{ env.DOTNET_SAMPLE_APP_NAMESPACE }} \ + --cluster ${{ inputs.test-cluster-name }} \ + --region ${{ env.E2E_TEST_AWS_REGION }} \ No newline at end of file diff --git a/terraform/dotnet/eks/linux/kubeconfig.tpl b/terraform/dotnet/eks/linux/kubeconfig.tpl new file mode 100644 index 000000000..a366b82cf --- /dev/null +++ b/terraform/dotnet/eks/linux/kubeconfig.tpl @@ -0,0 +1,19 @@ + +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: ${CA_DATA} + server: ${SERVER_ENDPOINT} + name: ${CLUSTER_NAME} +contexts: +- context: + cluster: ${CLUSTER_NAME} + user: terraform_user + name: ${CLUSTER_NAME} +current-context: ${CLUSTER_NAME} +kind: Config +preferences: {} +users: +- name: terraform_user + user: + token: ${TOKEN} \ No newline at end of file diff --git a/terraform/dotnet/eks/linux/main.tf b/terraform/dotnet/eks/linux/main.tf new file mode 100644 index 000000000..e441abc83 --- /dev/null +++ b/terraform/dotnet/eks/linux/main.tf @@ -0,0 +1,246 @@ +# ------------------------------------------------------------------------ +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# A copy of the License is located at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# or in the "license" file accompanying this file. This file 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. +# ------------------------------------------------------------------------- + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + } + + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.16.1" + } + + kubectl = { + source = "gavinbunney/kubectl" + version = ">= 1.7.0" + } + } +} + +provider "aws" { + region = var.aws_region +} + +# get eks cluster +data "aws_eks_cluster" "testing_cluster" { + name = var.eks_cluster_name +} +data "aws_eks_cluster_auth" "testing_cluster" { + name = var.eks_cluster_name +} + +# set up kubectl +provider "kubernetes" { + host = data.aws_eks_cluster.testing_cluster.endpoint + cluster_ca_certificate = base64decode(data.aws_eks_cluster.testing_cluster.certificate_authority[0].data) + token = data.aws_eks_cluster_auth.testing_cluster.token +} + +provider "kubectl" { + // Note: copy from eks module. Please avoid use shorted-lived tokens when running locally. + // For more information: https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#exec-plugins + host = data.aws_eks_cluster.testing_cluster.endpoint + cluster_ca_certificate = base64decode(data.aws_eks_cluster.testing_cluster.certificate_authority[0].data) + token = data.aws_eks_cluster_auth.testing_cluster.token + load_config_file = false +} + +data "template_file" "kubeconfig_file" { + template = file("./kubeconfig.tpl") + vars = { + CLUSTER_NAME : var.eks_cluster_context_name + CA_DATA : data.aws_eks_cluster.testing_cluster.certificate_authority[0].data + SERVER_ENDPOINT : data.aws_eks_cluster.testing_cluster.endpoint + TOKEN = data.aws_eks_cluster_auth.testing_cluster.token + } +} + +resource "local_file" "kubeconfig" { + content = data.template_file.kubeconfig_file.rendered + filename = "${var.kube_directory_path}/config" +} + +### Setting up the sample app on the cluster + +resource "kubernetes_deployment" "dotnet_app_deployment" { + + metadata { + name = "dotnet-app-deployment-${var.test_id}" + namespace = var.test_namespace + labels = { + app = "dotnet-app" + } + } + + spec { + replicas = 1 + selector { + match_labels = { + app = "dotnet-app" + } + } + template { + metadata { + labels = { + app = "dotnet-app" + } + annotations = { + # these annotations allow for OTel Dotnet instrumentation + "instrumentation.opentelemetry.io/inject-dotnet": "true" + } + } + spec { + service_account_name = var.service_account_aws_access + container { + name = "back-end" + image = var.dotnet_app_image + image_pull_policy = "Always" + env { + #inject the test id to service name for unique App Signals metrics + name = "OTEL_SERVICE_NAME" + value = "dotnet-application-${var.test_id}" + } + port { + container_port = 8080 + } + } + } + } + } +} + +resource "kubernetes_service" "dotnet_app_service" { + depends_on = [ kubernetes_deployment.dotnet_app_deployment ] + + metadata { + name = "dotnet-app-service" + namespace = var.test_namespace + } + spec { + type = "NodePort" + selector = { + app = "dotnet-app" + } + port { + protocol = "TCP" + port = 8080 + target_port = 8080 + node_port = 30100 + } + } +} + +# Set up the remote service + +resource "kubernetes_deployment" "dotnet_r_app_deployment" { + + metadata { + name = "dotnet-r-app-deployment-${var.test_id}" + namespace = var.test_namespace + labels = { + app = "remote-app" + } + } + + spec { + replicas = 1 + selector { + match_labels = { + app = "remote-app" + } + } + template { + metadata { + labels = { + app = "remote-app" + } + annotations = { + # these annotations allow for OTel Dotnet instrumentation + "instrumentation.opentelemetry.io/inject-dotnet" = "true" + } + } + spec { + service_account_name = var.service_account_aws_access + container { + name = "back-end" + image = var.dotnet_remote_app_image + image_pull_policy = "Always" + port { + container_port = 8081 + } + } + } + } + } +} + +resource "kubernetes_service" "dotnet_r_app_service" { + depends_on = [ kubernetes_deployment.dotnet_r_app_deployment ] + + metadata { + name = "dotnet-r-app-service" + namespace = var.test_namespace + } + spec { + type = "NodePort" + selector = { + app = "remote-app" + } + port { + protocol = "TCP" + port = 8081 + target_port = 8081 + node_port = 30101 + } + } +} + +resource "kubernetes_deployment" "traffic_generator" { + metadata { + name = "traffic-generator" + namespace = var.test_namespace + labels = { + app = "traffic-generator" + } + } + spec { + replicas = 1 + selector { + match_labels = { + app = "traffic-generator" + } + } + template { + metadata { + labels = { + app = "traffic-generator" + } + } + spec { + container { + name = "traffic-generator" + image = "${var.account_id}.dkr.ecr.${var.aws_region}.amazonaws.com/e2e-test-resource:traffic-generator" + image_pull_policy = "Always" + env { + name = "ID" + value = var.test_id + } + } + } + } + } +} diff --git a/terraform/dotnet/eks/linux/variables.tf b/terraform/dotnet/eks/linux/variables.tf new file mode 100644 index 000000000..dec01b9c7 --- /dev/null +++ b/terraform/dotnet/eks/linux/variables.tf @@ -0,0 +1,54 @@ +# ------------------------------------------------------------------------ +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# A copy of the License is located at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# or in the "license" file accompanying this file. This file 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. +# ------------------------------------------------------------------------- + +variable "test_id" { + default = "dummy-123" +} + +variable "kube_directory_path" { + default = "./.kube" +} + +variable "aws_region" { + default = "" +} + +variable "eks_cluster_name" { + default = "" +} + +variable "eks_cluster_context_name" { + default = "." +} + +variable "test_namespace" { + default = "dotnet-app-namespace" +} + +variable "service_account_aws_access" { + default = "dotnet-app-service-account" +} + +variable "dotnet_app_image" { + default = ":" +} + +variable "dotnet_remote_app_image" { + default = ":" +} + +variable "account_id" { + default = "" +} \ No newline at end of file diff --git a/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java b/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java index a9647f9dd..1d2fdb2b3 100644 --- a/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java +++ b/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java @@ -210,6 +210,24 @@ public enum PredefinedExpectedTemplate implements FileConfig { DOTNET_EC2_ASG_CLIENT_CALL_LOG("/expected-data-template/dotnet/ec2/asg/client-call-log.mustache"), DOTNET_EC2_ASG_CLIENT_CALL_METRIC("/expected-data-template/dotnet/ec2/asg/client-call-metric.mustache"), DOTNET_EC2_ASG_CLIENT_CALL_TRACE("/expected-data-template/dotnet/ec2/asg/client-call-trace.mustache"), + + /** DotNet EKS Linux Test Case Validations */ + DOTNET_EKS_LINUX_OUTGOING_HTTP_CALL_LOG("/expected-data-template/dotnet/eks/linux/outgoing-http-call-log.mustache"), + DOTNET_EKS_LINUX_OUTGOING_HTTP_CALL_METRIC("/expected-data-template/dotnet/eks/linux/outgoing-http-call-metric.mustache"), + DOTNET_EKS_LINUX_OUTGOING_HTTP_CALL_TRACE("/expected-data-template/dotnet/eks/linux/outgoing-http-call-trace.mustache"), + + DOTNET_EKS_LINUX_AWS_SDK_CALL_LOG("/expected-data-template/dotnet/eks/linux/aws-sdk-call-log.mustache"), + DOTNET_EKS_LINUX_AWS_SDK_CALL_METRIC("/expected-data-template/dotnet/eks/linux/aws-sdk-call-metric.mustache"), + DOTNET_EKS_LINUX_AWS_SDK_CALL_TRACE("/expected-data-template/dotnet/eks/linux/aws-sdk-call-trace.mustache"), + + DOTNET_EKS_LINUX_REMOTE_SERVICE_LOG("/expected-data-template/dotnet/eks/linux/remote-service-log.mustache"), + DOTNET_EKS_LINUX_REMOTE_SERVICE_METRIC("/expected-data-template/dotnet/eks/linux/remote-service-metric.mustache"), + DOTNET_EKS_LINUX_REMOTE_SERVICE_TRACE("/expected-data-template/dotnet/eks/linux/remote-service-trace.mustache"), + + DOTNET_EKS_LINUX_CLIENT_CALL_LOG("/expected-data-template/dotnet/eks/linux/client-call-log.mustache"), + DOTNET_EKS_LINUX_CLIENT_CALL_METRIC("/expected-data-template/dotnet/eks/linux/client-call-metric.mustache"), + DOTNET_EKS_LINUX_CLIENT_CALL_TRACE("/expected-data-template/dotnet/eks/linux/client-call-trace.mustache"), + /** Node EC2 Default Test Case Validations */ NODE_EC2_DEFAULT_OUTGOING_HTTP_CALL_LOG("/expected-data-template/node/ec2/default/outgoing-http-call-log.mustache"), NODE_EC2_DEFAULT_OUTGOING_HTTP_CALL_METRIC("/expected-data-template/node/ec2/default/outgoing-http-call-metric.mustache"), diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-log.mustache new file mode 100644 index 000000000..ece6a4816 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-log.mustache @@ -0,0 +1,34 @@ +[{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "GET /aws-sdk-call", + "Version": "^1$", + "Telemetry.Source": "^LocalRootSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}, +{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "GET /aws-sdk-call", + "Version": "^1$", + "RemoteService": "AWS::S3", + "RemoteOperation": "GetBucketLocation", + "Telemetry.Source": "^ClientSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-metric.mustache new file mode 100644 index 000000000..740415ee0 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-metric.mustache @@ -0,0 +1,375 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: AWS::S3 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + - + name: RemoteResourceType + value: AWS::S3::Bucket + - + name: RemoteResourceIdentifier + value: {{testingId}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + - + name: RemoteResourceType + value: AWS::S3::Bucket + - + name: RemoteResourceIdentifier + value: {{testingId}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: AWS::S3 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + - + name: RemoteResourceType + value: AWS::S3::Bucket + - + name: RemoteResourceIdentifier + value: {{testingId}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + - + name: RemoteResourceType + value: AWS::S3::Bucket + - + name: RemoteResourceIdentifier + value: {{testingId}} + + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: AWS::S3 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + - + name: RemoteResourceType + value: AWS::S3::Bucket + - + name: RemoteResourceIdentifier + value: {{testingId}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + - + name: RemoteResourceType + value: AWS::S3::Bucket + - + name: RemoteResourceIdentifier + value: {{testingId}} \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-trace.mustache new file mode 100644 index 000000000..f02320fee --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/aws-sdk-call-trace.mustache @@ -0,0 +1,60 @@ +[{ + "name": "^{{serviceName}}$", + "http": { + "request": { + "url": "^{{endpoint}}/aws-sdk-call$", + "method": "^GET$" + } + }, + "aws": { + "account_id": "^{{accountId}}$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET /aws-sdk-call$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}", + "otel.resource.K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "otel.resource.K8s.Node": "^i-[A-Za-z0-9]{17}$", + "otel.resource.K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "otel.resource.host.name": "^ip(-[0-9]{1,3}){4}.*$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^LOCAL_ROOT$" + } + }, + "subsegments": [ + { + "name": "^S3$", + "aws": { + "region": "{{region}}", + "operation": "^GetBucketLocation$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET /aws-sdk-call$", + "aws.remote.service": "^AWS::S3$", + "aws.remote.operation": "^GetBucketLocation$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "aws.remote.resource.type": "AWS::S3::Bucket" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^CLIENT$" + } + }, + "namespace": "^aws$" + } + ] +}, +{ + "name": "^S3$" +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-log.mustache new file mode 100644 index 000000000..f5b85031e --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-log.mustache @@ -0,0 +1,34 @@ +[{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "InternalOperation", + "Version": "^1$", + "Telemetry.Source": "^LocalRootSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}, +{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "InternalOperation", + "Version": "^1$", + "RemoteService": "local-root-client-call:80", + "RemoteOperation": "GET /", + "Telemetry.Source": "^ClientSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-metric.mustache new file mode 100644 index 000000000..6c8a65eab --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-metric.mustache @@ -0,0 +1,269 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: GET /client-call + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: GET /client-call + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: GET /client-call + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: local-root-client-call:80 \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-trace.mustache new file mode 100644 index 000000000..25a8b184d --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/client-call-trace.mustache @@ -0,0 +1,60 @@ +[{ + "name": "^{{serviceName}}$", + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^InternalOperation$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "otel.resource.K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "otel.resource.K8s.Node": "^i-[A-Za-z0-9]{17}$", + "otel.resource.K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "otel.resource.host.name": "^ip(-[0-9]{1,3}){4}.*$" + } + }, + "subsegments": [ + { + "name": "^local-root-client-call:80$", + "http": { + "request": { + "url": "^http://local-root-client-call/$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^InternalOperation$", + "aws.remote.service": "^local-root-client-call:80$", + "aws.remote.operation": "GET /", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^LOCAL_ROOT$" + } + }, + "namespace": "^remote$" + } + ] +}, +{ + "name": "^local-root-client-call:80$", + "http": { + "request": { + "url": "^http://local-root-client-call/$", + "method": "^GET$" + }, + "response": { + "content_length": 0 + } + }, + "annotations": { + "aws.local.service": "^local-root-client-call:80$", + "aws.local.operation": "^GET /$" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-log.mustache new file mode 100644 index 000000000..65c5bb307 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-log.mustache @@ -0,0 +1,35 @@ +[{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "GET /outgoing-http-call", + "Version": "^1$", + "Telemetry.Source": "^LocalRootSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}, +{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "GET /outgoing-http-call", + "Version": "^1$", + "RemoteService": "aws.amazon.com:443", + "RemoteOperation": "GET /", + "Telemetry.Source": "^ClientSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}] + diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-metric.mustache new file mode 100644 index 000000000..6a3ac4242 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-metric.mustache @@ -0,0 +1,227 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: aws.amazon.com:443 \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-trace.mustache new file mode 100644 index 000000000..b4d22c545 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/outgoing-http-call-trace.mustache @@ -0,0 +1,61 @@ +[{ + "name": "^{{serviceName}}$", + "http": { + "request": { + "url": "^{{endpoint}}/outgoing-http-call$", + "method": "^GET$" + } + }, + "aws": { + "account_id": "^{{accountId}}$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET /outgoing-http-call$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}", + "otel.resource.K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "otel.resource.K8s.Node": "^i-[A-Za-z0-9]{17}$", + "otel.resource.K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "otel.resource.host.name": "^ip(-[0-9]{1,3}){4}.*$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^LOCAL_ROOT$" + } + }, + "subsegments": [ + { + "name": "^aws.amazon.com:443$", + "http": { + "request": { + "url": "^https://aws.amazon.com/$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET /outgoing-http-call$", + "aws.remote.service": "^aws.amazon.com:443$", + "aws.remote.operation": "^GET /$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^CLIENT$" + } + }, + "namespace": "^remote$" + } + ] +}, +{ + "name": "^aws.amazon.com:443$" +}] diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-log.mustache new file mode 100644 index 000000000..d32e68b4b --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-log.mustache @@ -0,0 +1,35 @@ +[{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "GET /remote-service", + "Version": "^1$", + "Telemetry.Source": "^LocalRootSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}, +{ + "EC2.AutoScalingGroup": "^eks-.+", + "EC2.InstanceId": "^i-[A-Za-z0-9]{17}$", + "EKS.Cluster": "^{{platformInfo}}$", + "Environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "RemoteEnvironment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "K8s.Node": "^i-[A-Za-z0-9]{17}$", + "K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "PlatformType": "^AWS::EKS$", + "Service": "^{{serviceName}}$", + "Operation": "GET /remote-service", + "Version": "^1$", + "RemoteService": "{{remoteServiceDeploymentName}}", + "RemoteOperation": "GET /healthcheck", + "Telemetry.Source": "^ClientSpan$", + "Host": "^ip(-[0-9]{1,3}){4}.*$" +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-metric.mustache new file mode 100644 index 000000000..928652d25 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-metric.mustache @@ -0,0 +1,506 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: Operation + value: GET /healthcheck + - + name: Service + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{remoteServiceDeploymentName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: Operation + value: GET /remote-service + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: Operation + value: GET /healthcheck + - + name: Service + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{remoteServiceDeploymentName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: Operation + value: GET /remote-service + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET /remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: Operation + value: GET /healthcheck + - + name: Service + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{remoteServiceDeploymentName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: RemoteEnvironment + value: eks:{{platformInfo}}/{{appNamespace}} + - + name: Operation + value: GET /remote-service + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + - + name: Service + value: {{serviceName}} \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-trace.mustache new file mode 100644 index 000000000..c42b164cf --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/eks/linux/remote-service-trace.mustache @@ -0,0 +1,83 @@ +[{ + "name": "^{{serviceName}}$", + "http": { + "request": { + "url": "^{{endpoint}}/remote-service$", + "method": "^GET$" + } + }, + "aws": { + "account_id": "^{{accountId}}$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET /remote-service$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}", + "otel.resource.K8s.Workload": "^dotnet-app-deployment-{{testingId}}$", + "otel.resource.K8s.Node": "^i-[A-Za-z0-9]{17}$", + "otel.resource.K8s.Pod": "^dotnet-app-deployment-{{testingId}}(-[A-Za-z0-9]*)*$", + "otel.resource.host.name": "^ip(-[0-9]{1,3}){4}.*$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^LOCAL_ROOT$" + } + }, + "subsegments": [ + { + "name": "^{{remoteServiceDeploymentName}}$", + "http": { + "request": { + "url": "^http://(([0-9]{1,3}.){3}[0-9]{1,3}):8081/healthcheck$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET /remote-service$", + "aws.remote.service": "^{{remoteServiceDeploymentName}}$", + "aws.remote.operation": "^GET /healthcheck$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$", + "aws.remote.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "EC2.AutoScalingGroup": "^eks-.+", + "EKS.Cluster": "^{{platformInfo}}$", + "K8s.Namespace": "^{{appNamespace}}$", + "PlatformType": "^AWS::EKS$", + "aws.span.kind": "^CLIENT$" + } + }, + "namespace": "^remote$" + } + ] +}, +{ + "name": "^{{remoteServiceDeploymentName}}$", + "http": { + "request": { + "url": "^http://(([0-9]{1,3}.){3}[0-9]{1,3}):8081/healthcheck$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{remoteServiceDeploymentName}}$", + "aws.local.operation": "^GET /healthcheck$", + "aws.local.environment": "^eks:{{platformInfo}}/{{appNamespace}}$" + }, + "metadata": { + "default": { + "otel.resource.K8s.Workload": "^{{remoteServiceDeploymentName}}$", + "otel.resource.K8s.Node": "^i-[A-Za-z0-9]{17}$", + "otel.resource.K8s.Pod": "^{{remoteServiceDeploymentName}}(-[A-Za-z0-9]*)*$", + "aws.span.kind": "^LOCAL_ROOT$" + } + } +}] + + diff --git a/validator/src/main/resources/validations/dotnet/eks/linux/log-validation.yml b/validator/src/main/resources/validations/dotnet/eks/linux/log-validation.yml new file mode 100644 index 000000000..6084d95f5 --- /dev/null +++ b/validator/src/main/resources/validations/dotnet/eks/linux/log-validation.yml @@ -0,0 +1,24 @@ +- + validationType: "cw-log" + httpPath: "/outgoing-http-call" + httpMethod: "get" + callingType: "http" + expectedLogStructureTemplate: "DOTNET_EKS_LINUX_OUTGOING_HTTP_CALL_LOG" +- + validationType: "cw-log" + httpPath: "/aws-sdk-call" + httpMethod: "get" + callingType: "http-with-query" + expectedLogStructureTemplate: "DOTNET_EKS_LINUX_AWS_SDK_CALL_LOG" +- + validationType: "cw-log" + httpPath: "/remote-service" + httpMethod: "get" + callingType: "http-with-query" + expectedLogStructureTemplate: "DOTNET_EKS_LINUX_REMOTE_SERVICE_LOG" +- + validationType: "cw-log" + httpPath: "/client-call" + httpMethod: "get" + callingType: "http" + expectedLogStructureTemplate: "DOTNET_EKS_LINUX_CLIENT_CALL_LOG" \ No newline at end of file diff --git a/validator/src/main/resources/validations/dotnet/eks/linux/metric-validation.yml b/validator/src/main/resources/validations/dotnet/eks/linux/metric-validation.yml new file mode 100644 index 000000000..cee097e0d --- /dev/null +++ b/validator/src/main/resources/validations/dotnet/eks/linux/metric-validation.yml @@ -0,0 +1,24 @@ +- + validationType: "cw-metric" + httpPath: "/outgoing-http-call" + httpMethod: "get" + callingType: "http" + expectedMetricTemplate: "DOTNET_EKS_LINUX_OUTGOING_HTTP_CALL_METRIC" +- + validationType: "cw-metric" + httpPath: "/aws-sdk-call" + httpMethod: "get" + callingType: "http-with-query" + expectedMetricTemplate: "DOTNET_EKS_LINUX_AWS_SDK_CALL_METRIC" +- + validationType: "cw-metric" + httpPath: "/remote-service" + httpMethod: "get" + callingType: "http-with-query" + expectedMetricTemplate: "DOTNET_EKS_LINUX_REMOTE_SERVICE_METRIC" +- + validationType: "cw-metric" + httpPath: "/client-call" + httpMethod: "get" + callingType: "http" + expectedMetricTemplate: "DOTNET_EKS_LINUX_CLIENT_CALL_METRIC" diff --git a/validator/src/main/resources/validations/dotnet/eks/linux/trace-validation.yml b/validator/src/main/resources/validations/dotnet/eks/linux/trace-validation.yml new file mode 100644 index 000000000..07e7429a6 --- /dev/null +++ b/validator/src/main/resources/validations/dotnet/eks/linux/trace-validation.yml @@ -0,0 +1,24 @@ +- + validationType: "trace" + httpPath: "/outgoing-http-call" + httpMethod: "get" + callingType: "http" + expectedTraceTemplate: "DOTNET_EKS_LINUX_OUTGOING_HTTP_CALL_TRACE" +- + validationType: "trace" + httpPath: "/aws-sdk-call" + httpMethod: "get" + callingType: "http-with-query" + expectedTraceTemplate: "DOTNET_EKS_LINUX_AWS_SDK_CALL_TRACE" +- + validationType: "trace" + httpPath: "/remote-service" + httpMethod: "get" + callingType: "http-with-query" + expectedTraceTemplate: "DOTNET_EKS_LINUX_REMOTE_SERVICE_TRACE" +- + validationType: "trace" + httpPath: "/client-call" + httpMethod: "get" + callingType: "http" + expectedTraceTemplate: "DOTNET_EKS_LINUX_CLIENT_CALL_TRACE" \ No newline at end of file