mirror of
https://github.com/bartvdbraak/keyweave.git
synced 2025-04-27 23:01:20 +00:00
feat: e2e tests within rust instead
This commit is contained in:
parent
7b40a0ae17
commit
38a15a3bcd
8 changed files with 550 additions and 156 deletions
2
.github/workflows/checks.yml
vendored
2
.github/workflows/checks.yml
vendored
|
@ -40,7 +40,7 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: Run tests
|
||||
run: cargo test --all
|
||||
run: cargo test --bins
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
|
153
.github/workflows/e2e.yml
vendored
153
.github/workflows/e2e.yml
vendored
|
@ -1,153 +0,0 @@
|
|||
name: Checks
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
env:
|
||||
VAULT_NAME: bvdbkeyweavetweukvt{0}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Keyweave
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: Build project
|
||||
run: cargo build --all --release
|
||||
- uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
path: target/release/keyweave
|
||||
|
||||
bicep:
|
||||
name: Deploy Azure resources
|
||||
environment: bicep
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LOCATION: eastus
|
||||
DEPLOYMENT_NAME: keyweave-${{ github.run_id }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
- name: Deploy Bicep template
|
||||
uses: azure/arm-deploy@v1
|
||||
with:
|
||||
scope: subscription
|
||||
region: ${{ env.LOCATION }}
|
||||
template: bicep/main.bicep
|
||||
deploymentName: ${{ env.DEPLOYMENT_NAME }}
|
||||
|
||||
none-test:
|
||||
name: Tests without access
|
||||
needs: [build, bicep]
|
||||
runs-on: ubuntu-latest
|
||||
environment: none
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3.0.2
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
- name: Use Keyweave with No Access Policies
|
||||
run: |
|
||||
chmod +x ./artifact/keyweave
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}
|
||||
|
||||
get-test:
|
||||
name: Tests with Get access
|
||||
needs: [build, bicep]
|
||||
runs-on: ubuntu-latest
|
||||
environment: get
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3.0.2
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
- name: Use Keyweave with Only Get Access Policy
|
||||
run: |
|
||||
chmod +x ./artifact/keyweave
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}
|
||||
|
||||
list-test:
|
||||
name: Tests with List access
|
||||
needs: [build, bicep]
|
||||
runs-on: ubuntu-latest
|
||||
environment: list
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3.0.2
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
- name: Use Keyweave with Only List Access Policy
|
||||
run: |
|
||||
chmod +x ./artifact/keyweave
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}
|
||||
|
||||
get-list-test:
|
||||
name: Tests with Get and List access
|
||||
needs: [build, bicep]
|
||||
runs-on: ubuntu-latest
|
||||
environment: getlist
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3.0.2
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
- name: Use Keyweave with both Get and List Access Policies
|
||||
run: |
|
||||
chmod +x ./artifact/keyweave
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}
|
||||
|
||||
- name: Use Keyweave with a filter
|
||||
run: |
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }} --filter "filter"
|
||||
|
||||
- name: Use Keyweave with a complex file path
|
||||
run: |
|
||||
mkdir -p "user/projects/project 1/src/lib"
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }} --output "user/projects/project 1/src/lib/.env"
|
||||
|
||||
- name: Use Keyweave with a non-existent Key Vault
|
||||
run: ./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}1234
|
||||
|
||||
- name: Use Keyweave with a firewalled Key Vault
|
||||
run: ./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '2') }}
|
||||
|
||||
- name: Use Keyweave with a no permissions
|
||||
run: |
|
||||
mkdir -p "user/projects/project 1/src/lib"
|
||||
./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }} --output "/.env"
|
||||
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.OTHER_SUBSCRIPTION_ID }}
|
||||
- name: Use Keyweave while logged into other Subscription
|
||||
run: ./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}
|
||||
|
||||
# - uses: azure/login@v1
|
||||
# with:
|
||||
# client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
# tenant-id: ${{ secrets.OTHER_TENANT_ID }}
|
||||
# subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
# - name: Use Keyweave while logged into other Azure Tenant
|
||||
# run: ./artifact/keyweave --vault-name ${{ format(env.VAULT_NAME, '1') }}
|
45
.github/workflows/tests.yml
vendored
Normal file
45
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
name: Tests
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
bicep:
|
||||
name: Deploy Azure resources
|
||||
environment: bicep
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LOCATION: eastus
|
||||
DEPLOYMENT_NAME: keyweave-${{ github.run_id }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
- name: Deploy Bicep template
|
||||
uses: azure/arm-deploy@v1
|
||||
with:
|
||||
scope: subscription
|
||||
region: ${{ env.LOCATION }}
|
||||
template: bicep/main.bicep
|
||||
deploymentName: ${{ env.DEPLOYMENT_NAME }}
|
||||
|
||||
test:
|
||||
name: Tests
|
||||
needs: bicep
|
||||
runs-on: ubuntu-latest
|
||||
environment: test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: Run all tests
|
||||
run: cargo test --all
|
297
Cargo.lock
generated
297
Cargo.lock
generated
|
@ -17,6 +17,15 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
|
@ -86,6 +95,36 @@ version = "1.0.75"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"bstr",
|
||||
"doc-comment",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
"predicates-tree",
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_fs"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f070617a68e5c2ed5d06ee8dd620ee18fb72b99f6c094bed34cf8ab07c875b48"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"doc-comment",
|
||||
"globwalk",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
"predicates-tree",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.9.0"
|
||||
|
@ -235,6 +274,17 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.14.0"
|
||||
|
@ -382,6 +432,19 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown 0.14.2",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.9"
|
||||
|
@ -392,6 +455,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "difflib"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
|
@ -402,12 +471,24 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.33"
|
||||
|
@ -469,6 +550,15 @@ version = "2.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -643,6 +733,30 @@ version = "0.28.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globwalk"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"ignore",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.21"
|
||||
|
@ -668,6 +782,12 @@ version = "0.12.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
|
@ -804,6 +924,23 @@ dependencies = [
|
|||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
|
||||
dependencies = [
|
||||
"globset",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex",
|
||||
"same-file",
|
||||
"thread_local",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
|
@ -811,7 +948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -835,6 +972,15 @@ version = "2.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
|
@ -855,12 +1001,17 @@ name = "keyweave"
|
|||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
"assert_fs",
|
||||
"azure_core",
|
||||
"azure_identity",
|
||||
"azure_security_keyvault",
|
||||
"clap",
|
||||
"futures",
|
||||
"openssl",
|
||||
"paris",
|
||||
"predicates",
|
||||
"serial_test",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -948,6 +1099,12 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "normalize-line-endings"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
|
@ -1161,6 +1318,37 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "3.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"difflib",
|
||||
"float-cmp",
|
||||
"itertools",
|
||||
"normalize-line-endings",
|
||||
"predicates-core",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
|
@ -1259,6 +1447,35 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.22"
|
||||
|
@ -1333,6 +1550,15 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.22"
|
||||
|
@ -1441,6 +1667,31 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"serial_test_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test_derive"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
|
@ -1547,6 +1798,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termtree"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
|
@ -1567,6 +1824,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.30"
|
||||
|
@ -1774,12 +2041,31 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
|
@ -1906,6 +2192,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
|
|
@ -11,6 +11,7 @@ repository = "https://github.com/bartvdbraak/keyweave/"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.75"
|
||||
azure_core = "0.17.0"
|
||||
azure_identity = "0.17.0"
|
||||
azure_security_keyvault = "0.17.0"
|
||||
clap = { version = "4.4.8", features = ["derive"] }
|
||||
|
@ -20,3 +21,9 @@ tokio = {version = "1.34.0", features = ["full"]}
|
|||
|
||||
[target.'cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "arm", target_arch = "aarch64")))'.dependencies]
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "2.0.12"
|
||||
assert_fs = "1.0.13"
|
||||
predicates = "3.0.4"
|
||||
serial_test = "2.0.0"
|
||||
|
|
|
@ -20,7 +20,7 @@ resource federatedCredential 'Microsoft.ManagedIdentity/userAssignedIdentities/f
|
|||
parent: managedIdentity[index]
|
||||
properties: {
|
||||
issuer: 'https://token.actions.githubusercontent.com'
|
||||
subject: 'repo:bartvdbraak/keyweave:environment:${environment}'
|
||||
subject: 'repo:bartvdbraak/keyweave:environment:test'
|
||||
audiences: [
|
||||
'api://AzureADTokenExchange'
|
||||
]
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -11,6 +11,7 @@ use std::io::Write;
|
|||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Semaphore;
|
||||
use azure_core::error::HttpError;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
|
@ -59,6 +60,15 @@ async fn fetch_secrets_from_key_vault(
|
|||
Err(err) => {
|
||||
log!("\n");
|
||||
error!("Failed to fetch secrets page: {}", err);
|
||||
let specific_error = err.downcast_ref::<HttpError>();
|
||||
if let Some(specific_error) = specific_error {
|
||||
// Check the contents of the specific error
|
||||
if specific_error.error_message().unwrap().to_string().contains("does not have secrets list permission on key vault") {
|
||||
info!("Make sure you have List permissions on the Key Vault.");
|
||||
} else if specific_error.error_message().unwrap().to_string().contains("is not authorized and caller is not a trusted service") {
|
||||
info!("Make sure you're on the Key Vaults Firewall allowlist.");
|
||||
}
|
||||
}
|
||||
return Err(err.into());
|
||||
}
|
||||
};
|
||||
|
@ -69,6 +79,7 @@ async fn fetch_secrets_from_key_vault(
|
|||
Ok(secret_values)
|
||||
}
|
||||
|
||||
|
||||
async fn fetch_secrets_from_page(
|
||||
client: &azure_security_keyvault::SecretClient,
|
||||
page: &KeyVaultGetSecretsResponse,
|
||||
|
@ -127,6 +138,7 @@ async fn fetch_and_send_secret(
|
|||
}
|
||||
Err(err) => {
|
||||
error!("Error fetching secret: {}", err);
|
||||
info!("Make sure you have Get permissions on the Key Vault.");
|
||||
(secret_id, String::new())
|
||||
}
|
||||
}
|
||||
|
|
188
tests/e2e.rs
Normal file
188
tests/e2e.rs
Normal file
|
@ -0,0 +1,188 @@
|
|||
use assert_cmd::prelude::*;
|
||||
use assert_fs::prelude::*;
|
||||
use assert_fs::TempDir;
|
||||
use std::process::Command;
|
||||
use predicates::prelude::*;
|
||||
use serial_test::serial;
|
||||
use std::env;
|
||||
|
||||
static BINARY: &str = "keyweave";
|
||||
static KEYVAULT: &str = "bvdbkeyweavetweukvt1";
|
||||
static FIREWALL_KEYVAULT: &str = "bvdbkeyweavetweukvt2";
|
||||
static NON_EXISTENT_KEYVAULT: &str = "bvdbkeyweavetweukvt3";
|
||||
|
||||
fn azure_cli_login(client_id: String, tenant_id: String, subscription_id: String) -> Result<(), std::io::Error> {
|
||||
Command::new("az")
|
||||
.arg("login")
|
||||
.arg("--identity")
|
||||
.arg("--username")
|
||||
.arg(client_id)
|
||||
.arg("--tenant")
|
||||
.arg(tenant_id)
|
||||
.output()?;
|
||||
|
||||
Command::new("az")
|
||||
.arg("account")
|
||||
.arg("set")
|
||||
.arg("--subscription")
|
||||
.arg(subscription_id)
|
||||
.output()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test with no access policies - expected to fail.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_no_access_policies() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_NO_ACCESS").expect("Failed to get AZURE_CLIENT_ID_NO_ACCESS"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(KEYVAULT)
|
||||
.arg("--output").arg(output_path.path());
|
||||
cmd.assert().failure().stderr(predicate::str::contains("Make sure you have List permissions on the Key Vault."));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
||||
/// Test with only Get access policy - expected to fail.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_only_get_access_policy() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_GET").expect("Failed to get AZURE_CLIENT_ID_GET"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(KEYVAULT)
|
||||
.arg("--output").arg(output_path.path());
|
||||
cmd.assert().failure().stderr(predicate::str::contains("Make sure you have List permissions on the Key Vault."));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
||||
/// Test with only List access policy - expected to succeed with get errors.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_only_list_access_policy() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_LIST").expect("Failed to get AZURE_CLIENT_ID_LIST"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(KEYVAULT)
|
||||
.arg("--output").arg(output_path.path());
|
||||
cmd.assert().success().stderr(predicate::str::contains("Make sure you have Get permissions on the Key Vault."));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
||||
/// Test with both Get and List access policies - expected to pass.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_get_and_list_access_policies() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_GET_LIST").expect("Failed to get AZURE_CLIENT_ID_GET_LIST"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(KEYVAULT)
|
||||
.arg("--output").arg(output_path.path());
|
||||
cmd.assert().success();
|
||||
|
||||
output_path.assert(predicate::path::is_file());
|
||||
output_path.assert(predicate::str::contains("testSecret=testSecretValue"));
|
||||
output_path.assert(predicate::str::contains("filterTestSecret=filterTestSecretValue"));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
||||
/// Test with both Get and List access policies and filter - expected to pass.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_get_and_list_access_policies_filter() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_GET_LIST").expect("Failed to get AZURE_CLIENT_ID_GET_LIST"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(KEYVAULT)
|
||||
.arg("--output").arg(output_path.path())
|
||||
.arg("--filter").arg("filter");
|
||||
cmd.assert().success();
|
||||
|
||||
output_path.assert(predicate::path::is_file());
|
||||
output_path.assert(predicate::str::contains("filterTestSecret=filterTestSecretValue"));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
||||
/// Test with both Get and List access policies on a Key Vault with Firewall - expected to fail.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_get_and_list_access_policies_firewall() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_GET_LIST").expect("Failed to get AZURE_CLIENT_ID_GET_LIST"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(FIREWALL_KEYVAULT)
|
||||
.arg("--output").arg(output_path.path());
|
||||
cmd.assert().failure().stderr(predicate::str::contains("Make sure you're on the Key Vaults Firewall allowlist."));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
||||
/// Test with both Get and List access policies on a non-existent Key Vault - expected to fail.
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_get_and_list_access_policies_non_existent() {
|
||||
azure_cli_login(
|
||||
env::var("AZURE_CLIENT_ID_GET_LIST").expect("Failed to get AZURE_CLIENT_ID_GET_LIST"),
|
||||
env::var("AZURE_TENANT_ID").expect("Failed to get AZURE_TENANT_ID"),
|
||||
env::var("AZURE_SUBSCRIPTION_ID").expect("Failed to get AZURE_SUBSCRIPTION_ID"),
|
||||
).expect("Failed to log in to Azure CLI");
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let output_path = temp_dir.child(".env");
|
||||
|
||||
let mut cmd = Command::cargo_bin(BINARY).unwrap();
|
||||
cmd.arg("--vault-name").arg(NON_EXISTENT_KEYVAULT)
|
||||
.arg("--output").arg(output_path.path());
|
||||
cmd.assert().failure().stderr(predicate::str::contains("Please check that the Key Vault exists or that you have no connectivity issues."));
|
||||
|
||||
temp_dir.close().unwrap();
|
||||
}
|
||||
|
Loading…
Reference in a new issue