mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-28 20:06:14 +00:00
* fix(s3api): route STS GetFederationToken requests to STS handler (#9157) The STS GetFederationToken handler was implemented but never reachable. Three routing gaps sent requests to the S3/IAM path instead of STS: - No explicit mux route for Action=GetFederationToken in the URL query - iamMatcher did not exclude GetFederationToken, so authenticated POSTs with Action in the form body were matched and dispatched to IAM - UnifiedPostHandler only dispatched AssumeRole* and GetCallerIdentity to STS, leaving GetFederationToken to fall through to DoActions and return NotImplemented Add the missing route, the matcher exclusion, and the dispatch branch. Also wire TestSTS, TestAssumeRoleWithWebIdentity, and TestServiceAccount into the s3-iam-tests workflow as a new "sts" matrix entry. Before this change, none of test/s3/iam/s3_sts_get_federation_token_test.go's four test functions ran in CI, which is why this regression shipped. * test(iam): make orphaned STS/service-account tests pass under auth-enabled CI Follow-up to wiring STS tests into CI: fixes several pre-existing issues that made the newly-included tests fail locally. Server fixes: - weed/s3api/s3api_sts.go: handleGetFederationToken no longer 500s when the caller is a legacy S3-config identity (not in the IAM user store). Previously any GetPoliciesForUser error short-circuited to InternalError, which hard-failed every SigV4 caller using keys from -s3.config. - weed/s3api/s3api_embedded_iam.go: CreateServiceAccount now generates IDs in the sa:<parent>:<uuid> format required by credential.ValidateServiceAccountId. The old "sa-XXXXXXXX" format failed the persistence-layer regex and caused every CreateServiceAccount call to return 500 once a filer-backed credential store validated the ID. Test helpers: - test/s3/iam/s3_sts_assume_role_test.go: callSTSAPIWithSigV4 no longer sets req.Header["Host"]. aws-sdk-go v1 v4.Signer already signs Host from req.URL.Host, and a manual Host header made the signer emit host;host in SignedHeaders, producing SignatureDoesNotMatch. Updated missing_role_arn subtest to match the existing SeaweedFS behavior (user-context assumption). - test/s3/iam/s3_service_account_test.go: callIAMAPI now SigV4-signs requests when STS_TEST_{ACCESS,SECRET}_KEY env vars are set. Unsigned IAM writes otherwise fall through to the STS fallback and return InvalidAction. CI matrix: - .github/workflows/s3-iam-tests.yml: skip TestServiceAccountLifecycle/use_service_account_credentials only. The rest of the service-account suite passes; that one subtest depends on a separate credential-reload issue where new ABIA keys briefly register into accessKeyIdent but aren't persisted to the filer, so they vanish on the next reload. Out of scope for the #9157 GetFederationToken fix. * fix(credential): accept AWS IAM username chars in service-account IDs Gemini review on #9167 pointed out that ServiceAccountIdPattern's parent-user segment was more restrictive than an AWS IAM username: `[A-Za-z0-9_-]` vs. IAM's `[\w+=,.@-]`. Realistic usernames with `@`, `.`, `+`, `=`, or `,` (e.g. email-style principals) would fail validation at the filer store even though the embedded IAM API happily created them. Broaden the regex to `[A-Za-z0-9_+=,.@-]` (matching the AWS IAM spec at https://docs.aws.amazon.com/IAM/latest/APIReference/API_User.html) and add a table-driven test that locks the expansion in. * address PR review feedback on #9167 All five review items were valid; changes keyed to review bullets: - weed/s3api/s3api_sts.go: handleGetFederationToken no longer swallows arbitrary policy-lookup failures. Only credential.ErrUserNotFound is treated leniently (the legacy-config SigV4 path); any other error now returns InternalError so we don't mint tokens with an incomplete policy set. - weed/credential/grpc/grpc_identity.go: GetUser translates gRPC NotFound back to credential.ErrUserNotFound so errors.Is(...) above matches for gRPC-backed stores, not just memory/filer-direct. - weed/s3api/s3api_embedded_iam.go: CreateServiceAccount now validates the generated saId against credential.ValidateServiceAccountId before returning. Surfaces a client 400 with the offending ID instead of the opaque 500 that used to bubble up from the persistence layer. - weed/s3api/s3api_server_routing_test.go: seed a routing-test identity with a known AK/SK, sign TestRouting_GetFederationTokenAuthenticatedBody with aws-sdk-go v4.Signer so the request actually passes AuthSignatureOnly. Assert 503 ServiceUnavailable (from STSHandlers with no stsService) instead of just NotEqual(501) — 503 proves the dispatch reached STSHandlers.HandleSTSRequest. - test/s3/iam/s3_service_account_test.go: callIAMAPI signs with service="iam" instead of "s3" (SeaweedFS verifies against whichever service the client signed with, but "iam" is semantically correct). - weed/credential/validation_test.go: add positive rows for an uppercase parent (sa:ALICE:...) and a canonical hyphenated UUID suffix (sa:alice:123e4567-e89b-12d3-a456-426614174000).
310 lines
9.5 KiB
YAML
310 lines
9.5 KiB
YAML
name: "S3 IAM Integration Tests"
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'weed/iam/**'
|
|
- 'weed/s3api/**'
|
|
- 'weed/credential/**'
|
|
- 'weed/pb/**'
|
|
- 'test/s3/iam/**'
|
|
- '.github/workflows/s3-iam-tests.yml'
|
|
push:
|
|
branches: [ master ]
|
|
paths:
|
|
- 'weed/iam/**'
|
|
- 'weed/s3api/**'
|
|
- 'weed/credential/**'
|
|
- 'weed/pb/**'
|
|
- 'test/s3/iam/**'
|
|
- '.github/workflows/s3-iam-tests.yml'
|
|
|
|
concurrency:
|
|
group: ${{ github.head_ref }}/s3-iam-tests
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: weed
|
|
|
|
jobs:
|
|
# Unit tests for IAM components
|
|
iam-unit-tests:
|
|
name: IAM Unit Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 15
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version-file: 'go.mod'
|
|
id: go
|
|
|
|
- name: Get dependencies
|
|
run: |
|
|
go mod download
|
|
|
|
- name: Run IAM Unit Tests
|
|
timeout-minutes: 10
|
|
run: |
|
|
set -x
|
|
echo "=== Running IAM STS Tests ==="
|
|
go test -v -timeout 5m ./iam/sts/...
|
|
|
|
echo "=== Running IAM Policy Tests ==="
|
|
go test -v -timeout 5m ./iam/policy/...
|
|
|
|
echo "=== Running IAM Integration Tests ==="
|
|
go test -v -timeout 5m ./iam/integration/...
|
|
|
|
echo "=== Running S3 API IAM Tests ==="
|
|
go test -v -timeout 5m ./s3api/... -run ".*IAM.*|.*JWT.*|.*Auth.*"
|
|
|
|
- name: Upload test results on failure
|
|
if: failure()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: iam-unit-test-results
|
|
path: |
|
|
weed/testdata/
|
|
weed/**/testdata/
|
|
retention-days: 3
|
|
|
|
# S3 IAM integration tests with SeaweedFS services
|
|
s3-iam-integration-tests:
|
|
name: S3 IAM Integration Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 25
|
|
strategy:
|
|
matrix:
|
|
test-type: ["basic", "advanced", "policy-enforcement", "group", "sts"]
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version-file: 'go.mod'
|
|
id: go
|
|
|
|
- name: Install SeaweedFS
|
|
working-directory: weed
|
|
run: |
|
|
go install -buildvcs=false
|
|
|
|
- name: Run S3 IAM Integration Tests - ${{ matrix.test-type }}
|
|
timeout-minutes: 20
|
|
working-directory: test/s3/iam
|
|
run: |
|
|
set -x
|
|
echo "=== System Information ==="
|
|
uname -a
|
|
free -h
|
|
df -h
|
|
echo "=== Starting S3 IAM Integration Tests (${{ matrix.test-type }}) ==="
|
|
|
|
# Set WEED_BINARY to use the installed version
|
|
export WEED_BINARY=$(which weed)
|
|
export TEST_TIMEOUT=15m
|
|
|
|
# Run tests based on type
|
|
case "${{ matrix.test-type }}" in
|
|
"basic")
|
|
echo "Running basic IAM functionality tests..."
|
|
make clean setup start-services wait-for-services
|
|
go test -v -timeout 15m -run "TestS3IAMAuthentication|TestS3IAMBasicWorkflow|TestS3IAMTokenValidation|TestIAMUserManagement|TestIAMAccessKeyManagement|TestIAMPolicyManagement" ./...
|
|
;;
|
|
"advanced")
|
|
echo "Running advanced IAM feature tests..."
|
|
make clean setup start-services wait-for-services
|
|
go test -v -timeout 15m -run "TestS3IAMSessionExpiration|TestS3IAMMultipart|TestS3IAMPresigned" ./...
|
|
;;
|
|
"policy-enforcement")
|
|
echo "Running policy enforcement tests..."
|
|
make clean setup start-services wait-for-services
|
|
go test -v -timeout 15m -run "TestS3IAMPolicyEnforcement|TestS3IAMBucketPolicy|TestS3IAMContextual" ./...
|
|
;;
|
|
"group")
|
|
echo "Running IAM group management tests..."
|
|
make clean setup start-services wait-for-services
|
|
go test -v -timeout 15m -run "TestIAMGroup" ./...
|
|
;;
|
|
"sts")
|
|
echo "Running STS and service account tests..."
|
|
make clean setup start-services wait-for-services
|
|
# SigV4-signed STS calls need admin credentials matching test_config.json.
|
|
# Tests default to "admin"/"admin" when env vars are unset, which don't exist.
|
|
export STS_TEST_ACCESS_KEY=test-access-key
|
|
export STS_TEST_SECRET_KEY=test-secret-key
|
|
# The use_service_account_credentials subtest is excluded because
|
|
# newly-created service-account access keys are not currently
|
|
# persisted to the filer after CreateServiceAccount — a
|
|
# pre-existing sync issue tracked separately from the
|
|
# GetFederationToken routing fix this PR addresses.
|
|
go test -v -timeout 15m \
|
|
-run "TestSTS|TestAssumeRoleWithWebIdentity|TestServiceAccount" \
|
|
-skip "TestServiceAccountLifecycle/use_service_account_credentials" \
|
|
./...
|
|
;;
|
|
*)
|
|
echo "Unknown test type: ${{ matrix.test-type }}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Always cleanup
|
|
make stop-services
|
|
|
|
- name: Show service logs on failure
|
|
if: failure()
|
|
working-directory: test/s3/iam
|
|
run: |
|
|
echo "=== Service Logs ==="
|
|
echo "--- Master Log ---"
|
|
tail -50 weed-master.log 2>/dev/null || echo "No master log found"
|
|
echo ""
|
|
echo "--- Filer Log ---"
|
|
tail -50 weed-filer.log 2>/dev/null || echo "No filer log found"
|
|
echo ""
|
|
echo "--- Volume Log ---"
|
|
tail -50 weed-volume.log 2>/dev/null || echo "No volume log found"
|
|
echo ""
|
|
echo "--- S3 API Log ---"
|
|
tail -50 weed-s3.log 2>/dev/null || echo "No S3 log found"
|
|
echo ""
|
|
|
|
echo "=== Process Information ==="
|
|
ps aux | grep -E "(weed|test)" || true
|
|
netstat -tlnp | grep -E "(8333|8888|9333|8080)" || true
|
|
|
|
- name: Upload test logs on failure
|
|
if: failure()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: s3-iam-integration-logs-${{ matrix.test-type }}
|
|
path: test/s3/iam/weed-*.log
|
|
retention-days: 5
|
|
|
|
# Distributed IAM tests
|
|
s3-iam-distributed-tests:
|
|
name: S3 IAM Distributed Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 25
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version-file: 'go.mod'
|
|
id: go
|
|
|
|
- name: Install SeaweedFS
|
|
working-directory: weed
|
|
run: |
|
|
go install -buildvcs=false
|
|
|
|
- name: Run Distributed IAM Tests
|
|
timeout-minutes: 20
|
|
working-directory: test/s3/iam
|
|
run: |
|
|
set -x
|
|
echo "=== System Information ==="
|
|
uname -a
|
|
free -h
|
|
|
|
export WEED_BINARY=$(which weed)
|
|
export TEST_TIMEOUT=15m
|
|
|
|
# Test distributed configuration
|
|
echo "Testing distributed IAM configuration..."
|
|
make clean setup
|
|
|
|
# Start services with distributed IAM config
|
|
echo "Starting services with distributed configuration..."
|
|
make start-services
|
|
make wait-for-services
|
|
|
|
# Run distributed-specific tests
|
|
export ENABLE_DISTRIBUTED_TESTS=true
|
|
go test -v -timeout 15m -run "TestS3IAMDistributedTests" ./... || {
|
|
echo "❌ Distributed tests failed, checking logs..."
|
|
make logs
|
|
exit 1
|
|
}
|
|
|
|
make stop-services
|
|
|
|
- name: Upload distributed test logs
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: s3-iam-distributed-logs
|
|
path: test/s3/iam/weed-*.log
|
|
retention-days: 7
|
|
|
|
# Performance and stress tests
|
|
s3-iam-performance-tests:
|
|
name: S3 IAM Performance Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 30
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version-file: 'go.mod'
|
|
id: go
|
|
|
|
- name: Install SeaweedFS
|
|
working-directory: weed
|
|
run: |
|
|
go install -buildvcs=false
|
|
|
|
- name: Run IAM Performance Benchmarks
|
|
timeout-minutes: 25
|
|
working-directory: test/s3/iam
|
|
run: |
|
|
set -x
|
|
echo "=== Running IAM Performance Tests ==="
|
|
|
|
export WEED_BINARY=$(which weed)
|
|
export TEST_TIMEOUT=20m
|
|
|
|
make clean setup start-services wait-for-services
|
|
|
|
# Run performance tests (benchmarks disabled for CI)
|
|
echo "Running performance tests..."
|
|
export ENABLE_PERFORMANCE_TESTS=true
|
|
go test -v -timeout 15m -run "TestS3IAMPerformanceTests" ./... || {
|
|
echo "❌ Performance tests failed"
|
|
make logs
|
|
exit 1
|
|
}
|
|
|
|
make stop-services
|
|
|
|
- name: Upload performance test results
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: s3-iam-performance-results
|
|
path: |
|
|
test/s3/iam/weed-*.log
|
|
test/s3/iam/*.test
|
|
retention-days: 7
|