Skip to content
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

Implement multiple executors #790

Draft
wants to merge 312 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
312 commits
Select commit Hold shift + click to select a range
dba4464
Address azure api failures
BMurri Oct 26, 2023
22f0a1d
Fix list in blobs
BMurri Oct 26, 2023
1e88661
Cleanup
BMurri Oct 27, 2023
ba71c1e
Continue debugging
BMurri Oct 27, 2023
60db169
Cleanup
BMurri Oct 27, 2023
520c0e0
Cleanup
BMurri Oct 27, 2023
505f71a
Formatting and renaming
BMurri Oct 27, 2023
f605f2e
more logging to find reason event metadata isn't populating task log
BMurri Oct 27, 2023
3a1382a
formatting
BMurri Oct 27, 2023
62de42e
Fix event bugs
BMurri Oct 27, 2023
ba91091
fix TesOutputFileLog
BMurri Oct 28, 2023
22b2d8c
Gather information to better detect tasks affected by node failures
BMurri Oct 28, 2023
8dcd99e
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 28, 2023
df5b437
YA attempt at output file log
BMurri Oct 28, 2023
bb846a3
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 30, 2023
d611383
Add URL to failure logs and code cleanup
BMurri Oct 30, 2023
d7ca8c4
formatting
BMurri Oct 30, 2023
1bcf3ec
code correction and cleanup
BMurri Oct 30, 2023
34ac766
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 31, 2023
341199b
Process.WaitForExitAsync does not kill the process when the cancellat…
BMurri Oct 31, 2023
f7260d8
Address null issues
BMurri Oct 31, 2023
d1d9c46
address NullReferenceException
BMurri Nov 1, 2023
ed83f01
address NullReferenceException again
BMurri Nov 1, 2023
28364dd
Fix two exceptions and some code cleanup
BMurri Nov 2, 2023
774a2e3
Retry logging and reduction of errors when pools are removed
BMurri Nov 3, 2023
e17a1c3
finalize featires, cleanup code
BMurri Nov 4, 2023
bb3a137
Address exceptions and determine cause of task deletion failures
BMurri Nov 7, 2023
3fb901e
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 7, 2023
c1c68f4
Yet another attempt to get the desired info
BMurri Nov 8, 2023
e2b897b
Property 'identity' on type 'Microsoft.Azure.Batch.Protocol.Entities.…
BMurri Nov 8, 2023
31a34e5
https://learn.microsoft.com/azure/batch/batch-efficient-list-queries#…
BMurri Nov 8, 2023
45290b8
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 9, 2023
3e1b66e
Fix GetInternalTesTaskBlobUrlWithoutSasToken()
BMurri Nov 9, 2023
92d1947
Resolve file upload logs in runner
BMurri Nov 9, 2023
6f44d99
Eventify compute node failure conditions
BMurri Nov 10, 2023
7b6c634
Move processing of output file log from server to node
BMurri Nov 10, 2023
feb8ccc
Log retries
BMurri Nov 10, 2023
60ba233
Address feedback
BMurri Nov 10, 2023
7e5934c
Merge branch 'main' into bmurri/log-retries
BMurri Nov 10, 2023
50a40b5
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 10, 2023
42ff99f
Refactor for clarity and address issues
BMurri Nov 11, 2023
654cc18
Address errors, reduce batch api calls
BMurri Nov 14, 2023
5347d49
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 14, 2023
b216da1
Merge branch 'main' into bmurri/log-retries
BMurri Nov 14, 2023
8293f37
Address feedback
BMurri Nov 14, 2023
95fc2d9
Remove retries specifically on reading http responses
BMurri Nov 14, 2023
2add673
Fix imports ordering
BMurri Nov 14, 2023
33494f3
Merge branch 'main' into bmurri/log-retries
BMurri Nov 15, 2023
bfef5fd
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 15, 2023
e89e854
Merge branch 'main' into bmurri/log-retries
BMurri Nov 15, 2023
18a70ed
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 15, 2023
efbe46a
Merge branch 'main' into bmurri/log-retries
BMurri Nov 15, 2023
3c16567
fix predicates
BMurri Nov 15, 2023
b548e3d
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 15, 2023
aecebaa
fix time math around deleting cloud tasks
BMurri Nov 16, 2023
9c6181a
fix more time math around deleting cloud tasks
BMurri Nov 16, 2023
6046b04
Remove exception thrown during normal process shutdown
BMurri Nov 16, 2023
7b2640e
some cleanup
BMurri Nov 16, 2023
49a4508
some more cleanup
BMurri Nov 17, 2023
12bfb3a
Missed changes from the merge from 'main'
BMurri Nov 17, 2023
5ccf88a
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 17, 2023
e4c1a1c
Merge branch 'main' into bmurri/log-retries
BMurri Nov 20, 2023
d859c2d
Stage compute node ids and parallelize portions of queued task handling
BMurri Nov 21, 2023
e27682f
formatting and minor refactor
BMurri Nov 21, 2023
3784799
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 23, 2023
48c19ac
Refactor based on feedback
BMurri Nov 23, 2023
48ef66a
formatting
BMurri Nov 23, 2023
579a7a5
Futureproof Polly v7 code generation (since v8 is a complete refactor)
BMurri Nov 23, 2023
3cdffdb
Merge branch 'main' into bmurri/log-retries
BMurri Nov 27, 2023
e0275c5
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 29, 2023
5eb5228
Merge branch 'main' into bmurri/log-retries
BMurri Nov 29, 2023
0d50839
Refactor builders
BMurri Nov 29, 2023
8b5b58d
Refactor TestServices
BMurri Nov 29, 2023
371be08
Refactor for testability and to ensure that retries are logged when p…
BMurri Nov 30, 2023
cd0b275
format and refactor for clarity
BMurri Dec 1, 2023
0d6b864
Merge branch 'main' into bmurri/log-retries
BMurri Dec 1, 2023
3f577eb
format and refactor for clarity
BMurri Dec 1, 2023
ddb428e
formatting
BMurri Dec 2, 2023
0ea998f
Merge branch 'main' into bmurri/log-retries
BMurri Dec 4, 2023
e45a48b
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 5, 2023
ba3d679
Merge branch 'main' into bmurri/log-retries
BMurri Dec 5, 2023
0bc5cfe
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 5, 2023
313bc2b
Merge branch 'main' into bmurri/log-retries
BMurri Dec 11, 2023
c2def55
Order process logs (err then out), in order
BMurri Dec 11, 2023
fb20bff
WIP temporary marker
BMurri Dec 11, 2023
ab98d80
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 11, 2023
99f5e48
Unit test multiple new pool quota checks
BMurri Dec 12, 2023
56823f7
Merge branch 'main' into bmurri/log-retries
BMurri Dec 16, 2023
98e6291
formatting
BMurri Dec 16, 2023
cf7fa12
Split builders and implementers
BMurri Dec 18, 2023
cbeffbb
Improve code reuse
BMurri Dec 19, 2023
9eff300
fix unit tests
BMurri Dec 19, 2023
9a8cee8
Reduce noise in PR
BMurri Dec 19, 2023
42769ff
Add comments and reduce noise in PR
BMurri Dec 19, 2023
3840fef
fix unit tests
BMurri Dec 19, 2023
14fff0c
formatting for PR clarity
BMurri Dec 19, 2023
d9c7ee6
formatting for PR clarity
BMurri Dec 19, 2023
b3f3e6c
Fix code doc comments
BMurri Dec 19, 2023
a24a903
fix test
BMurri Dec 19, 2023
e79f787
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 20, 2023
a251124
Merge remote-tracking branch 'origin/bmurri/log-retries' into bmurri/…
BMurri Dec 20, 2023
ea3cba3
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 20, 2023
91a7220
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 21, 2023
247cdd6
formatting
BMurri Dec 21, 2023
1d65f72
queued task pipeline (batch api call reductions)
BMurri Dec 23, 2023
6dd9f77
formatting
BMurri Dec 27, 2023
2a479fa
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jan 22, 2024
f240174
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jan 27, 2024
805d7cc
format
BMurri Jan 27, 2024
632f878
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 3, 2024
045d19c
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 3, 2024
4bcca0f
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 9, 2024
c2a649c
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 13, 2024
1aef303
Merge branch 'bmurri/simplify-task-management' of https://github.com/…
BMurri Feb 13, 2024
38b5fed
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 13, 2024
6892f12
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 4, 2024
8a0cc40
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 7, 2024
2065644
formatting
BMurri Mar 8, 2024
7970ec1
Feedback and minor cleanup
BMurri Mar 12, 2024
55a6d0c
fix off-by-one error
BMurri Mar 14, 2024
cfe1f27
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 14, 2024
03dc2cf
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 23, 2024
de34a24
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 28, 2024
b390f12
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 28, 2024
6389af6
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 4, 2024
0483806
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 16, 2024
004e972
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 17, 2024
5b680ee
update dependencies
BMurri Apr 17, 2024
5515cef
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 22, 2024
4a80856
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 24, 2024
b9b2c45
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 24, 2024
9a7cd15
Merge branch 'main' into bmurri/simplify-task-management
BMurri Apr 25, 2024
8e15f6d
Weird test failure
BMurri Apr 25, 2024
b969fe3
Add task start event to the processed events
BMurri Apr 26, 2024
e8d692c
Fix System.ArgumentOutOfRangeException: Specified argument was out of…
BMurri Apr 26, 2024
990aaf5
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 1, 2024
0fe063f
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 3, 2024
70e4166
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 8, 2024
5c5fc7d
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 9, 2024
640dc10
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 15, 2024
6a355f6
cleanup
BMurri May 15, 2024
ff15485
Reduce load on storage account
BMurri May 16, 2024
01faf62
Give enough time for TES to accept connections
BMurri May 17, 2024
37ed656
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 20, 2024
37b30af
Merge branch 'main' into bmurri/simplify-task-management
BMurri May 21, 2024
ec76b3c
Address terminal condition where cancelled task was completed
BMurri May 30, 2024
c9f318c
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jun 12, 2024
43cc61c
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jun 18, 2024
d348d4a
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jun 25, 2024
ce3d36d
Merge branch 'main' into bmurri/simplify-task-management (with unit t…
BMurri Jul 25, 2024
9feb6f1
Fix unit tests
BMurri Jul 25, 2024
ed02220
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jul 25, 2024
212bb79
Merge branch 'main' into bmurri/simplify-task-management
BMurri Jul 25, 2024
5ff4961
Fix issues in MapLocalPathToSasUrlAsync
BMurri Jul 25, 2024
ad44333
Merge branch 'main' into bmurri/simplify-task-management
BMurri Aug 8, 2024
7bae5d9
Merge branch 'main' into bmurri/simplify-task-management
BMurri Aug 13, 2024
bf935ca
Rename EmumerableExtensions and make queued task bulk processing more…
BMurri Aug 16, 2024
f120ca0
Merge branch 'main' into bmurri/simplify-task-management
BMurri Sep 18, 2024
7eb6891
Implement multiple executors
BMurri Sep 28, 2024
725c0f1
Add standard i/o to executors
BMurri Oct 3, 2024
f860cd4
Convert between container and host filesystems
BMurri Oct 3, 2024
3e9541c
Fix log gathering
BMurri Oct 4, 2024
56d1148
append instead of truncate
BMurri Oct 4, 2024
6aa0f8d
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 9, 2024
3119873
Merge branch 'main' into bmurri/multiple-executors
BMurri Oct 9, 2024
edd6d17
cleanup merge
BMurri Oct 9, 2024
64b35c4
fix unit tests
BMurri Oct 9, 2024
7b161ba
fix batch task environment
BMurri Oct 9, 2024
6e5ad3a
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 9, 2024
98baf8a
minor refactoring of task initialization and pool verification and cr…
BMurri Oct 12, 2024
eb4c780
formatting
BMurri Oct 14, 2024
1a0d6ae
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 14, 2024
4409ca6
several fixes
BMurri Oct 15, 2024
3ecca37
fix DI
BMurri Oct 15, 2024
e35dc8c
startup fixes
BMurri Oct 15, 2024
95306fb
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 15, 2024
7119891
temp logging
BMurri Oct 15, 2024
007df4d
more temp logging
BMurri Oct 17, 2024
4005a23
Repository retry logging
BMurri Oct 17, 2024
244e0d8
Fix repository retry logging
BMurri Oct 17, 2024
8554d30
Add ability to utilize enumerable retry sleep providers
BMurri Oct 18, 2024
049c4cb
Add jitter by default
BMurri Oct 18, 2024
ca978bd
Consolidate restart handlers and exit services when startup fails
BMurri Oct 18, 2024
ce2ca28
formatting
BMurri Oct 18, 2024
d48a5fe
attempted fix
BMurri Oct 18, 2024
32dd178
Various fixes
BMurri Oct 21, 2024
112a556
fix tests
BMurri Oct 21, 2024
0a547cc
Merge branch 'main' into bmurri/simplify-task-management
BMurri Oct 31, 2024
ad64b22
fix repository concurrency detection
BMurri Oct 31, 2024
17a0cd1
Handle RepositoryCollisionException
BMurri Oct 31, 2024
a6d9420
Fix task event processing loop
BMurri Nov 1, 2024
d19d95e
Logging formatting and level updates
BMurri Nov 1, 2024
c309cb5
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 1, 2024
b9b496e
Cleanup
BMurri Nov 2, 2024
7f299eb
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 8, 2024
8527022
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 12, 2024
3b0baaa
Extend retry configuration
BMurri Nov 26, 2024
cd17e04
Merge branch 'main' into bmurri/simplify-task-management
BMurri Nov 26, 2024
8d11792
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 11, 2024
c1b75b7
Implement token retry from connection string
BMurri Dec 11, 2024
6e3b5fd
Address flaky unit tests
BMurri Dec 11, 2024
9c75295
Fix metrics.txt path
BMurri Dec 11, 2024
e92f636
Address flaky unit tests
BMurri Dec 12, 2024
f92334e
Apply the specified Workload Identity
BMurri Dec 12, 2024
f178514
Separate node task outputs from task container(s) outputs
BMurri Dec 12, 2024
4bb354f
Merge branch 'main' into bmurri/simplify-task-management
BMurri Dec 18, 2024
6c79c8f
various small fixes
BMurri Dec 19, 2024
7d26ab2
Actually upload task files
BMurri Dec 19, 2024
a2e051e
Address various regressions
BMurri Dec 21, 2024
d200a63
formatting
BMurri Dec 26, 2024
60ea49e
Address failure to load TES task from repository
BMurri Dec 26, 2024
ff75276
attempt to address serialization failure
BMurri Dec 26, 2024
06400ee
Fail tasks when associated pool or job is removed
BMurri Dec 31, 2024
d7ea8f8
handle repository collisions while processing orphaned tasks
BMurri Jan 2, 2025
4126820
Handle orphaned tasks
BMurri Jan 7, 2025
2d0f68c
Address flaky tests
BMurri Jan 7, 2025
f89c2ea
Address CodeQL build failure
BMurri Jan 7, 2025
f938f15
Address CodeQL build failure again
BMurri Jan 7, 2025
a20a375
Address CodeQL build failure redux
BMurri Jan 7, 2025
caa62d2
Fix yaml syntax error
BMurri Jan 7, 2025
36a03c6
Fix yaml syntax error redux
BMurri Jan 7, 2025
7ef9a51
yaml syntax yet again
BMurri Jan 7, 2025
54d12f5
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 12, 2025
e126729
Merge branch 'main' into bmurri/multiple-executors
BMurri Feb 12, 2025
1c4f9e6
Use GITHUB_TOKEN to limit GitHub API rate-limiting
BMurri Feb 13, 2025
a730128
Merge branch 'main' into bmurri/simplify-task-management
BMurri Feb 14, 2025
b0f48b9
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Feb 15, 2025
ebc62b8
Implement multiple executors results
BMurri Feb 15, 2025
fd3636b
revert file
BMurri Feb 15, 2025
e245ce2
cleanup
BMurri Feb 15, 2025
db47d50
fix mistype
BMurri Feb 15, 2025
cf6c5c5
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Feb 15, 2025
a801b27
remove incomplete example
BMurri Feb 15, 2025
d4d47ed
Fix executor log locator and address various exceptions
BMurri Feb 15, 2025
aeef0b0
Merge branch 'bmurri/github-token' into bmurri/simplify-task-management
BMurri Feb 15, 2025
0566e08
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Feb 15, 2025
a20be53
fix process log name gathering
BMurri Feb 18, 2025
f655ce6
Use GITHUB_TOKEN to limit GitHub API rate-limiting (#834)
BMurri Feb 18, 2025
34109e8
Update AppArmor configuration (#836)
BMurri Feb 18, 2025
1e94534
Wait for storage account role propagation (#838)
BMurri Feb 25, 2025
acf6fd3
Announce v6.0.0 deployment changes (#839)
BMurri Feb 25, 2025
ab117a5
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Feb 27, 2025
38a75ad
Fix bad git merge
BMurri Feb 27, 2025
b1a8a91
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Feb 27, 2025
f1d3447
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 3, 2025
8762823
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Mar 3, 2025
09a4136
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 5, 2025
3ceac57
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Mar 5, 2025
e78030c
Merge branch 'main' into bmurri/simplify-task-management
BMurri Mar 6, 2025
916a5fe
Merge branch 'bmurri/simplify-task-management' into bmurri/multiple-e…
BMurri Mar 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ jobs:
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8
9

# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
Expand Down
6 changes: 6 additions & 0 deletions Microsoft.GA4GH.TES.sln
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tes.SDK", "src\Tes.SDK\Tes.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tes.SDK.Tests", "src\Tes.SDK.Tests\Tes.SDK.Tests.csproj", "{AE7ADB92-BEC6-4030-B62F-BDBB6AC53CB4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tes.Repository", "src\Tes.Repository\Tes.Repository.csproj", "{515A4905-0522-4C72-BC18-41BE6A3BE880}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tes.SDK.Examples", "src\Tes.SDK.Examples\Tes.SDK.Examples.csproj", "{08A30572-2C5A-4F61-AF77-36F624A6020B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "build-push-acr", "src\build-push-acr\build-push-acr.csproj", "{9DD148A9-86DA-4BB4-886C-1D29E11A0BB3}"
Expand Down Expand Up @@ -119,6 +121,10 @@ Global
{AE7ADB92-BEC6-4030-B62F-BDBB6AC53CB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE7ADB92-BEC6-4030-B62F-BDBB6AC53CB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE7ADB92-BEC6-4030-B62F-BDBB6AC53CB4}.Release|Any CPU.Build.0 = Release|Any CPU
{515A4905-0522-4C72-BC18-41BE6A3BE880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{515A4905-0522-4C72-BC18-41BE6A3BE880}.Debug|Any CPU.Build.0 = Debug|Any CPU
{515A4905-0522-4C72-BC18-41BE6A3BE880}.Release|Any CPU.ActiveCfg = Release|Any CPU
{515A4905-0522-4C72-BC18-41BE6A3BE880}.Release|Any CPU.Build.0 = Release|Any CPU
{08A30572-2C5A-4F61-AF77-36F624A6020B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08A30572-2C5A-4F61-AF77-36F624A6020B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08A30572-2C5A-4F61-AF77-36F624A6020B}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
27 changes: 20 additions & 7 deletions src/CommonUtilities.Tests/ArmEnvironmentEndpointsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,17 @@ private static bool Equals(IReadOnlyDictionary<string, object?> x, T y)
[DataRow("AzureChinaCloud", "https://management.chinacloudapi.cn/.default", DisplayName = "AzureChinaCloud")]
public async Task FromKnownCloudNameAsync_ExpectedDefaultTokenScope(string cloud, string audience)
{
var environment = await AzureCloudConfig.FromKnownCloudNameAsync(cloudName: cloud, retryPolicyOptions: Microsoft.Extensions.Options.Options.Create(new Options.RetryPolicyOptions()));
var environment = await SkipWhenTimeout(AzureCloudConfig.FromKnownCloudNameAsync(cloudName: cloud, retryPolicyOptions: Microsoft.Extensions.Options.Options.Create(new Options.RetryPolicyOptions())));
Assert.AreEqual(audience, GetPropertyFromEnvironment<string>(environment, nameof(AzureCloudConfig.DefaultTokenScope)));
}

private static T? GetPropertyFromEnvironment<T>(AzureCloudConfig environment, string property)
{
return (T?)environment.GetType().GetProperty(property)?.GetValue(environment);
}

[DataTestMethod]
[DataRow(Cloud.Public, "AzureCloud", DisplayName = "All generally available global Azure regions")]
[DataRow(Cloud.USGovernment, "AzureUSGovernment", DisplayName = "Azure Government")]
[DataRow(Cloud.China, "AzureChinaCloud", DisplayName = "Microsoft Azure operated by 21Vianet")]
public async Task FromKnownCloudNameAsync_ExpectedValues(Cloud cloud, string cloudName)
{
var environment = await AzureCloudConfig.FromKnownCloudNameAsync(cloudName: cloudName, retryPolicyOptions: Microsoft.Extensions.Options.Options.Create(new Options.RetryPolicyOptions()));
var environment = await SkipWhenTimeout(AzureCloudConfig.FromKnownCloudNameAsync(cloudName: cloudName, retryPolicyOptions: Microsoft.Extensions.Options.Options.Create(new Options.RetryPolicyOptions())));
foreach (var (property, value) in CloudEndpoints[cloud])
{
switch (value)
Expand All @@ -189,5 +184,23 @@ public async Task FromKnownCloudNameAsync_ExpectedValues(Cloud cloud, string clo
}
}
}

private static T? GetPropertyFromEnvironment<T>(AzureCloudConfig environment, string property)
{
return (T?)environment.GetType().GetProperty(property)?.GetValue(environment);
}

private static async Task<T> SkipWhenTimeout<T>(Task<T> task)
{
try
{
return await task;
}
catch (TaskCanceledException e) when (e.InnerException is TimeoutException)
{
Assert.Inconclusive(e.Message);
throw new System.Diagnostics.UnreachableException();
}
}
}
}
152 changes: 110 additions & 42 deletions src/CommonUtilities/AzureServicesConnectionStringCredential.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private AzureServicesConnectionStringCredentialOptions()

private void SetInitialState(AzureCloudConfig armEndpoints)
{
(GetEnvironmentVariable("AZURE_ADDITIONALLY_ALLOWED_TENANTS") ?? string.Empty).Split((char[]?)[';'], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ForEach(AdditionallyAllowedTenants.Add);
(GetEnvironmentVariable("AZURE_ADDITIONALLY_ALLOWED_TENANTS") ?? string.Empty).Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ForEach(AdditionallyAllowedTenants.Add);
TenantId = GetEnvironmentVariable("AZURE_TENANT_ID")!;
AuthorityHost = armEndpoints.AuthorityHost ?? new(armEndpoints.Authentication?.LoginEndpointUrl ?? throw new ArgumentException("AuthorityHost is missing", nameof(armEndpoints)));
Audience = armEndpoints.ArmEnvironment?.Audience ?? armEndpoints.Authentication?.Audiences?.LastOrDefault() ?? throw new ArgumentException("Audience is missing", nameof(armEndpoints));
Expand Down Expand Up @@ -113,6 +113,11 @@ private void SetInitialState(AzureCloudConfig armEndpoints)
/// </summary>
public bool DisableInstanceDiscovery { get; set; }

/// <summary>
/// Options controlling the storage of the token cache.
/// </summary>
public Azure.Identity.TokenCachePersistenceOptions TokenCachePersistenceOptions { get; set; }

/// <summary>
/// Specifies tenants in addition to the specified <see cref="TenantId"/> for which the credential may acquire tokens.
/// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant the logged in account can access.
Expand All @@ -134,23 +139,17 @@ private void SetInitialState(AzureCloudConfig armEndpoints)

internal Azure.Identity.AzureCliCredential CreateAzureCliCredential()
{
var result = new Azure.Identity.AzureCliCredentialOptions { TenantId = TenantId, AuthorityHost = AuthorityHost, IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled };
CopyAdditionallyAllowedTenants(result.AdditionallyAllowedTenants);
return new(result);
return new(ConfigureOptions(new Azure.Identity.AzureCliCredentialOptions()));
}

internal Azure.Identity.VisualStudioCredential CreateVisualStudioCredential()
{
var result = new Azure.Identity.VisualStudioCredentialOptions { TenantId = TenantId, AuthorityHost = AuthorityHost, IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled };
CopyAdditionallyAllowedTenants(result.AdditionallyAllowedTenants);
return new(result);
return new(ConfigureOptions(new Azure.Identity.VisualStudioCredentialOptions()));
}

internal Azure.Identity.VisualStudioCodeCredential CreateVisualStudioCodeCredential()
{
var result = new Azure.Identity.VisualStudioCodeCredentialOptions { TenantId = TenantId, AuthorityHost = AuthorityHost, IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled };
CopyAdditionallyAllowedTenants(result.AdditionallyAllowedTenants);
return new(result);
return new(ConfigureOptions(new Azure.Identity.VisualStudioCodeCredentialOptions()));
}

//internal Azure.Identity.InteractiveBrowserCredential CreateInteractiveBrowserCredential()
Expand All @@ -169,40 +168,112 @@ internal Azure.Identity.VisualStudioCodeCredential CreateVisualStudioCodeCredent

internal Azure.Identity.ClientSecretCredential CreateClientSecretCredential(string appId, string appKey, string tenantId)
{
var result = new Azure.Identity.ClientSecretCredentialOptions { AuthorityHost = AuthorityHost, IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled, DisableInstanceDiscovery = DisableInstanceDiscovery };
CopyAdditionallyAllowedTenants(result.AdditionallyAllowedTenants);
return new(string.IsNullOrEmpty(tenantId) ? TenantId : tenantId, appId, appKey, result);
return new(string.IsNullOrEmpty(tenantId) ? TenantId : tenantId, appId, appKey, ConfigureOptions(new Azure.Identity.ClientSecretCredentialOptions()));
}

internal Azure.Identity.ManagedIdentityCredential CreateManagedIdentityCredential(int _1, string appId)
internal Azure.Identity.ManagedIdentityCredential CreateManagedIdentityCredential(string appId)
{
return new(appId, this);
return new(appId, options: this);
}

internal Azure.Identity.ManagedIdentityCredential CreateManagedIdentityCredential(int _1)
internal Azure.Identity.ManagedIdentityCredential CreateManagedIdentityCredential()
{
return new(options: this);
return CreateManagedIdentityCredential(null!);
}

internal Azure.Identity.WorkloadIdentityCredential CreateWorkloadIdentityCredential(string appId)
{
Azure.Identity.WorkloadIdentityCredentialOptions result = new() { ClientId = appId, AuthorityHost = AuthorityHost, IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled, DisableInstanceDiscovery = DisableInstanceDiscovery, TenantId = TenantId };
CopyAdditionallyAllowedTenants(result.AdditionallyAllowedTenants);
return new(result);
return new(ConfigureOptions(new Azure.Identity.WorkloadIdentityCredentialOptions() { ClientId = appId }));
}

internal Azure.Identity.WorkloadIdentityCredential CreateWorkloadIdentityCredential()
{
Azure.Identity.WorkloadIdentityCredentialOptions result = new() { AuthorityHost = AuthorityHost, IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled, DisableInstanceDiscovery = DisableInstanceDiscovery, TenantId = TenantId };
CopyAdditionallyAllowedTenants(result.AdditionallyAllowedTenants);
return new(result);
return new(ConfigureOptions(new Azure.Identity.WorkloadIdentityCredentialOptions()));
}

void CopyAdditionallyAllowedTenants(IList<string> additionalTenants)
// Based on https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Credentials/TokenCredentialOptions.cs#L50 method Clone
private T ConfigureOptions<T>(T options) where T : Azure.Identity.TokenCredentialOptions
{
foreach (var tenant in AdditionallyAllowedTenants)
CopyTenantId(options);

// copy TokenCredentialOptions Properties
options.AuthorityHost = AuthorityHost;

options.IsUnsafeSupportLoggingEnabled = IsUnsafeSupportLoggingEnabled;

// copy TokenCredentialDiagnosticsOptions specific options
options.Diagnostics.IsAccountIdentifierLoggingEnabled = Diagnostics.IsAccountIdentifierLoggingEnabled;

// copy ISupportsDisableInstanceDiscovery
CopyDisableInstanceDiscovery(options);

// copy ISupportsTokenCachePersistenceOptions
CopyTokenCachePersistenceOptions(options);

// copy ISupportsAdditionallyAllowedTenants
CopyAdditionallyAllowedTenants(options);

// copy base ClientOptions properties

// only copy transport if the original has changed from the default so as not to set IsCustomTransportSet unintentionally
if (Transport != Default.Transport)
{
additionalTenants.Add(tenant);
options.Transport = Transport;
}

// clone base Diagnostic options
options.Diagnostics.ApplicationId = Diagnostics.ApplicationId;
options.Diagnostics.IsLoggingEnabled = Diagnostics.IsLoggingEnabled;
options.Diagnostics.IsTelemetryEnabled = Diagnostics.IsTelemetryEnabled;
options.Diagnostics.LoggedContentSizeLimit = Diagnostics.LoggedContentSizeLimit;
options.Diagnostics.IsDistributedTracingEnabled = Diagnostics.IsDistributedTracingEnabled;
options.Diagnostics.IsLoggingContentEnabled = Diagnostics.IsLoggingContentEnabled;

CopyListItems(Diagnostics.LoggedHeaderNames, options.Diagnostics.LoggedHeaderNames);
CopyListItems(Diagnostics.LoggedQueryParameters, options.Diagnostics.LoggedQueryParameters);

// clone base RetryOptions
options.RetryPolicy = RetryPolicy;

options.Retry.MaxRetries = Retry.MaxRetries;
options.Retry.Delay = Retry.Delay;
options.Retry.MaxDelay = Retry.MaxDelay;
options.Retry.Mode = Retry.Mode;
options.Retry.NetworkTimeout = Retry.NetworkTimeout;

return options;
}

private static void CopyListItems<TItem>(IList<TItem> source, IList<TItem> destination)
{
foreach (var item in source)
{
destination.Add(item);
}
}

private void CopyTenantId<T>(T options) where T : Azure.Identity.TokenCredentialOptions
{
options?.GetType().GetProperty(nameof(TenantId))?.SetValue(options, TenantId);
}

private void CopyDisableInstanceDiscovery<T>(T options) where T : Azure.Identity.TokenCredentialOptions
{
options?.GetType().GetProperty(nameof(DisableInstanceDiscovery))?.SetValue(options, DisableInstanceDiscovery);
}

private void CopyTokenCachePersistenceOptions<T>(T options) where T : Azure.Identity.TokenCredentialOptions
{
options?.GetType().GetProperty(nameof(TokenCachePersistenceOptions))?.SetValue(options, TokenCachePersistenceOptions);
}

void CopyAdditionallyAllowedTenants<T>(T options) where T : Azure.Identity.TokenCredentialOptions
{
var additionalTenants = options?.GetType().GetProperty(nameof(AdditionallyAllowedTenants))?.GetValue(options) as IList<string>;

if (additionalTenants is not null)
{
CopyListItems(AdditionallyAllowedTenants, additionalTenants);
}
}
}
Expand Down Expand Up @@ -367,30 +438,24 @@ internal static TokenCredential Create(AzureServicesConnectionStringCredentialOp
}
else
{
ValidateMsiRetryTimeout(connectionSettings, options.ConnectionString);
ValidateAndSetMsiRetryTimeout(connectionSettings, options);

// If certificate or client secret are not specified, use the specified managed identity
azureServiceTokenCredential = options.CreateManagedIdentityCredential(
connectionSettings.TryGetValue(MsiRetryTimeout, out var value)
? int.Parse(value)
: 0,
appId);
azureServiceTokenCredential = options.CreateManagedIdentityCredential(appId);
}
}
else
{
ValidateMsiRetryTimeout(connectionSettings, options.ConnectionString);
ValidateAndSetMsiRetryTimeout(connectionSettings, options);

// If AppId is not specified, use Managed Service Identity
azureServiceTokenCredential = options.CreateManagedIdentityCredential(
connectionSettings.TryGetValue(MsiRetryTimeout, out var value)
? int.Parse(value)
: 0);
azureServiceTokenCredential = options.CreateManagedIdentityCredential();
}
}
else if (string.Equals(runAs, Workload, StringComparison.OrdinalIgnoreCase))
{
// If RunAs=Workload use the specified Workload Identity
// RunAs=Workload
// Use the specified Workload Identity
// If AppId key is present, use it as the ClientId
if (connectionSettings.TryGetValue(AppId, out var appId))
{
Expand Down Expand Up @@ -468,18 +533,21 @@ private static void ValidateAttribute(Dictionary<string, string> connectionSetti
// }
//}

private static void ValidateMsiRetryTimeout(Dictionary<string, string> connectionSettings, string connectionString)
private static void ValidateAndSetMsiRetryTimeout(Dictionary<string, string> connectionSettings, AzureServicesConnectionStringCredentialOptions options)
{
if (connectionSettings != null && connectionSettings.TryGetValue(MsiRetryTimeout, out var value))
{
if (!string.IsNullOrWhiteSpace(value))
{
var timeoutString = value;

var parseSucceeded = int.TryParse(timeoutString, out _);
if (!parseSucceeded)
if (int.TryParse(timeoutString, out var timeoutValue) && timeoutValue >= 0)
{
options.Retry.NetworkTimeout = TimeSpan.FromSeconds(timeoutValue);
}
else
{
throw new ArgumentException($"Connection string '{connectionString}' is not valid. MsiRetryTimeout '{timeoutString}' is not valid. Valid values are integers greater than or equal to 0.", nameof(connectionString));
throw new ArgumentException($"Connection string '{options.ConnectionString}' is not valid. MsiRetryTimeout '{timeoutString}' is not valid. Valid values are integers greater than or equal to 0.", nameof(options));
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/CommonUtilities/CommonUtilities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Polly" Version="8.4.2" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<!--Mitigate reported security issues-->
<PackageReference Include="System.Text.Json" Version="8.0.5" />
Expand Down
Loading
Loading