-
Notifications
You must be signed in to change notification settings - Fork 330
Create YAML Kerberos Test Pipeline #4252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
fd6a759
Convert Kerberos pipeline from Classic to YAML (11 jobs)
priyankatiwari08 44d6f22
fix: use env mapping for secret variables in pwsh inline scripts
priyankatiwari08 e234360
fix: use correct build.proj targets
priyankatiwari08 4e5fefd
fix: use BuildSqlClient instead of BuildAllConfigurations for Windows
priyankatiwari08 d99a9d1
fix: use BuildNetFx for netfx, DotNetCoreCLI for netcore on Windows
priyankatiwari08 5036d10
fix: add separate restore step for Windows netcore stage
priyankatiwari08 0dc88aa
fix: add clean step to remove stale obj/artifacts before build
priyankatiwari08 c3310e9
fix: switch Windows netcore to MSBuild@1 + BuildAllConfigurations + B…
priyankatiwari08 f0eeebb
fix: use BuildNetCore target for Windows netcore stage
priyankatiwari08 ed91fcd
fix: bypass build.proj for Windows netcore build step
priyankatiwari08 2952136
fix: clean stale obj dirs + explicit restore for Windows netcore
priyankatiwari08 41c3ab7
fix: workaround P2P TFM negotiation failure on ADO agents
priyankatiwari08 c27e6d2
fix: Replace DotNetCoreCLI@2 csproj build with MSBuild@1 build.proj -…
priyankatiwari08 fa16c85
Updated to use the new build.proj targets and the .NET SDK exclusively.
paulmedynski 9da3ba3
- Combined Windows stages together.
paulmedynski 89e7cf3
- Moved environmental variables into the YAML from the Pipeline UI.
paulmedynski 93dd96f
Fixed problem of YAML targetFramework matrix variable being implicitl…
paulmedynski bca920a
- Moved the pipeline files into a kerberos/ directory.
paulmedynski f5fdd5f
- Fixed test results and coverage file processing.
paulmedynski 86457d7
Fix Kerberos pipeline review feedback
paulmedynski abc52e3
- Excluding kerberos pipeline files from PR checks.
paulmedynski 52773cd
Address additional Copilot pipeline review feedback
paulmedynski 6424e37
Use YAML exists condition for coverage rename step
paulmedynski 00556fa
Use runtime variable for test_results directory checks
paulmedynski 159d457
Address latest Copilot pipeline suggestions
paulmedynski File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| ################################################################################# | ||
| # Licensed to the .NET Foundation under one or more agreements. # | ||
| # The .NET Foundation licenses this file to you under the MIT license. # | ||
| # See the LICENSE file in the project root for more information. # | ||
| ################################################################################# | ||
|
|
||
| # Shared build-and-test steps used by both the Windows and Linux Kerberos jobs. | ||
| # | ||
| # Parameters: | ||
| # buildTarget — The build.proj target that builds SqlClient for the current | ||
| # OS (e.g. BuildSqlClientWindows or BuildSqlClientUnix). | ||
| # testFramework — The TFM to test against (e.g. net9.0, net462). | ||
| # testRunTitle — Title for the published test results (displayed in the ADO | ||
| # Tests tab). | ||
| # artifactName — Name of the published pipeline artifact that carries the | ||
| # test results and coverage files. | ||
|
|
||
| parameters: | ||
|
|
||
| # build.proj target to build SqlClient for the current OS. | ||
| - name: buildTarget | ||
| type: string | ||
|
|
||
| # TFM to pass to the test targets (-p:TestFramework). | ||
| - name: testFramework | ||
| type: string | ||
|
|
||
| # Title shown in the ADO Tests tab for this run. | ||
| - name: testRunTitle | ||
| type: string | ||
|
|
||
| # Pipeline artifact name for test results and coverage. | ||
| - name: artifactName | ||
| type: string | ||
|
|
||
| steps: | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Build | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| # Build the given target. | ||
| # | ||
| # The test stages build as part of their targets, but this separate step isolates build failures | ||
| # so we can fail fast before running tests. Retries are enabled intentionally (1 attempt for | ||
| # build, 2 attempts for test steps) to reduce transient infrastructure-related failures. | ||
| # | ||
| - task: DotNetCoreCLI@2 | ||
| displayName: Build SqlClient | ||
| retryCountOnTaskFailure: 1 | ||
| inputs: | ||
| command: build | ||
| projects: build.proj | ||
| arguments: >- | ||
| -t:${{ parameters.buildTarget }} | ||
| -p:Configuration=Release | ||
|
|
||
|
paulmedynski marked this conversation as resolved.
|
||
| # --------------------------------------------------------------------------- | ||
| # Run tests in separate steps to permit focused retries. | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| # Run the Unit Test suite. | ||
|
paulmedynski marked this conversation as resolved.
|
||
| - task: DotNetCoreCLI@2 | ||
| displayName: Run Unit Tests (${{ parameters.testFramework }}) | ||
| retryCountOnTaskFailure: 2 | ||
| inputs: | ||
| command: build | ||
| projects: build.proj | ||
| arguments: >- | ||
| -t:TestSqlClientUnit | ||
| -p:TestFramework=${{ parameters.testFramework }} | ||
| -p:Configuration=Release | ||
|
|
||
| # Run the Functional Test suite. | ||
| - task: DotNetCoreCLI@2 | ||
| displayName: Run Functional Tests (${{ parameters.testFramework }}) | ||
| retryCountOnTaskFailure: 2 | ||
| inputs: | ||
| command: build | ||
| projects: build.proj | ||
| arguments: >- | ||
| -t:TestSqlClientFunctional | ||
| -p:TestFramework=${{ parameters.testFramework }} | ||
| -p:Configuration=Release | ||
|
|
||
| # Run the Manual Test suite. | ||
| - task: DotNetCoreCLI@2 | ||
| displayName: Run Manual Tests (${{ parameters.testFramework }}) | ||
| retryCountOnTaskFailure: 2 | ||
| inputs: | ||
| command: build | ||
| projects: build.proj | ||
| arguments: >- | ||
| -t:TestSqlClientManual | ||
| -p:TestFramework=${{ parameters.testFramework }} | ||
| -p:Configuration=Release | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Publish results & coverage | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| # Publish the TRX test results to the pipeline run. | ||
| - task: PublishTestResults@2 | ||
| displayName: Publish Test Results | ||
| condition: succeededOrFailed() | ||
| inputs: | ||
| testResultsFormat: VSTest | ||
| # build.proj defines TestResultsFolderPath which defaults to | ||
| # $(Build.SourcesDirectory)/test_results, so we look there for the results and coverage files. | ||
| testResultsFiles: $(Build.SourcesDirectory)/test_results/**/*.trx | ||
| mergeTestResults: true | ||
| testRunTitle: ${{ parameters.testRunTitle }} | ||
| buildConfiguration: Release | ||
|
paulmedynski marked this conversation as resolved.
|
||
|
|
||
| # Azure Pipelines task conditions do not support path existence checks directly, | ||
| # so compute this once and gate later steps on the variable. | ||
| - pwsh: | | ||
| $resultsDir = "$(Build.SourcesDirectory)/test_results" | ||
| if (Test-Path -LiteralPath $resultsDir) { | ||
| Write-Host "##vso[task.setvariable variable=HasTestResultsDir]true" | ||
| } | ||
| else { | ||
| Write-Host "##vso[task.setvariable variable=HasTestResultsDir]false" | ||
| } | ||
| displayName: Detect test_results directory | ||
| condition: succeededOrFailed() | ||
|
|
||
| # Give our coverage files a unique name to make it clear where they originated when we download | ||
| # the artifacts from all jobs in the merge stage. | ||
| - pwsh: | | ||
|
paulmedynski marked this conversation as resolved.
|
||
| cd $(Build.SourcesDirectory)/test_results | ||
| Get-ChildItem -Filter "*.coverage" -Recurse | | ||
| Rename-Item -NewName { "${{ parameters.testFramework }}" + $_.Name } | ||
| displayName: Rename coverage files | ||
| condition: and(succeededOrFailed(), eq(variables['HasTestResultsDir'], 'true')) | ||
|
|
||
| # Publish TRX test results and coverage files as pipeline artifacts. The merge stage needs the | ||
| # coverage files from all of the jobs. | ||
| - task: PublishPipelineArtifact@1 | ||
| displayName: Publish Test Artifacts | ||
| condition: and(succeededOrFailed(), eq(variables['HasTestResultsDir'], 'true')) | ||
| inputs: | ||
| targetPath: $(Build.SourcesDirectory)/test_results | ||
| artifact: ${{ parameters.artifactName }} | ||
|
paulmedynski marked this conversation as resolved.
|
||
|
paulmedynski marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| ################################################################################# | ||
| # Licensed to the .NET Foundation under one or more agreements. # | ||
| # The .NET Foundation licenses this file to you under the MIT license. # | ||
| # See the LICENSE file in the project root for more information. # | ||
| ################################################################################# | ||
|
|
||
| # This template leaves the Active Directory domain and destroys Kerberos | ||
| # credentials. It should be referenced at the end of any job that called | ||
| # linux-init-step.yml. | ||
| # | ||
| # All steps use condition: always() so that cleanup runs even when previous | ||
| # steps fail. | ||
|
|
||
| parameters: | ||
|
|
||
| # The Active Directory domain to leave (e.g. mydomain.contoso.com). | ||
| - name: kerberosDomain | ||
| type: string | ||
|
|
||
| # The domain user account used during the join. | ||
| - name: kerberosDomainUser | ||
| type: string | ||
|
|
||
| # The password for the domain user account. | ||
| - name: kerberosDomainPassword | ||
| type: string | ||
|
|
||
| steps: | ||
|
|
||
| - bash: | | ||
| set -uo pipefail | ||
|
|
||
| DOMAIN="${{ parameters.kerberosDomain }}" | ||
| DOMAIN_USER="${{ parameters.kerberosDomainUser }}" | ||
| DOMAIN_PASSWORD="${{ parameters.kerberosDomainPassword }}" | ||
| DOMAIN_UPPER=$(echo "$DOMAIN" | tr '[:lower:]' '[:upper:]') | ||
|
|
||
| # Leave the domain | ||
| echo "$DOMAIN_PASSWORD" | sudo realm leave "$DOMAIN_UPPER" --verbose \ | ||
| -U "$DOMAIN_USER@$DOMAIN_UPPER" || true | ||
|
|
||
| # Destroy the TGT and credential cache | ||
| kdestroy || true | ||
| displayName: Clean up Kerberos (domain leave + kdestroy) | ||
| condition: always() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| ################################################################################# | ||
| # Licensed to the .NET Foundation under one or more agreements. # | ||
| # The .NET Foundation licenses this file to you under the MIT license. # | ||
| # See the LICENSE file in the project root for more information. # | ||
| ################################################################################# | ||
|
|
||
| # This template joins a Linux agent to an Active Directory domain using Kerberos | ||
| # and acquires a TGT (Ticket-Granting Ticket) for the specified domain user. | ||
| # | ||
| # Prerequisites: | ||
| # - The agent must be running on Ubuntu/Debian (uses apt-get). | ||
| # - The domain controller must be reachable from the agent network. | ||
| # | ||
| # After this step completes successfully, the agent will have: | ||
| # - Kerberos packages installed (krb5-user, realmd, sssd, adcli, etc.) | ||
| # - Hostname set to FQDN within the domain | ||
| # - NTP synchronized with the domain controller | ||
| # - Machine joined to the AD domain | ||
| # - A valid Kerberos TGT for the specified user | ||
|
|
||
| parameters: | ||
|
|
||
| # The Active Directory domain to join (e.g. mydomain.contoso.com). | ||
| - name: kerberosDomain | ||
| type: string | ||
|
|
||
| # The Organizational Unit in which to place the computer account. | ||
| - name: kerberosDomainOU | ||
| type: string | ||
|
|
||
| # The domain user account to authenticate with (sAMAccountName, without @realm). | ||
| - name: kerberosDomainUser | ||
| type: string | ||
|
|
||
| # The password for the domain user account. | ||
| - name: kerberosDomainPassword | ||
| type: string | ||
|
|
||
| steps: | ||
|
|
||
| - bash: | | ||
| set -euo pipefail | ||
|
|
||
| DOMAIN="${{ parameters.kerberosDomain }}" | ||
| DOMAIN_OU="${{ parameters.kerberosDomainOU }}" | ||
| DOMAIN_USER="${{ parameters.kerberosDomainUser }}" | ||
| DOMAIN_PASSWORD="${{ parameters.kerberosDomainPassword }}" | ||
| DOMAIN_UPPER=$(echo "$DOMAIN" | tr '[:lower:]' '[:upper:]') | ||
|
|
||
| echo "Domain: $DOMAIN" | ||
| echo "Realm: $DOMAIN_UPPER" | ||
| echo "User: $DOMAIN_USER" | ||
| echo "OU: $DOMAIN_OU" | ||
|
|
||
| if [ -z "$DOMAIN_PASSWORD" ]; then | ||
| echo "##vso[task.logissue type=error]KerberosDomainPassword is empty" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # ----------------------------------------------------------------------- | ||
| # Install Kerberos and AD integration packages | ||
| # ----------------------------------------------------------------------- | ||
| echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections | ||
|
|
||
| sudo apt-get -y update | ||
| sudo apt-get install -y dialog apt-utils | ||
| sudo apt-get install -y \ | ||
| krb5-user samba sssd sssd-tools libnss-sss libpam-sss \ | ||
| ntp ntpdate realmd adcli | ||
|
|
||
| # ----------------------------------------------------------------------- | ||
| # Set the hostname to FQDN within the domain | ||
| # ----------------------------------------------------------------------- | ||
| CURRENT_HOSTNAME="$(hostname)" | ||
| if [ "$CURRENT_HOSTNAME" = "$DOMAIN" ] || [[ "$CURRENT_HOSTNAME" == *".$DOMAIN" ]]; then | ||
| echo "Hostname already uses domain suffix '.$DOMAIN': $CURRENT_HOSTNAME" | ||
| else | ||
| sudo hostnamectl set-hostname "$CURRENT_HOSTNAME.$DOMAIN" | ||
| fi | ||
|
|
||
| # ----------------------------------------------------------------------- | ||
| # Synchronize time with the domain controller (required for Kerberos) | ||
| # ----------------------------------------------------------------------- | ||
| if ! sudo grep -Fqx "server $DOMAIN" /etc/ntp.conf; then | ||
| echo "server $DOMAIN" | sudo tee -a /etc/ntp.conf | ||
| fi | ||
| sudo systemctl stop ntp | ||
| sudo ntpdate "$DOMAIN" | ||
| sudo systemctl start ntp | ||
|
|
||
| # ----------------------------------------------------------------------- | ||
| # Configure Kerberos realm | ||
| # ----------------------------------------------------------------------- | ||
| echo "[libdefaults] | ||
| default_realm = $DOMAIN_UPPER | ||
| rdns = false" | sudo tee /etc/krb5.conf | ||
|
|
||
| # ----------------------------------------------------------------------- | ||
| # Discover and join the domain | ||
| # ----------------------------------------------------------------------- | ||
| sudo realm discover "$DOMAIN_UPPER" | ||
|
|
||
| echo "$DOMAIN_PASSWORD" | sudo realm join --verbose "$DOMAIN_UPPER" \ | ||
| -U "$DOMAIN_USER@$DOMAIN_UPPER" \ | ||
| --computer-ou "OU=$DOMAIN_OU" | ||
|
|
||
| realm list | ||
|
|
||
| # ----------------------------------------------------------------------- | ||
| # Acquire a Kerberos TGT | ||
| # ----------------------------------------------------------------------- | ||
| echo "$DOMAIN_PASSWORD" | kinit "$DOMAIN_USER@$DOMAIN_UPPER" | ||
|
|
||
| klist | ||
| sudo ip addr | ||
| sudo ip route | ||
| displayName: Initialize Kerberos (domain join + kinit) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.