diff --git a/.pipelines/azure-pipeline-config-tests.yml b/.pipelines/azure-pipeline-config-tests.yml new file mode 100644 index 00000000..979760d1 --- /dev/null +++ b/.pipelines/azure-pipeline-config-tests.yml @@ -0,0 +1,1006 @@ +trigger: + branches: + include: + - rashmi/config-tests +# pr: +# autoCancel: true +# branches: +# include: +# - main + +variables: + HELM_CHART_NAME: 'prometheus-collector' + ARC_HELM_CHART_NAME: 'ama-metrics-arc' + ACR_REGISTRY: 'containerinsightsprod.azurecr.io' + ACR_REPOSITORY: '/public/azuremonitor/containerinsights/cidev/prometheus-collector/images' + ACR_REPOSITORY_HELM: '/public/azuremonitor/containerinsights/cidev' + MCR_REGISTRY: 'mcr.microsoft.com' + MCR_REPOSITORY: '/azuremonitor/containerinsights/cidev/prometheus-collector/images' + MCR_REPOSITORY_HELM: '/azuremonitor/containerinsights/cidev/prometheus-collector' + MCR_REPOSITORY_HELM_DEPENDENCIES: '/azuremonitor/containerinsights/cidev' + KUBE_STATE_METRICS_IMAGE: 'mcr.microsoft.com/oss/kubernetes/kube-state-metrics:v2.12.0' + NODE_EXPORTER_IMAGE: 'mcr.microsoft.com/oss/prometheus/node-exporter:v1.6.0' + IS_PR: $[eq(variables['Build.Reason'], 'PullRequest')] + IS_MAIN_BRANCH: $[eq(variables['Build.SourceBranchName'], 'main')] + BUILD_WINDOWS: true + Codeql.Enabled: true + GOLANG_VERSION: '1.22.7' + +stages: +- stage: Build + jobs: + - job: Image_Tags_and_Ev2_Artifacts + displayName: "Build: Set image tags and publish Ev2 artifacts" + pool: + name: Azure-Pipelines-CI-Test-EO + variables: + skipComponentGovernanceDetection: true + steps: + - checkout: self + submodules: true + - bash: | + if [ $(IS_PR) == "True" ]; then + BRANCH_NAME=$(System.PullRequest.SourceBranch) + else + BRANCH_NAME=$(Build.SourceBranch) + BRANCH_NAME=${BRANCH_NAME#refs/heads/} + fi + BRANCH_NAME=$(echo $BRANCH_NAME | tr / - | tr . - | tr _ - | cut -c1-90) + COMMIT_SHA=$(echo $(Build.SourceVersion) | cut -b -8) + DATE=$(TZ=America/Los_Angeles date +%m-%d-%Y) + VERSION=$(cat $(Build.SourcesDirectory)/otelcollector/VERSION) + SEMVER=$VERSION-$BRANCH_NAME-$DATE-$COMMIT_SHA + + LINUX_IMAGE_TAG=$SEMVER + # Truncating to 128 characters as it is required by docker + LINUX_IMAGE_TAG=$(echo "${LINUX_IMAGE_TAG}" | cut -c1-128) + + #Truncating this to 124 to add the cfg suffix + LINUX_IMAGE_TAG_PREFIX=$(echo "${LINUX_IMAGE_TAG}" | cut -c1-124) + LINUX_CONFIG_READER_IMAGE_TAG=$LINUX_IMAGE_TAG_PREFIX-cfg + LINUX_CCP_IMAGE_TAG=$LINUX_IMAGE_TAG_PREFIX-ccp + LINUX_CCP_IMAGE_TAG=$LINUX_IMAGE_TAG_PREFIX-ccp + + #Truncating this to 113 to add the ref app suffices + LINUX_REF_APP_IMAGE_TAG_PREFIX=$(echo "${LINUX_IMAGE_TAG}" | cut -c1-113) + LINUX_REF_APP_GOLANG_IMAGE_TAG=$LINUX_REF_APP_IMAGE_TAG_PREFIX-ref-app-golang + LINUX_REF_APP_PYTHON_IMAGE_TAG=$LINUX_REF_APP_IMAGE_TAG_PREFIX-ref-app-python + + # Truncating to 115 characters as it is required by docker (4 characters used in -win and 9 characters used in -ltsc2019/-ltsc2022) + WINDOWS_IMAGE_TAG_PREFIX=$(echo "${LINUX_IMAGE_TAG}" | cut -c1-115) + WINDOWS_IMAGE_TAG=$WINDOWS_IMAGE_TAG_PREFIX-win + + + #Truncating this to 112 characters to add the targetallocator suffix + TARGET_ALLOCATOR_IMAGE_TAG_PREFIX=$(echo "${LINUX_IMAGE_TAG}" | cut -c1-112) + TARGET_ALLOCATOR_IMAGE_TAG=$TARGET_ALLOCATOR_IMAGE_TAG_PREFIX-targetallocator + + #Truncating this to 113 to add the ref app suffices + WIN_REF_APP_IMAGE_TAG_PREFIX=$(echo "${LINUX_IMAGE_TAG}" | cut -c1-107) + WIN_REF_APP_GOLANG_IMAGE_TAG=$WIN_REF_APP_IMAGE_TAG_PREFIX-win-ref-app-golang + WIN_REF_APP_PYTHON_IMAGE_TAG=$WIN_REF_APP_IMAGE_TAG_PREFIX-win-ref-app-python + + # Truncating to 119 characters as it is required by docker (9 characters used in -ltsc2019/-ltsc2022) + WINDOWS_2019_BASE_IMAGE_VERSION=ltsc2019 + WINDOWS_2022_BASE_IMAGE_VERSION=ltsc2022 + + LINUX_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$LINUX_IMAGE_TAG + TARGET_ALLOCATOR_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$TARGET_ALLOCATOR_IMAGE_TAG + LINUX_CONFIG_READER_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$LINUX_CONFIG_READER_IMAGE_TAG + LINUX_CCP_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$LINUX_CCP_IMAGE_TAG + WINDOWS_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$WINDOWS_IMAGE_TAG + HELM_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY_HELM/$HELM_CHART_NAME:$SEMVER + ARC_HELM_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY_HELM/$ARC_HELM_CHART_NAME:$SEMVER + LINUX_REF_APP_GOLANG_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$LINUX_REF_APP_GOLANG_IMAGE_TAG + LINUX_REF_APP_PYTHON_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$LINUX_REF_APP_PYTHON_IMAGE_TAG + WINDOWS_REF_APP_GOLANG_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$WIN_REF_APP_GOLANG_IMAGE_TAG + WINDOWS_REF_APP_PYTHON_FULL_IMAGE_NAME=$ACR_REGISTRY$ACR_REPOSITORY:$WIN_REF_APP_PYTHON_IMAGE_TAG + + echo "##vso[build.updatebuildnumber]$SEMVER" + echo "##vso[task.setvariable variable=SEMVER;isOutput=true]$SEMVER" + echo "##vso[task.setvariable variable=LINUX_FULL_IMAGE_NAME;isOutput=true]$LINUX_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=TARGET_ALLOCATOR_IMAGE_TAG;isOutput=true]$TARGET_ALLOCATOR_IMAGE_TAG" + echo "##vso[task.setvariable variable=LINUX_CONFIG_READER_IMAGE_TAG;isOutput=true]$LINUX_CONFIG_READER_IMAGE_TAG" + echo "##vso[task.setvariable variable=TARGET_ALLOCATOR_FULL_IMAGE_NAME;isOutput=true]$TARGET_ALLOCATOR_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=LINUX_CONFIG_READER_FULL_IMAGE_NAME;isOutput=true]$LINUX_CONFIG_READER_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=LINUX_CCP_FULL_IMAGE_NAME;isOutput=true]$LINUX_CCP_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=WINDOWS_FULL_IMAGE_NAME;isOutput=true]$WINDOWS_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=LINUX_REF_APP_GOLANG_FULL_IMAGE_NAME;isOutput=true]$LINUX_REF_APP_GOLANG_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=LINUX_REF_APP_PYTHON_FULL_IMAGE_NAME;isOutput=true]$LINUX_REF_APP_PYTHON_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=WINDOWS_REF_APP_GOLANG_FULL_IMAGE_NAME;isOutput=true]$WINDOWS_REF_APP_GOLANG_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=WINDOWS_REF_APP_PYTHON_FULL_IMAGE_NAME;isOutput=true]$WINDOWS_REF_APP_PYTHON_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=WINDOWS_IMAGE_TAG;isOutput=true]$WINDOWS_IMAGE_TAG" + echo "##vso[task.setvariable variable=WINDOWS_2019_BASE_IMAGE_VERSION;isOutput=true]$WINDOWS_2019_BASE_IMAGE_VERSION" + echo "##vso[task.setvariable variable=WINDOWS_2022_BASE_IMAGE_VERSION;isOutput=true]$WINDOWS_2022_BASE_IMAGE_VERSION" + echo "##vso[task.setvariable variable=HELM_CHART_NAME;isOutput=true]$HELM_CHART_NAME" + echo "##vso[task.setvariable variable=ARC_HELM_CHART_NAME;isOutput=true]$ARC_HELM_CHART_NAME" + echo "##vso[task.setvariable variable=HELM_FULL_IMAGE_NAME;isOutput=true]$HELM_FULL_IMAGE_NAME" + echo "##vso[task.setvariable variable=ARC_HELM_FULL_IMAGE_NAME;isOutput=true]$ARC_HELM_FULL_IMAGE_NAME" + displayName: 'Build: set image registry, repo, and tags' + name: setup + + - bash: | + cd $(Build.SourcesDirectory)/.pipelines/deployment/ServiceGroupRoot/Scripts + cp ../../../../otelcollector/deploy/chart/prometheus-collector prometheus-collector -r + cp ../../../../otelcollector/deploy/addon-chart/azure-monitor-metrics-addon ama-metrics-arc -r + export MCR_REPOSITORY='/azuremonitor/containerinsights/ciprod/prometheus-collector/images' + export MCR_REPOSITORY_HELM_DEPENDENCIES='/azuremonitor/containerinsights/ciprod' + export HELM_SEMVER=$SETUP_SEMVER + export IMAGE_TAG=$SETUP_SEMVER + export IMAGE_TAG_WINDOWS=$SETUP_WINDOWS_IMAGE_TAG + env + + envsubst < prometheus-collector/Chart-template.yaml > prometheus-collector/Chart.yaml && envsubst < prometheus-collector/values-template.yaml > prometheus-collector/values.yaml + export ARC_EXTENSION=true + export HELM_CHART_NAME=$ARC_HELM_CHART_NAME + envsubst < ama-metrics-arc/Chart-template.yaml > ama-metrics-arc/Chart.yaml && envsubst < ama-metrics-arc/values-template.yaml > ama-metrics-arc/values.yaml + tar -czvf ../artifacts.tar.gz pushAgentToAcr.sh pushChartToAcr.sh prometheus-collector ama-metrics-arc + + cd $(Build.ArtifactStagingDirectory) + cp $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon azure-monitor-metrics-addon -r + export HELM_CHART_NAME="ama-metrics" + export ARC_EXTENSION=false + export AKS_REGION="westeurope" + export AKS_RESOURCE_ID="/subscriptions/9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb/resourceGroups/ci-prod-aks-mac-weu-rg/providers/Microsoft.ContainerService/managedClusters/ci-prod-aks-mac-weu" + envsubst < azure-monitor-metrics-addon/Chart-template.yaml > azure-monitor-metrics-addon/Chart.yaml && envsubst < azure-monitor-metrics-addon/values-template.yaml > azure-monitor-metrics-addon/values.yaml + displayName: 'Ev2: package artifacts.tar.gz for prod release' + + - bash: | + cd $(Build.SourcesDirectory)/.pipelines/deployment/arc-extension-release/ServiceGroupRoot/Scripts + tar -czvf ../extension-artifacts.tar.gz arcExtensionRelease.sh + displayName: 'Ev2: package extension-artifacts.tar.gz for prod release' + + - task: CredScan@3 + displayName: "SDL : Run credscan" + + - task: CopyFiles@2 + displayName: "Ev2: copy Ev2 deployment artifacts to staging directory" + inputs: + SourceFolder: "$(Build.SourcesDirectory)/.pipelines/deployment" + Contents: | + **/* + TargetFolder: '$(Build.ArtifactStagingDirectory)/deploy' + + - task: PublishBuildArtifacts@1 + displayName: "Ev2: publish Ev2 deployment artifacts" + inputs: + pathToPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: drop + + - job: Linux_Prometheus_Collector + displayName: "Build: linux prometheus-collector image" + pool: + name: Azure-Pipelines-CI-Test-EO + dependsOn: Image_Tags_and_Ev2_Artifacts + variables: + LINUX_FULL_IMAGE_NAME: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.LINUX_FULL_IMAGE_NAME'] ] + # This is necessary because of: https://github.com/moby/moby/issues/37965 + DOCKER_BUILDKIT: 1 + steps: + - checkout: self + submodules: true + + - task: CodeQL3000Init@0 + displayName: 'SDL: init codeql' + + - task: GoTool@0 + displayName: "Build: specify golang version" + inputs: + version: $(GOLANG_VERSION) + + - bash: | + mkdir -p $(Build.ArtifactStagingDirectory)/linux + + # Necessary due to necessary due to https://stackoverflow.com/questions/60080264/docker-cannot-build-multi-platform-images-with-docker-buildx + sudo apt-get update && sudo apt-get -y install qemu binfmt-support qemu-user-static + docker system prune --all -f + docker images -q --filter "dangling=true" | xargs docker rmi + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + + docker buildx create --name dockerbuilder + docker buildx use dockerbuilder + docker buildx build . --platform=linux/amd64,linux/arm64 --file ./build/linux/Dockerfile -t $(LINUX_FULL_IMAGE_NAME) --build-arg "GOLANG_VERSION=$(GOLANG_VERSION)" --metadata-file $(Build.ArtifactStagingDirectory)/linux/metadata.json --push # --cache-to type=registry,ref=$(ACR_REGISTRY)$(ACR_REPOSITORY)/cache:prometheuscollector,mode=max --cache-from type=registry,ref=$(ACR_REGISTRY)$(ACR_REPOSITORY)/cache:prometheuscollector + docker pull $(LINUX_FULL_IMAGE_NAME) + docker system prune --all -f + workingDirectory: $(Build.SourcesDirectory)/otelcollector/ + displayName: "Build: build and push image to dev ACR" + + - bash: | + MEDIA_TYPE=$(docker manifest inspect -v $(LINUX_FULL_IMAGE_NAME) | jq '.Descriptor.mediaType') + DIGEST=$(docker manifest inspect -v $(LINUX_FULL_IMAGE_NAME) | jq '.Descriptor.digest') + SIZE=$(docker manifest inspect -v $(LINUX_FULL_IMAGE_NAME) | jq '.Descriptor.size') + cat <>$(Build.ArtifactStagingDirectory)/linux/payload.json + {"targetArtifact":{"mediaType":$MEDIA_TYPE,"digest":$DIGEST,"size":$SIZE}} + EOF + workingDirectory: $(Build.SourcesDirectory)/otelcollector/ + displayName: "Build: Set values in payload.json for signing" + condition: succeeded() + + - task: EsrpCodeSigning@5 + displayName: "ESRP CodeSigning for Prometheus Linux" + inputs: + ConnectedServiceName: 'ESRPServiceConnectionPrometheus' + AppRegistrationClientId: '73f8d5f9-b507-497f-b698-4ed00fcba5a3' + AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47' + AuthAKVName: 'ESRPPrometheusKVProd' + AuthCertName: 'ESRPContainerImageSignCert' + AuthSignCertName: 'ESRPReqPrometheusProdCert' + FolderPath: '$(Build.ArtifactStagingDirectory)/linux/' + Pattern: '*.json' + signConfigType: 'inlineSignParams' + inlineOperation: | + [ + { + "keyCode": "CP-469451", + "operationSetCode": "NotaryCoseSign", + "parameters": [ + { + "parameterName": "CoseFlags", + "parameterValue": "chainunprotected" + } + ], + "toolName": "sign", + "toolVersion": "1.0" + } + ] + SessionTimeout: '60' + MaxConcurrency: '50' + MaxRetryAttempts: '5' + PendingAnalysisWaitTimeoutMinutes: '5' + + - bash: | + set -euxo pipefail + curl -LO "https://github.com/oras-project/oras/releases/download/v1.0.0/oras_1.0.0_linux_amd64.tar.gz" + mkdir -p oras-install/ + tar -zxf oras_1.0.0_*.tar.gz -C oras-install/ + sudo mv oras-install/oras /usr/local/bin/ + rm -rf oras_1.0.0_*.tar.gz oras-install/ + oras attach $(LINUX_FULL_IMAGE_NAME) \ + --artifact-type 'application/vnd.cncf.notary.signature' \ + ./payload.json:application/cose \ + -a "io.cncf.notary.x509chain.thumbprint#S256=[\"79E6A702361E1F60DAA84AEEC4CBF6F6420DE6BA\"]" + oras attach $(LINUX_FULL_IMAGE_NAME) \ + --artifact-type 'application/vnd.microsoft.artifact.lifecycle' \ + --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$(date -u -d '-1 hour' +"%Y-%m-%dT%H:%M:%SZ")" + workingDirectory: $(Build.ArtifactStagingDirectory)/linux/ + displayName: "ORAS Push Artifacts in $(Build.ArtifactStagingDirectory)/linux/" + condition: succeeded() + + - bash: | + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin + export TRIVY_DB_REPOSITORY="ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db" + export TRIVY_JAVA_DB_REPOSITORY="ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db" + for image in $(LINUX_FULL_IMAGE_NAME) $(KUBE_STATE_METRICS_IMAGE) $(NODE_EXPORTER_IMAGE); do + for i in {1..5}; do + trivy image --ignore-unfixed --no-progress --severity HIGH,CRITICAL,MEDIUM $image > trivy_output.log 2>&1 + TRIVY_EXIT_CODE=$? + if [ $TRIVY_EXIT_CODE -eq 0 ]; then + cat trivy_output.log + break + fi + if grep -q "TOOMANYREQUESTS" trivy_output.log; then + echo "Error: Too many requests to the Trivy server. Retrying... ($i/5)" + sleep 5 + else + cat trivy_output.log + exit 1 + fi + done + if [ $TRIVY_EXIT_CODE -ne 0 ]; then + echo "Error: Trivy scan failed after 5 retries." + exit 1 + fi + done + workingDirectory: $(Build.SourcesDirectory) + displayName: "Build: run trivy scan" + + - task: CodeQL3000Finalize@0 + displayName: 'SDL: run codeql' + + - task: ComponentGovernanceComponentDetection@0 + displayName: "SDL: run component governance" + inputs: + scanType: 'Register' + verbosity: 'Verbose' + dockerImagesToScan: '$(LINUX_FULL_IMAGE_NAME)' + alertWarningLevel: 'High' + sourceScanPath: '$(Build.SourcesDirectory)/otelcollector' + ignoreDirectories: '$(Build.SourcesDirectory)/mixins,$(Build.SourcesDirectory)/tools,$(Build.SourcesDirectory)/otelcollector/react' + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: "Ev2: Generate image artifacts" + condition: and(succeeded(), and(eq(variables.IS_PR, false), eq(variables.IS_MAIN_BRANCH, true))) + inputs: + BuildDropPath: '$(Build.ArtifactStagingDirectory)/linux' + DockerImagesToScan: '$(LINUX_FULL_IMAGE_NAME)' + + - task: SdtReport@2 + displayName: 'SDL: generate report' + inputs: + GdnExportAllTools: false + GdnExportGdnToolBinSkim: true + GdnExportGdnToolBinSkimSeverity: 'Note' + GdnExportGdnToolGosec: true + GdnExportGdnToolGosecSeverity: 'Note' + GdnExportGdnToolSemmle: true + GdnExportGdnToolSemmleSeverity: 'Note' + + - task: PublishSecurityAnalysisLogs@3 + displayName: 'SDL: publish report' + inputs: + ArtifactName: 'CodeAnalysisLogs' + ArtifactType: 'Container' + PublishProcessedResults: true + AllTools: true + ToolLogsNotFoundAction: 'Standard' + + - task: PublishBuildArtifacts@1 + displayName: "Ev2: Publish image artifacts" + condition: and(succeeded(), and(eq(variables.IS_PR, false), eq(variables.IS_MAIN_BRANCH, true))) + inputs: + pathToPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: drop + + - task: PostAnalysis@2 + displayName: 'SDL: Post-Build Analysis' + inputs: + GdnBreakAllTools: false + GdnBreakGdnToolBinSkim: true + GdnBreakGdnToolBinSkimSeverity: 'Warning' + GdnBreakGdnToolGosec: true + GdnBreakGdnToolGosecSeverity: 'Warning' + GdnBreakGdnToolSemmle: true + GdnBreakGdnToolSemmleSeverity: 'Warning' + + + + - job: Linux_Target_Allocator + displayName: "Build: target allocator image" + pool: + name: Azure-Pipelines-CI-Test-EO + dependsOn: Image_Tags_and_Ev2_Artifacts + variables: + TARGET_ALLOCATOR_FULL_IMAGE_NAME: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.TARGET_ALLOCATOR_FULL_IMAGE_NAME'] ] + # This is necessary because of: https://github.com/moby/moby/issues/37965 + DOCKER_BUILDKIT: 1 + skipComponentGovernanceDetection: true + steps: + - checkout: self + persistCredentials: true + + - task: GoTool@0 + displayName: "Build: specify golang version" + inputs: + version: $(GOLANG_VERSION) + + - bash: | + mkdir -p $(Build.ArtifactStagingDirectory)/targetallocator + + # Necessary due to necessary due to https://stackoverflow.com/questions/60080264/docker-cannot-build-multi-platform-images-with-docker-buildx + sudo apt-get update && sudo apt-get -y install qemu binfmt-support qemu-user-static + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + + docker system prune --all -f + + docker buildx create --name dockerbuilder + docker buildx use dockerbuilder + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker buildx build . --platform=linux/amd64,linux/arm64 --file Dockerfile -t $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) --build-arg "GOLANG_VERSION=$(GOLANG_VERSION)" --metadata-file $(Build.ArtifactStagingDirectory)/targetallocator/metadata.json --push # --cache-to type=registry,ref=$(ACR_REGISTRY)$(ACR_REPOSITORY)/cache:targetallocator,mode=max --cache-from type=registry,ref=$(ACR_REGISTRY)$(ACR_REPOSITORY)/cache:targetallocator + docker pull $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) + MEDIA_TYPE=$(docker manifest inspect -v $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) | jq '.Descriptor.mediaType') + DIGEST=$(docker manifest inspect -v $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) | jq '.Descriptor.digest') + SIZE=$(docker manifest inspect -v $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) | jq '.Descriptor.size') + cat <>$(Build.ArtifactStagingDirectory)/targetallocator/payload.json + {"targetArtifact":{"mediaType":$MEDIA_TYPE,"digest":$DIGEST,"size":$SIZE}} + EOF + workingDirectory: $(Build.SourcesDirectory)/otelcollector/otel-allocator + displayName: "Build: build and push target allocator image to dev ACR" + condition: succeeded() + + - bash: | + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin + export TRIVY_DB_REPOSITORY="ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db" + export TRIVY_JAVA_DB_REPOSITORY="ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db" + for i in {1..5}; do + trivy image --ignore-unfixed --no-progress --severity HIGH,CRITICAL,MEDIUM $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) > trivy_output.log 2>&1 + TRIVY_EXIT_CODE=$? + if [ $TRIVY_EXIT_CODE -eq 0 ]; then + cat trivy_output.log + break + fi + if grep -q "TOOMANYREQUESTS" trivy_output.log; then + echo "Error: Too many requests to the Trivy server. Retrying... ($i/5)" + sleep 5 + else + cat trivy_output.log + exit 1 + fi + done + if [ $TRIVY_EXIT_CODE -ne 0 ]; then + echo "Error: Trivy scan failed after 5 retries." + exit 1 + fi + workingDirectory: $(Build.SourcesDirectory) + displayName: "Build: run trivy scan" + + - task: EsrpCodeSigning@5 + displayName: "ESRP CodeSigning for TargetAllocator" + inputs: + ConnectedServiceName: "ESRPServiceConnectionPrometheus" + AppRegistrationClientId: '73f8d5f9-b507-497f-b698-4ed00fcba5a3' + AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47' + AuthAKVName: 'ESRPPrometheusKVProd' + AuthCertName: 'ESRPContainerImageSignCert' + AuthSignCertName: 'ESRPReqPrometheusProdCert' + FolderPath: $(Build.ArtifactStagingDirectory)/targetallocator/ + Pattern: "*.json" + signConfigType: inlineSignParams + inlineOperation: | + [ + { + "keyCode": "CP-469451", + "operationSetCode": "NotaryCoseSign", + "parameters": [ + { + "parameterName": "CoseFlags", + "parameterValue": "chainunprotected" + } + ], + "toolName": "sign", + "toolVersion": "1.0" + } + ] + SessionTimeout: '60' + MaxConcurrency: '50' + MaxRetryAttempts: '5' + PendingAnalysisWaitTimeoutMinutes: '5' + + - bash: | + set -euxo pipefail + curl -LO "https://github.com/oras-project/oras/releases/download/v1.0.0/oras_1.0.0_linux_amd64.tar.gz" + mkdir -p oras-install/ + tar -zxf oras_1.0.0_*.tar.gz -C oras-install/ + sudo mv oras-install/oras /usr/local/bin/ + rm -rf oras_1.0.0_*.tar.gz oras-install/ + oras attach $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) \ + --artifact-type 'application/vnd.cncf.notary.signature' \ + ./payload.json:application/cose \ + -a "io.cncf.notary.x509chain.thumbprint#S256=[\"79E6A702361E1F60DAA84AEEC4CBF6F6420DE6BA\"]" + oras attach $(TARGET_ALLOCATOR_FULL_IMAGE_NAME) \ + --artifact-type 'application/vnd.microsoft.artifact.lifecycle' \ + --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$(date -u -d '-1 hour' +"%Y-%m-%dT%H:%M:%SZ")" + workingDirectory: $(Build.ArtifactStagingDirectory)/targetallocator/ + displayName: "ORAS Push Artifacts in $(Build.ArtifactStagingDirectory)/targetallocator/" + condition: succeeded() + + - job: Linux_Config_Reader + displayName: "Build: config reader image" + pool: + name: Azure-Pipelines-CI-Test-EO + dependsOn: Image_Tags_and_Ev2_Artifacts + variables: + LINUX_CONFIG_READER_FULL_IMAGE_NAME: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.LINUX_CONFIG_READER_FULL_IMAGE_NAME'] ] + # This is necessary because of: https://github.com/moby/moby/issues/37965 + DOCKER_BUILDKIT: 1 + skipComponentGovernanceDetection: true + steps: + - task: GoTool@0 + displayName: "Build: specify golang version" + inputs: + version: $(GOLANG_VERSION) + + - bash: | + mkdir -p $(Build.ArtifactStagingDirectory)/linuxcfgreader + + # Necessary due to necessary due to https://stackoverflow.com/questions/60080264/docker-cannot-build-multi-platform-images-with-docker-buildx + sudo apt-get update && sudo apt-get -y install qemu binfmt-support qemu-user-static + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + docker system prune --all -f + + docker buildx create --name dockerbuilder + docker buildx use dockerbuilder + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker buildx build . --platform=linux/amd64,linux/arm64 --file ./build/linux/configuration-reader/Dockerfile -t $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) --build-arg "GOLANG_VERSION=$(GOLANG_VERSION)" --metadata-file $(Build.ArtifactStagingDirectory)/linux/configuration-reader/metadata.json --push # --cache-to type=registry,ref=$(ACR_REGISTRY)$(ACR_REPOSITORY)/cache:cfg,mode=max --cache-from type=registry,ref=$(ACR_REGISTRY)$(ACR_REPOSITORY)/cache:cfg + docker pull $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) + MEDIA_TYPE=$(docker manifest inspect -v $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) | jq '.Descriptor.mediaType') + DIGEST=$(docker manifest inspect -v $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) | jq '.Descriptor.digest') + SIZE=$(docker manifest inspect -v $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) | jq '.Descriptor.size') + cat <>$(Build.ArtifactStagingDirectory)/linuxcfgreader/payload.json + {"targetArtifact":{"mediaType":$MEDIA_TYPE,"digest":$DIGEST,"size":$SIZE}} + EOF + workingDirectory: $(Build.SourcesDirectory)/otelcollector/ + displayName: "Build: build and push configuration reader image to dev ACR" + condition: succeeded() + + - bash: | + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin + export TRIVY_DB_REPOSITORY="ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db" + export TRIVY_JAVA_DB_REPOSITORY="ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db" + for i in {1..5}; do + trivy image --ignore-unfixed --no-progress --severity HIGH,CRITICAL,MEDIUM $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) > trivy_output.log 2>&1 + TRIVY_EXIT_CODE=$? + if [ $TRIVY_EXIT_CODE -eq 0 ]; then + cat trivy_output.log + break + fi + if grep -q "TOOMANYREQUESTS" trivy_output.log; then + echo "Error: Too many requests to the Trivy server. Retrying... ($i/5)" + sleep 5 + else + cat trivy_output.log + exit 1 + fi + done + if [ $TRIVY_EXIT_CODE -ne 0 ]; then + echo "Error: Trivy scan failed after 5 retries." + exit 1 + fi + workingDirectory: $(Build.SourcesDirectory) + displayName: "Build: run trivy scan" + + - task: EsrpCodeSigning@5 + displayName: "ESRP CodeSigning for Config Reader" + inputs: + ConnectedServiceName: "ESRPServiceConnectionPrometheus" + AppRegistrationClientId: '73f8d5f9-b507-497f-b698-4ed00fcba5a3' + AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47' + AuthAKVName: 'ESRPPrometheusKVProd' + AuthCertName: 'ESRPContainerImageSignCert' + AuthSignCertName: 'ESRPReqPrometheusProdCert' + FolderPath: $(Build.ArtifactStagingDirectory)/linuxcfgreader/ + Pattern: "*.json" + signConfigType: inlineSignParams + inlineOperation: | + [ + { + "keyCode": "CP-469451", + "operationSetCode": "NotaryCoseSign", + "parameters": [ + { + "parameterName": "CoseFlags", + "parameterValue": "chainunprotected" + } + ], + "toolName": "sign", + "toolVersion": "1.0" + } + ] + SessionTimeout: '60' + MaxConcurrency: '50' + MaxRetryAttempts: '5' + PendingAnalysisWaitTimeoutMinutes: '5' + + - bash: | + set -euxo pipefail + curl -LO "https://github.com/oras-project/oras/releases/download/v1.0.0/oras_1.0.0_linux_amd64.tar.gz" + mkdir -p oras-install/ + tar -zxf oras_1.0.0_*.tar.gz -C oras-install/ + sudo mv oras-install/oras /usr/local/bin/ + rm -rf oras_1.0.0_*.tar.gz oras-install/ + oras attach $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) \ + --artifact-type 'application/vnd.cncf.notary.signature' \ + ./payload.json:application/cose \ + -a "io.cncf.notary.x509chain.thumbprint#S256=[\"79E6A702361E1F60DAA84AEEC4CBF6F6420DE6BA\"]" + oras attach $(LINUX_CONFIG_READER_FULL_IMAGE_NAME) \ + --artifact-type 'application/vnd.microsoft.artifact.lifecycle' \ + --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$(date -u -d '-1 hour' +"%Y-%m-%dT%H:%M:%SZ")" + workingDirectory: $(Build.ArtifactStagingDirectory)/linuxcfgreader/ + displayName: "ORAS Push Artifacts in $(Build.ArtifactStagingDirectory)/linuxcfgreader/" + condition: succeeded() + + - job: Windows2019_Prometheus_Collector + displayName: "Build: windows 2019 prometheus-collector image" + pool: + name: Azure-Pipelines-Windows-CI-Test-EO + timeoutInMinutes: 120 + dependsOn: + - Image_Tags_and_Ev2_Artifacts + variables: + WINDOWS_FULL_IMAGE_NAME: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_FULL_IMAGE_NAME'] ] + WINDOWS_2019_BASE_IMAGE_VERSION: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_2019_BASE_IMAGE_VERSION'] ] + skipComponentGovernanceDetection: true + condition: and(succeeded(), eq(variables.BUILD_WINDOWS, true)) + steps: + - task: GoTool@0 + displayName: "Build: specify golang version" + inputs: + version: $(GOLANG_VERSION) + + - powershell: | + ./makefile_windows.ps1 + workingDirectory: $(Build.SourcesDirectory)/otelcollector/opentelemetry-collector-builder/ + displayName: "Build: build otelcollector, promconfigvalidator, and fluent-bit plugin" + + - powershell: | + docker build . --isolation=hyperv --file ./build/windows/Dockerfile -t $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2019_BASE_IMAGE_VERSION) --build-arg WINDOWS_VERSION=$(WINDOWS_2019_BASE_IMAGE_VERSION) + workingDirectory: $(Build.SourcesDirectory)/otelcollector/ + displayName: "Build: build WS2019 image" + retryCountOnTaskFailure: 2 + + - powershell: | + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker push $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2019_BASE_IMAGE_VERSION) + displayName: "Build: push image to dev ACR" + + - job: Windows2022_Prometheus_Collector + displayName: "Build: windows 2022 prometheus-collector image" + pool: + name: Azure-Pipelines-Windows-CI-Test-EO + timeoutInMinutes: 120 + dependsOn: + - Image_Tags_and_Ev2_Artifacts + variables: + WINDOWS_FULL_IMAGE_NAME: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_FULL_IMAGE_NAME'] ] + WINDOWS_2022_BASE_IMAGE_VERSION: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_2022_BASE_IMAGE_VERSION'] ] + skipComponentGovernanceDetection: true + condition: and(succeeded(), eq(variables.BUILD_WINDOWS, true)) + steps: + - task: GoTool@0 + displayName: "Build: specify golang version" + inputs: + version: $(GOLANG_VERSION) + + - powershell: | + ./makefile_windows.ps1 + workingDirectory: $(Build.SourcesDirectory)/otelcollector/opentelemetry-collector-builder/ + displayName: "Build: build otelcollector, promconfigvalidator, and fluent-bit plugin" + + - powershell: | + docker build . --isolation=hyperv --file ./build/windows/Dockerfile -t $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2022_BASE_IMAGE_VERSION) --build-arg WINDOWS_VERSION=$(WINDOWS_2022_BASE_IMAGE_VERSION) + workingDirectory: $(Build.SourcesDirectory)/otelcollector/ + displayName: "Build: build WS2022 image" + retryCountOnTaskFailure: 2 + + - powershell: | + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker push $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2022_BASE_IMAGE_VERSION) + displayName: "Build: push image to dev ACR" + + - job: WindowsMultiArch_Prometheus_Collector + displayName: "Build: windows multi-arch prometheus-collector image" + pool: + name: Azure-Pipelines-Windows-CI-Test-EO + timeoutInMinutes: 120 + dependsOn: + - Image_Tags_and_Ev2_Artifacts + - Windows2019_Prometheus_Collector + - Windows2022_Prometheus_Collector + variables: + WINDOWS_IMAGE_TAG: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_IMAGE_TAG'] ] + WINDOWS_FULL_IMAGE_NAME: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_FULL_IMAGE_NAME'] ] + WINDOWS_2019_BASE_IMAGE_VERSION: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_2019_BASE_IMAGE_VERSION'] ] + WINDOWS_2022_BASE_IMAGE_VERSION: $[ dependencies.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_2022_BASE_IMAGE_VERSION'] ] + skipComponentGovernanceDetection: true + condition: and(succeeded(), eq(variables.BUILD_WINDOWS, true)) + steps: + - task: GoTool@0 + displayName: "Build: specify golang version" + inputs: + version: $(GOLANG_VERSION) + + - bash: | + export ACR_REPOSITORY_VAR="$(ACR_REPOSITORY)" + export ACR_REPOSITORY_WITHOUT_SLASH="${ACR_REPOSITORY_VAR:1}" + + export WINDOWS_2019_TAG="$(WINDOWS_IMAGE_TAG)-$(WINDOWS_2019_BASE_IMAGE_VERSION)" + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker pull $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2019_BASE_IMAGE_VERSION) + if [ $? -ne 0 ]; then + echo "Failed to pull $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2019_BASE_IMAGE_VERSION). Checking if MCR image is published." + IMAGES_ARE_PUBLISHED=0 + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + output=$(curl -s https://$(MCR_REGISTRY)/v2$(MCR_REPOSITORY)/tags/list) + if (echo $output | grep $WINDOWS_2019_TAG) + then + echo "Images are published to mcr" + IMAGES_ARE_PUBLISHED=1 + break + fi + sleep 30 + done + if [ IMAGES_ARE_PUBLISHED -eq 0 ]; then + echo "Images are not published to mcr within the timeout" + exit 1 + fi + + az acr import --name $(ACR_REGISTRY) --source $(MCR_REGISTRY)$(MCR_REPOSITORY):$(IMAGE_TAG) --image $(ACR_REPOSITORY_WITHOUT_SLASH):$(WINDOWS_2019_TAG) + fi + + export WINDOWS_2022_TAG="$(WINDOWS_IMAGE_TAG)-$(WINDOWS_2022_BASE_IMAGE_VERSION)" + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker pull $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2022_BASE_IMAGE_VERSION) + if [ $? -ne 0 ]; then + echo "Failed to pull $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2022_BASE_IMAGE_VERSION). Checking if MCR image is published." + IMAGES_ARE_PUBLISHED=0 + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + output=$(curl -s https://$(MCR_REGISTRY)/v2$(MCR_REPOSITORY)/tags/list) + if (echo $output | grep $WINDOWS_2022_TAG) + then + echo "Images are published to mcr" + IMAGES_ARE_PUBLISHED=1 + break + fi + sleep 30 + done + if [ IMAGES_ARE_PUBLISHED -eq 0 ]; then + echo "Images are not published to mcr within the timeout" + exit 1 + fi + + az acr import --name $(ACR_REGISTRY) --source $(MCR_REGISTRY)$(MCR_REPOSITORY):$(IMAGE_TAG) --image $(ACR_REPOSITORY_WITHOUT_SLASH):$(WINDOWS_2022_TAG) + fi + displayName: "Build: ensure images are present in ACR" + retryCountOnTaskFailure: 3 + + - powershell: | + New-Item -Path "$(Build.ArtifactStagingDirectory)" -Name "windows" -ItemType "directory" + @{"image.name"="$(WINDOWS_FULL_IMAGE_NAME)"} | ConvertTo-Json -Compress | Out-File -Encoding ascii $(Build.ArtifactStagingDirectory)/windows/metadata.json + docker login containerinsightsprod.azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD) + docker manifest create $(WINDOWS_FULL_IMAGE_NAME) $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2019_BASE_IMAGE_VERSION) $(WINDOWS_FULL_IMAGE_NAME)-$(WINDOWS_2022_BASE_IMAGE_VERSION) + docker manifest push $(WINDOWS_FULL_IMAGE_NAME) + workingDirectory: $(Build.SourcesDirectory)/otelcollector/ + displayName: "Build: Windows multi-arch manifest" + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + condition: and(succeeded(), and(eq(variables.IS_PR, false), eq(variables.IS_MAIN_BRANCH, true))) + displayName: "Ev2: generate image artifacts" + inputs: + BuildDropPath: '$(Build.ArtifactStagingDirectory)/windows' + DockerImagesToScan: '$(WINDOWS_FULL_IMAGE_NAME)' + + - powershell: | + $output = docker manifest inspect -v $(WINDOWS_FULL_IMAGE_NAME) | ConvertFrom-Json + $firstManifest = $output[0] + $MEDIA_TYPE = $firstManifest.Descriptor.mediaType + $DIGEST = $firstManifest.Descriptor.digest + $SIZE = $firstManifest.Descriptor.size + $payload = @{ + targetArtifact = @{ + mediaType = $MEDIA_TYPE + digest = $DIGEST + size = $SIZE + } + } | ConvertTo-Json + + $payload | Out-File -FilePath "$(Build.ArtifactStagingDirectory)/windows/payload.json" + workingDirectory: $(Build.ArtifactStagingDirectory)/windows + displayName: "Build the payload json file" + condition: succeeded() + + - task: EsrpCodeSigning@5 + displayName: "ESRP CodeSigning for Windows Multi-Arch Prometheus" + inputs: + ConnectedServiceName: "ESRPServiceConnectionPrometheus" + AppRegistrationClientId: '73f8d5f9-b507-497f-b698-4ed00fcba5a3' + AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47' + AuthAKVName: 'ESRPPrometheusKVProd' + AuthCertName: 'ESRPContainerImageSignCert' + AuthSignCertName: 'ESRPReqPrometheusProdCert' + FolderPath: $(Build.ArtifactStagingDirectory)/windows/ + Pattern: "*.json" + signConfigType: inlineSignParams + inlineOperation: | + [ + { + "keyCode": "CP-469451", + "operationSetCode": "NotaryCoseSign", + "parameters": [ + { + "parameterName": "CoseFlags", + "parameterValue": "chainunprotected" + } + ], + "toolName": "sign", + "toolVersion": "1.0" + } + ] + SessionTimeout: '60' + MaxConcurrency: '50' + MaxRetryAttempts: '5' + PendingAnalysisWaitTimeoutMinutes: '5' + + - powershell: | + curl.exe -sLO "https://github.com/oras-project/oras/releases/download/v1.0.0/oras_1.0.0_windows_amd64.zip" + $currentDirectory = Get-Location + Expand-Archive -Path $currentDirectory\oras_1.0.0_windows_amd64.zip -DestinationPath . -Force + New-Item -ItemType Directory -Force -Path $env:USERPROFILE\bin + Copy-Item -Path $currentDirectory\oras.exe -Destination "$env:USERPROFILE\bin\" + $env:PATH = "$env:USERPROFILE\bin;$env:PATH" + oras attach $(WINDOWS_FULL_IMAGE_NAME) --artifact-type application/vnd.cncf.notary.signature ./payload.json:application/cose -a io.cncf.notary.x509chain.thumbprint#S256=[\""79E6A702361E1F60DAA84AEEC4CBF6F6420DE6BA\""] + oras attach $(WINDOWS_FULL_IMAGE_NAME) --artifact-type 'application/vnd.microsoft.artifact.lifecycle' --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$(powershell -Command "(Get-Date).AddHours(-1).ToString('yyyy-MM-ddTHH:mm:ssZ')")" + workingDirectory: $(Build.ArtifactStagingDirectory)/windows + displayName: "Download, install Oras and run oras attach" + condition: succeeded() + + - task: PublishBuildArtifacts@1 + condition: and(succeeded(), and(eq(variables.IS_PR, false), eq(variables.IS_MAIN_BRANCH, true))) + displayName: "Ev2: publish image artifacts" + inputs: + pathToPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: drop + + - task: AntiMalware@4 + displayName: 'Run MpCmdRun.exe' + inputs: + InputType: Basic + ScanType: CustomScan + FileDirPath: '$(Build.ArtifactStagingDirectory)' + DisableRemediation: false + + - deployment: Deploy_AKS_Chart + displayName: "Deploy: AKS dev cluster" + environment: Prometheus-Collector + pool: + name: Azure-Pipelines-CI-Test-EO + condition: and((not(succeeded('Deploy_AKS_Chart')), eq(variables['System.StageAttempt'], 1))) + variables: + HELM_CHART_NAME: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.HELM_CHART_NAME'] ] + HELM_SEMVER: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.SEMVER'] ] + IMAGE_TAG: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.SEMVER'] ] + IMAGE_TAG_WINDOWS: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_IMAGE_TAG'] ] + HELM_FULL_IMAGE_NAME: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.HELM_FULL_IMAGE_NAME'] ] + IMAGE_TAG_TARGET_ALLOCATOR: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.TARGET_ALLOCATOR_IMAGE_TAG'] ] + IMAGE_TAG_CONFIG_READER: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.LINUX_CONFIG_READER_IMAGE_TAG'] ] + skipComponentGovernanceDetection: true + strategy: + runOnce: + deploy: + steps: + - checkout: self + submodules: true + persistCredentials: true + + - bash: | + git config --global user.name "AzureDevOps Agent" + git tag "v$(HELM_SEMVER)" + git push origin "v$(HELM_SEMVER)" + displayName: Tag commit with semver + + - task: HelmInstaller@1 + displayName: Install Helm version + inputs: + helmVersionToInstall: 3.12.3 + - bash: | + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + sleep 30 + echo $(IMAGE_TAG) + echo $(IMAGE_TAG_WINDOWS) + echo $(IMAGE_TAG_TARGET_ALLOCATOR) + echo $(IMAGE_TAG_CONFIG_READER) + output=$(curl -s https://$(MCR_REGISTRY)/v2$(MCR_REPOSITORY)/tags/list) + if (echo $output | grep $(IMAGE_TAG_WINDOWS)) && (echo $output | grep $(IMAGE_TAG)) && (echo $output | grep $(IMAGE_TAG_TARGET_ALLOCATOR)) && (echo $output | grep $(IMAGE_TAG_CONFIG_READER)) + then + echo "Images are published to mcr" + exit 0 + fi + done + echo "Images are not published to mcr within the timeout" + exit 1 + displayName: "Check images are pushed to dev MCR" + retryCountOnTaskFailure: 5 + - bash: | + export AKS_REGION="centralus" + export AKS_RESOURCE_ID="/subscriptions/9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb/resourcegroups/ci-dev-aks-tests/providers/Microsoft.ContainerService/managedClusters/ci-dev-aks-tests" + export ARC_EXTENSION="false" + envsubst < $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon/Chart-template.yaml > $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon/Chart.yaml && envsubst < $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon/values-template.yaml > $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon/values.yaml + ls $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon + cd $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon + helm dependency update + displayName: "Build: substitute chart version for 3p in Chart.yaml and values.yaml" + - task: HelmDeploy@0 + displayName: "Deploy: ci-dev-aks-tests cluster" + inputs: + connectionType: 'Azure Resource Manager' + azureSubscription: 'ContainerInsights_Build_Subscription(9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb)' + azureResourceGroup: 'ci-dev-aks-tests' + kubernetesCluster: 'ci-dev-aks-tests' + namespace: 'default' + command: 'upgrade' + chartType: 'FilePath' + chartPath: '$(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon/' + releaseName: 'ama-metrics' + waitForExecution: false + arguments: --dependency-update --values $(Build.SourcesDirectory)/otelcollector/deploy/addon-chart/azure-monitor-metrics-addon/values.yaml + + - deployment: Testkube + displayName: "Test: AKS testkube tests" + environment: Prometheus-Collector + dependsOn: Deploy_AKS_Chart + pool: + name: Azure-Pipelines-CI-Test-EO + condition: (succeeded()) + variables: + HELM_CHART_NAME: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.HELM_CHART_NAME'] ] + HELM_SEMVER: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.SEMVER'] ] + IMAGE_TAG: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.SEMVER'] ] + IMAGE_TAG_WINDOWS: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.WINDOWS_IMAGE_TAG'] ] + HELM_FULL_IMAGE_NAME: $[ stageDependencies.Build.Image_Tags_and_Ev2_Artifacts.outputs['setup.HELM_FULL_IMAGE_NAME'] ] + skipComponentGovernanceDetection: true + strategy: + runOnce: + deploy: + steps: + - checkout: self + persistCredentials: true + + - bash: | + wget -qO - https://repo.testkube.io/key.pub | sudo apt-key add - + echo "deb https://repo.testkube.io/linux linux main" | sudo tee -a /etc/apt/sources.list + sudo apt-get update + sudo apt-get install -y testkube + + exit 0 + workingDirectory: $(Build.SourcesDirectory) + displayName: "Install testkube CLI" + + - task: AzureCLI@1 + displayName: Get kubeconfig + inputs: + azureSubscription: 'ContainerInsights_Build_Subscription(9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb)' + scriptLocation: 'inlineScript' + inlineScript: 'az aks get-credentials -g ci-dev-aks-tests -n ci-dev-aks-tests' + + - bash: | + export AMW_QUERY_ENDPOINT="https://ci-dev-aks-tests-amw-fcdqc5d4agbyh9en.centralus.prometheus.monitor.azure.com" + export AZURE_CLIENT_ID="f8b1889c-310c-4913-93c5-3faf0f594f34" + + envsubst < ./testkube/testkube-config-test-crs.yaml > ./testkube/testkube-config-test-crs-ci-dev-aks-tests.yaml + kubectl apply -f ./testkube/api-server-permissions.yaml + kubectl apply -f ./testkube/testkube-config-test-crs-ci-dev-aks-tests.yaml + kubectl apply -f ./test-cluster-yamls/configmaps/default-config-map/ama-metrics-settings-configmap-all-targets-disabled.yaml + # kubectl apply -f ./test-cluster-yamls/configmaps/ama-metrics-prometheus-config-node-configmap.yaml + # kubectl apply -f ./test-cluster-yamls/configmaps/ama-metrics-prometheus-config-node-windows=configmap.yaml + # kubectl apply -f ./test-cluster-yamls/configmaps/ama-metrics-settings-configmap.yaml + # kubectl apply -f ./test-cluster-yamls/customresources/prometheus-reference-app.yaml + + exit 0 + workingDirectory: $(Build.SourcesDirectory)/otelcollector/test/ + displayName: "Apply TestKube CRs, scrape configs and pod/service monitors" + + - bash: | + sleep 360 + + exit 0 + displayName: "Wait for cluster to be ready" + + - bash: | + # Run the full test suite + kubectl testkube run testsuite e2e-config-tests-nightly --verbose + + # Get the current id of the test suite now running + execution_id=$(kubectl testkube get testsuiteexecutions --test-suite e2e-config-tests-nightly --limit 1 | grep e2e-tests | awk '{print $1}') + + # Watch until the all the tests in the test suite finish + kubectl testkube watch testsuiteexecution $execution_id + + # Get the results as a formatted json file + kubectl testkube get testsuiteexecution $execution_id --output json > testkube-results.json + + # For any test that has failed, print out the Ginkgo logs + if [[ $(jq -r '.status' testkube-results.json) == "failed" ]]; then + + # Get each test name and id that failed + jq -r '.executeStepResults[].execute[] | select(.execution.executionResult.status=="failed") | "\(.execution.testName) \(.execution.id)"' testkube-results.json | while read line; do + testName=$(echo $line | cut -d ' ' -f 1) + id=$(echo $line | cut -d ' ' -f 2) + echo "Test $testName failed. Test ID: $id" + + # Get the Ginkgo logs of the test + kubectl testkube get execution $id > out 2>error.log + + # Remove superfluous logs of everything before the last occurence of 'go downloading'. + # The actual errors can be viewed from the ADO run, instead of needing to view the testkube dashboard. + cat error.log | tac | awk '/go: downloading/ {exit} 1' | tac + done + + # Explicitly fail the ADO task since at least one test failed + exit 0 + fi + + exit 0 + workingDirectory: $(Build.SourcesDirectory) + displayName: "Run tests" \ No newline at end of file