Skip to content

chore: Adds PoC sa org rotation DO NOT MERGE - #4487

Draft
EspenAlbert wants to merge 11 commits into
masterfrom
CLOUDP-381539_org_resource_sa_rotation_support
Draft

EspenAlbert wants to merge 11 commits into
masterfrom
CLOUDP-381539_org_resource_sa_rotation_support

Conversation

@EspenAlbert

Copy link
Copy Markdown
Collaborator

Description

Link to any related issue(s): CLOUDP-381539

Type of change:

  • Bug fix (non-breaking change which fixes an issue). Please, add the "bug" label to the PR.
  • New feature (non-breaking change which adds functionality). Please, add the "enhancement" label to the PR. A migration guide must be created or updated if the new feature will go in a major version.
  • Breaking change (fix or feature that would cause existing functionality to not work as expected). Please, add the "breaking change" label to the PR. A migration guide must be created or updated.
  • This change requires a documentation update
  • Documentation fix/enhancement

Required Checklist:

  • I have signed the MongoDB CLA
  • I have read the contributing guides
  • I have checked that this change does not generate any credentials and that they are NOT accidentally logged anywhere.
  • I have added tests that prove my fix is effective or that my feature works per HashiCorp requirements
  • I have added any necessary documentation (if appropriate)
  • I have run make fix and verified my code
  • If changes include deprecations or removals I have added appropriate changelog entries.
  • If changes include removal or addition of 3rd party GitHub actions, I updated our internal document. Reach out to the APIx Integration slack channel to get access to the internal document.

Further comments

Copilot AI review requested due to automatic review settings June 3, 2026 17:34
@EspenAlbert EspenAlbert changed the title chore: poc sa org rotation DO NOT MERGE chore: Adds PoC sa org rotation DO NOT MERGE Jun 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds experimental proof-of-concept Terraform Plugin Framework resources to demonstrate ModifyPlan-driven service account client secret rotation, including a mock-backed version (mongodbatlas_organization2) and a real-Atlas version (mongodbatlas_organization3). It also updates the provider’s internal service-account OAuth handling to support multiple credential sets within a single provider process (needed for rotation flows).

Changes:

  • Introduces new PoC resources mongodbatlas_organization2 (mock store) and mongodbatlas_organization3 (Atlas API-backed) with rotation scheduling/forcing behavior.
  • Registers the PoC resources in the framework provider and adds unit + acceptance tests for rotation behavior.
  • Reworks service account OAuth token caching to be keyed by credential tuple (client ID/secret/base URL/terraform version), allowing rotation to change secrets without breaking subsequent reads.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
POC_README.md Documents both PoCs, usage, limitations, and test commands.
internal/testutil/acc/pre_check.go Adds acceptance-test skip helper for org-owner-dependent PoC tests.
internal/service/organization3/resource.go Implements mongodbatlas_organization3 CRUD + ModifyPlan rotation workflow.
internal/service/organization3/resource_test.go Real-Atlas acceptance test covering rotation lifecycle.
internal/service/organization3/resource_schema.go Defines schema for org3 rotation block + secret metadata objects.
internal/service/organization3/objects.go Object conversions and plan-shaping helpers for rotation.
internal/service/organization3/model.go Rotation policy/decision logic and helpers.
internal/service/organization3/model_test.go Unit tests for rotation decisions and ModifyPlan behavior.
internal/service/organization3/auth.go Builds Atlas clients using SA creds from state when available.
internal/service/organization3/api.go Atlas API calls for org + SA secret create/delete.
internal/service/organization2/store.go Adds a persisted local JSON store for the mock PoC backend.
internal/service/organization2/resource.go Implements mongodbatlas_organization2 CRUD + ModifyPlan rotation behavior.
internal/service/organization2/resource_test.go Mock-backed acceptance tests for org2 rotation scenarios.
internal/service/organization2/resource_schema.go Defines schema for org2 rotation block and state fields.
internal/service/organization2/model.go Rotation timing and interval parsing helpers for org2.
internal/service/organization2/model_test.go Unit tests for org2 rotation due logic + ModifyPlan shaping.
internal/provider/provider.go Registers organization2 and organization3 resources in the provider.
internal/config/service_account.go Replaces single global SA token source with a credential-keyed token cache.
internal/config/service_account_test.go Adds tests validating new SA token cache semantics.
internal/config/export_test.go Exposes internal SA token-cache helpers for tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +18 to +21
req := admin.NewCreateOrganizationRequest(name)
req.OrgOwnerId = new(orgOwnerID)
skipDefaultAlerts := true
req.SkipDefaultAlertsSettings = &skipDefaultAlerts
Comment on lines +275 to +284
func (r *organization2RS) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state TFModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

if err := deleteStoreEntry(state.Name.ValueString()); err != nil {
resp.Diagnostics.AddError(errorUpdate, fmt.Sprintf("failed to persist mock store: %s", err))
}
Comment on lines +323 to +336
if plan.ClientSecretRotation.IsNull() {
state.Name = plan.Name
state.ClientSecretRotation = types.ObjectNull(rotationObjectType.AttrTypes)
resp.Diagnostics.Append(resp.State.Set(ctx, state)...)
return
}

planRotation, diags := RotationFromObject(ctx, plan.ClientSecretRotation)
resp.Diagnostics.Append(diags...)
stateRotation, stateDiags := RotationFromObject(ctx, state.ClientSecretRotation)
resp.Diagnostics.Append(stateDiags...)
if resp.Diagnostics.HasError() {
return
}
@svc-apix-Bot

Copy link
Copy Markdown
Contributor

This PR has gone 7 days without any activity and meets the project’s definition of "stale". This will be auto-closed if there is no new activity over the next 7 days. If the issue is still relevant and active, you can simply comment with a "bump" to keep it open, or add the label "not_stale". Thanks for keeping our repository healthy!

@EspenAlbert EspenAlbert added the not_stale Not stale issue or PR label Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

not_stale Not stale issue or PR stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants