Skip to content

S3lock#137

Merged
yehlo merged 7 commits into
feat/initial-devfrom
s3lock
May 6, 2026
Merged

S3lock#137
yehlo merged 7 commits into
feat/initial-devfrom
s3lock

Conversation

@yehlo
Copy link
Copy Markdown
Collaborator

@yehlo yehlo commented Apr 29, 2026

Description

What does this PR do?

This PR bundles three new operator capabilities plus several supporting fixes
and API/doc improvements. The features are independent but share generated CRDs
and webhook plumbing.

1. S3 Object Lock (WORM) end-to-end

Configurable, validated S3 Object Lock support spanning grid → tenant → bucket.

  • StorageGrid.status.s3ObjectLockAvailable — operator probes
    GET /grid/compliance-global and surfaces grid-wide capability
    (pkg/grid/objectlock.go,
    internal/controller/storagegrid_controller.go).
  • New S3ObjectLockSupported condition.
  • S3Tenant / S3TenantAccount: spec.s3ObjectLock = { mode, maxRetentionInDays }
    defines the per-tenant ceiling (Disabled < Governance < Compliance) and the
    cap on bucket retention. mode defaults to Disabled,
    maxRetentionInDays defaults to 0 (forces user to choose explicitly).
  • S3Bucket: spec.s3ObjectLock = { mode, retentionInDays } configures the
    default retention applied to new objects (existing objects keep their
    prior settings — documented on the field).
  • Validating webhooks
    (internal/webhook/objectlock_validation.go,
    s3bucket_webhook.go,
    s3tenant_webhook.go,
    s3tenantAccount_webhook.go):
    • Bucket mode may not exceed tenant mode; Compliance requires tenant=Compliance.
    • Compliance grid-wide requires StorageGrid.status.s3ObjectLockAvailable=true.
    • Lowering tenant mode or maxRetentionInDays is rejected if any owned
      bucket would be left in violation.
  • E2E coverage:
    test/e2e/chainsaw/s3bucket/governance/chainsaw-test.yaml.

⚠️ Breaking field change: S3Bucket.spec.retentionInDays is removed in
favor of spec.s3ObjectLock.retentionInDays. See migration notes below.

2. S3 Bucket Lifecycle Management

Operator-managed bucket lifecycle with drift detection.

  • New S3Bucket.spec.lifecycleManagement = { expirationInDays }
    (defaults to {expirationInDays: 0} = lifecycle disabled / removed).
  • expirationInDays > 0 maps to a single S3 Expiration.Days rule applied
    via the bucket's S3 endpoint (pkg/s3/lifecycle.go).
  • Status.LastAppliedLifecycle fingerprint for drift detection; reconcile
    re-applies on drift.
  • New LifecycleSynced condition; warning event emitted on versioned buckets
    noting that noncurrent versions are not removed by Expiration.Days.
  • E2E coverage:
    test/e2e/chainsaw/s3bucket/lifecycle/chainsaw-test.yaml.

3. Connection-Details Secret synthesis

Crossplane-style mountable Secret for S3Bucket and S3Access.

  • New spec.connectionDetails = { mode, destinationSecret } on S3Bucket
    and S3Access. mode: All (default) projects credentials + endpoint info
    into AWS-style env keys; mode: Disabled opts out.
  • Status.ConnectionDetailsSecretRef tracks the actually-deployed Secret
    name so renames and Disabled transitions clean up the previous Secret.
  • Default Secret names are kind-prefixed to prevent collisions when an
    S3Bucket and an S3Access share the same name in a namespace:
    • s3bucket-<name>-connection-details
    • s3access-<name>-connection-details
  • New shared helpers in pkg/kube/connection_details.go:
    • BuildConnectionDetailsData — assembles the AWS-style key/value map.
    • ReconcileOwnedSecret — creates/updates an owned Secret, derives labels
      from the owner GVK via the scheme, adopts orphan Secrets (no
      controllerRef), and rejects foreign-controlled Secrets with
      ErrSecretNotOwned (surfaced as OwnershipConflict event + condition).
    • DeleteOwnedSecret — idempotent name-based cleanup.
  • New S3EndpointConfig.URL and S3EndpointConfig.Protocol (default https)
    populated by the operator so consumers don't re-compose the endpoint URL.
  • E2E coverage:
    test/e2e/chainsaw/s3bucket/connection-details/chainsaw-test.yaml.

Supporting fixes & polish

  • fix(s3tenant): maxRetentionInDays defaults to 0 so users must
    explicitly opt in to a retention ceiling (avoids surprising defaults).
  • chore(apidoc): improved kubebuilder doc comments across types for better
    kubectl explain / IDE tooltips.
  • README and sample manifests updated for all three features.
  • Generated CRDs and deepcopy regenerated via make generate manifests.

Why is this change needed?

  • Object Lock unlocks regulated/WORM workloads on StorageGRID via Kubernetes-
    native APIs, with safety rails so users can't construct invalid grid/tenant/
    bucket combinations.
  • Lifecycle management removes a manual aws s3api put-bucket-lifecycle-…
    step and keeps configuration declarative + drift-corrected.
  • Connection-details Secrets remove boilerplate for consuming workloads, which
    can now envFrom: - secretRef: a single Secret to gain S3 access.

Related Issues

  • Related to: #

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (S3Bucket.spec.retentionInDays removed)
  • 📚 Documentation update
  • ✅ Test updates (adding or updating tests)
  • 🔧 Configuration changes (CRDs, samples, RBAC)

Conventional Commit Format

Suggested PR title:

feat(bucket)!: add S3 Object Lock, lifecycle management, and connection-details Secrets

Included commits:

  • feat: introduce s3objectLock API to configure and manage worm
  • feat: introduce bucket lifecycle management
  • feat(bucket/access): introduce connectiondetails
  • fix: include kind in secretname
  • chore(apidoc): improve tooltips
  • fix(s3tenant): set default maxRetention to 0 to force user to set something they need

Testing Checklist

  • Tests added or updated
  • All existing tests pass locally
  • Manual testing performed
  • Test coverage maintained or improved

Test commands run:

make generate manifests
make build
go vet ./...
make test
make test-e2e   # chainsaw suites: governance, lifecycle, connection-details

E2E suites added:

Documentation Checklist

Security Checklist

  • No secrets or credentials committed
  • Input validation implemented in webhooks (Object Lock matrix, retention
    caps, downgrade safety)
  • Security implications considered and documented
  • Foreign-controlled Secrets are never overwritten (ownership guard)
  • Error messages don't leak sensitive information

Breaking Changes

Does this PR introduce breaking changes?

  • Yes
  • No

Migration:

  • S3Bucket.spec.retentionInDaysS3Bucket.spec.s3ObjectLock.retentionInDays
    (and set s3ObjectLock.mode to Governance or Compliance to match prior
    intent). Existing buckets without the new field default to Disabled.
    Users who previously relied on retentionInDays > 0 must update their
    manifests
    before applying.
  • Tenants opting in to Object Lock must explicitly set
    spec.s3ObjectLock.maxRetentionInDays (default is 0, which forbids any
    bucket retention).

yehlo and others added 7 commits April 28, 2026 14:26
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
@yehlo yehlo merged commit 4e05244 into feat/initial-dev May 6, 2026
@yehlo yehlo deleted the s3lock branch May 6, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant