Skip to content

Fix Org Groups pagination response shape (meta.page + links)#4023

Merged
api-clients-generation-pipeline[bot] merged 1 commit into
masterfrom
datadog-api-spec/generated/5579
May 4, 2026
Merged

Fix Org Groups pagination response shape (meta.page + links)#4023
api-clients-generation-pipeline[bot] merged 1 commit into
masterfrom
datadog-api-spec/generated/5579

Conversation

@api-clients-generation-pipeline
Copy link
Copy Markdown
Contributor

@api-clients-generation-pipeline api-clients-generation-pipeline Bot added the changelog/Fixed Fixed features results into a bug fix version bump label May 1, 2026
@api-clients-generation-pipeline api-clients-generation-pipeline Bot requested review from a team as code owners May 1, 2026 19:20
@api-clients-generation-pipeline api-clients-generation-pipeline Bot added the changelog/Fixed Fixed features results into a bug fix version bump label May 1, 2026
@api-clients-generation-pipeline api-clients-generation-pipeline Bot merged commit 2ad4eb4 into master May 4, 2026
29 checks passed
@api-clients-generation-pipeline api-clients-generation-pipeline Bot deleted the datadog-api-spec/generated/5579 branch May 4, 2026 18:23
github-actions Bot pushed a commit that referenced this pull request May 4, 2026
Co-authored-by: ci.datadog-api-spec <packages@datadoghq.com> 2ad4eb4
github-actions Bot pushed a commit to ConnectionMaster/datadog-api-client-go that referenced this pull request May 4, 2026
Co-authored-by: ci.datadog-api-spec <packages@datadoghq.com> 2ad4eb4
k-phan added a commit to DataDog/terraform-provider-datadog that referenced this pull request May 4, 2026
…n fix

Pulls in DataDog/datadog-api-client-go#4023, which fixes the Org Groups
pagination response shape (adds Links and reworks Meta on list responses).
Our code only reads resp.GetData() so no behavior change is needed; this
just unblocks testing the upstream fix without waiting for a release cut.

All cassette-replay tests pass against the new pin.
gh-worker-dd-mergequeue-cf854d Bot pushed a commit to DataDog/terraform-provider-datadog that referenced this pull request May 7, 2026
)

[datadog_org_group] Add new org group resource

Add datadog_org_group resource supporting CRUD operations via the
OrgGroups v2 API, with acceptance tests and cassettes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

[datadog_org_group_membership] Add new org group membership resource

Adds a Terraform resource for managing an organization's membership in
an org group. Since the API has no create/delete endpoints, the resource
uses ListOrgGroupMemberships + UpdateOrgGroupMembership for create, and
delete is state-only (the org remains in its current group).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

[datadog_org_group_policy] Add new org group policy resource

Adds a Terraform resource for managing Datadog org group policies. The
policy content is exposed as a normalized JSON string; policy_name,
policy_type, and org_group_id are RequiresReplace since the API has no
path to mutate them in place.

Also fixes errorlint and revive issues flagged by golangci-lint on the
existing org_group and org_group_membership tests (use %w for error
wrapping; move context.Context to the first parameter in test helpers).

Depends on a datadog-api-client-go version that includes the new
GetOrgGroupPolicy endpoint; CI will fail until that bump lands.

[datadog_org_group_policy_override] Add new org group policy override resource

Adds a Terraform resource for managing per-org exemptions to org-group
policies. Every field forms part of the natural key (org_group_id +
policy_id + org_uuid + org_site) so everything is RequiresReplace and
Update is unreachable. content is Computed-only because the API records
the org's config value at override time rather than accepting one on
create.

Tests cover three override-specific behaviors:

- Basic CRUD + RequiresReplace on policy_id + import round-trip.
- ENFORCE cascade: when the parent policy transitions to ENFORCE,
  overrides are auto-deleted server-side; Terraform's Read catches the
  404 and reports drift on next plan.
- Auto-creation: a three-step flow seeds the org's config via an ENFORCE
  policy, then creates a new DEFAULT policy with a mismatching value and
  asserts the server auto-created an override. The two policies are in
  separate apply steps so Terraform's destroy-then-create ordering
  doesn't cause the backend to treat the DEFAULT policy as an update of
  the ENFORCE one (which would skip override computation).

Depends on a datadog-api-client-go version that includes the new
{Create,Get,Update,Delete,List}OrgGroupPolicyOverride endpoints; CI will
fail until that bump lands.

[datadog_org_group data sources] Add four data sources for org group discovery

Adds four plural data sources, one per List endpoint on OrgGroupsApi:

- datadog_org_groups: enumerate all groups in the tenant.
- datadog_org_group_memberships: list memberships, optionally filtered
  by org_group_id or org_uuid (both server-side).
- datadog_org_group_policies: list policies within a group, optionally
  filtered by policy_name (server-side).
- datadog_org_group_policy_overrides: list overrides within a group,
  optionally filtered by policy_id (server-side) or org_uuid (client-side
  since the API doesn't accept an org_uuid filter on this endpoint).

These enable discovery and adoption workflows the resources alone don't
cover. Primary use case: auto-created overrides can be enumerated via
datadog_org_group_policy_overrides and bulk-adopted with for_each +
import {} blocks.

Each data source auto-paginates internally (page_size 100) so callers
don't need to reason about pagination. Content fields on policies and
overrides are exposed as raw JSON strings — users can jsondecode() if
they need to parse.

Tests follow the record/replay pattern from the resource tests. Tests
that touch shared org membership state (memberships, overrides) are
non-parallel and use t.Cleanup(restoreOrgMembership(...)) to guarantee
the test org returns to its original group regardless of outcome.

Depends on the same datadog-api-client-go version as the override
resource; CI will fail until the client bump lands.

[datadog_org_group data sources] Record cassettes + enable List unstable ops

Adds recorded cassettes for all four data source acceptance tests, URL-
normalized to api.datadoghq.com for CI replay.

Also enables the two List unstable operations that were previously
unused by the resources (and thus not flipped on in the provider):

- v2.ListOrgGroups
- v2.ListOrgGroupPolicies

v2.ListOrgGroupMemberships and v2.ListOrgGroupPolicyOverrides were
already enabled in the resource PRs.

All 10 org_group tests (4 resources + 4 data sources + 2 extra override
cases) pass in both record and replay.

[datadog_org_group] Re-record resource cassettes with current site format

Re-records TestAccDatadogOrgGroup_Basic and TestAccDatadogOrgGroupMembership_Basic
against staging. The backend now returns the short site name (`us1`) in
the `owner_org_site` / `org_site` response fields instead of the old
datacenter-specific value (`us1.staging.dog`), so the previously
recorded cassettes leaked staging-env hints into committed test data.

New cassettes contain no `staging` or `datad0g` references. All 10
org_group tests still pass in both record and replay modes.

[datadog_org_group docs] Generate Registry docs for resources + data sources

Runs `make docs` to produce Terraform Registry markdown for the four
new resources and four new data sources. Pure generator output — no
hand edits.

[datadog_org_group docs] Document ENFORCE cascade, delete, auto-creation

Adds tfplugindocs templates for the policy and override resources with
"Behavior notes" sections covering three behaviors that aren't obvious
from the auto-generated schema:

- ENFORCE cascade: transitioning a policy to ENFORCE tier atomically
  deletes all overrides for that policy server-side. Override resource
  blocks must be removed from configuration in the same commit to avoid
  FailedPrecondition errors on subsequent applies.
- Delete behavior: removing an override resets the target org's config
  value to match the policy (via server-side propagation on delete), not
  merely removing the exemption marker. `terraform state rm` is the
  escape hatch for "stop managing but keep the org's current value."
- Server-side auto-creation: overrides are created automatically on
  (a) membership changes into a group with mismatching policies and
  (b) policy create/update with non-ENFORCE tier against mismatching
  member orgs.

Also corrects the org_site schema description to reflect the short site
name format (us1, eu1, us1-fed) rather than the obsolete datacenter
identifier.

[datadog_org_group docs] Add Example Usage sections for each resource and data source

Adds minimal Terraform example files under examples/ and tfplugindocs
templates that reference them, so every Registry page for the org_group
resources and data sources has a worked example alongside the schema
table.

- Resource examples show a single-purpose config (create one group,
  move an org, apply a policy, exempt an org).
- The override example includes a dependent membership resource so the
  example is apply-ready end-to-end.
- Data source examples show each filter combination the data source
  supports (e.g., list-all and filter-by-name for policies).
- All four resources get an `import.sh` + Import section.
- The org_group_membership template also documents the in-place
  org_group_id update vs. replacement semantics, and the state-only
  destroy behavior.

[datadog_org_group docs] Drop custom templates, move notes into resource Description

Removes the eight tfplugindocs templates added for the org_group
resources and data sources. They were stylistic outliers — only ~3
other resources out of ~130 in this repo use custom templates, with
the rest relying on the schema-level Description and attribute
MarkdownDescription fields for any non-schema content.

Moves the Behavior notes content into the top-level Description string
on each affected resource:

- datadog_org_group_membership: in-place org_group_id update semantics
  and state-only destroy behavior.
- datadog_org_group_policy: member-org side effects on non-ENFORCE
  policy create/update, and the ENFORCE cascade.
- datadog_org_group_policy_override: server-side auto-creation triggers,
  delete-resets-to-policy behavior, and the ENFORCE cascade.

Example Usage and Import sections still render — tfplugindocs' default
template auto-includes them from the examples/ directory when no custom
template overrides the render. Net result: same rendered docs, minus
eight files of template boilerplate, aligned with the rest of the
provider.

[datadog_org_group docs] Move policy/override behavior notes to templates

Restores tfplugindocs templates for the two resources whose behavior
notes don't fit cleanly into the repo's default `Description`-only
pattern: `datadog_org_group_policy` and `datadog_org_group_policy_override`.

Both have cross-cutting lifecycle behaviors (auto-creation, delete
semantics, ENFORCE cascade) that span multiple paragraphs and multiple
resources — the kind of content that reads as a "Behavior notes"
section rather than inline with the schema table.

Trims each resource's Go `Description` back to a one-line summary; the
multi-paragraph prose now lives in the template files where it belongs.
Leaves `datadog_org_group` and `datadog_org_group_membership`
template-free (their Descriptions are short enough to live inline,
matching the convention used by ~97% of other resources in this repo).

[datadog_org_group docs] Move membership behavior notes to template

Same treatment as policy/override: trim the inline Description to a
one-liner and move the in-place-move and state-only-destroy notes into
a dedicated "Behavior notes" section in the template. Consistent with
the other two resources in the stack whose lifecycle semantics don't
fit the default schema-only page layout.

The only org_group resource still template-free is `datadog_org_group`
itself — it has no non-schema behaviors to document.

[datadog_org_group] Address dual-review feedback

Applies fixes for 17 findings from the Claude + Codex dual review. Skipped
items where the existing behavior matches conventions in the rest of the
provider or where the fix would add complexity without real payoff.

Resource-level:

- Delete methods in org_group, org_group_policy, org_group_policy_override
  now emit a diagnostic when the state ID fails UUID parsing, instead of
  silently returning success.
- Override's Update stub now adds an error diagnostic so an accidental
  future schema change that makes Update reachable fails loudly rather
  than silently no-op'ing.
- updateState helpers on membership, policy, and override now fail with
  a clear error when the server omits a required relationship from the
  response, instead of leaving state fields at their prior value.
- Policy's updateState preserves the prior policy_type in state when the
  server response omits it; policy_type is RequiresReplace so empty
  server values must not force a spurious replace.
- datadog_org_group_membership's org_site attribute is now pure Computed
  instead of Optional+Computed, since the membership update endpoint
  doesn't accept attributes and user-supplied values were silently dropped.
- All "response contains unparsedObject" diagnostics now include the
  resource name so Sentry traces can distinguish call sites.
- Added LengthAtLeast(1) validators to name/policy_name/org_site fields.

Data-source-level:

- Pagination loops now have an explicit maxPages safety counter.
- Empty-string fallbacks for missing relationship IDs replaced with null.
- Overrides data source logs a debug line when encountering a zero-UUID row.

Tests:

- TestAccDatadogOrgGroupMembership_Basic now has a t.Cleanup safety net.
- New TestAccDatadogOrgGroupMembership_NoMembershipFound covers the
  error path for a valid-format-but-nonexistent org_uuid.
- TestAccDatadogOrgGroupPolicyOverride_AutoCreation verifies the
  auto-created override is readable end-to-end via the provider's Read
  path.
- restoreOrgMembership cleanup uses t.Errorf so failures surface in CI.
- Clarified HACK comment and cascadeCapturedPolicyID documentation.

Regenerated cassettes for the three tests with behavioral changes.

Skipped items: nil-panic guard on data source Configure (overwhelming
convention in this repo is to not check); helpers for UUID parsing and
pagination (no helper convention); content typing alignment in data
sources (deliberate — callers can jsondecode); discarding http.Response
from mutating calls (consistent with rest of provider); structural
duplication between resource and data-source models (repo convention).

[datadog_org_group] Address second-round review feedback

Covers 20 review items from /tmp/org-group-review-feedback.md. Highlights:

- Data sources now emit error diagnostics on missing relationships (consistent
  with the membership resource) and use duplicate-row detection to bail on
  pagination loops instead of a silent page-count cap.
- Schema gains plan-time uuidValidator on every UUID input and
  UseStateForUnknown on owner_org_* so refreshes don't churn plans.
- Policy + override resources switched to GetDataOk() to surface malformed
  relationships rather than silently writing zero-UUID strings.
- Membership Delete adds a warning explaining the server-side no-op and its
  destroy-order implications; template behavior notes updated to match.
- Tests: renamed _NoMembershipFound to _UnknownOrgReturns404 (the server's
  real behavior), added TestCheckResourceAttrPair on the membership update,
  gated restoreOrgMembership cleanup on t.Failed(), reset cascade globals for
  -count=N runs, asserted ENFORCE cascade via a 404 Get, introduced a composite
  CheckDestroy covering override+policy+org_group for all 3 override tests and
  all 4 data source tests, and replaced the auto-override Get probe with an
  actual provider.Read() invocation via a synthetic prior state.
- New TestAccDatadogOrgGroupPolicyOverride_OrgGroupIdRequiresReplace covers
  the org_group_id RequiresReplace plancheck; org_uuid and org_site remain
  backed by the Update-unreachable error guard only (env constraints).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

[datadog_org_group] Address third-round review feedback

Covers 9 items accepted from round-3 worksheet; 4 skipped per
author's notes (transport/status error split, TF-state drop
verification, ListNestedAttribute migration, docstring-enforced
test invariant).

- Restore len != 1 guard in membership Create so a server contract
  drift (empty 200 instead of 404) produces a diagnostic rather
  than a panic.
- Mirror the overrides data source's zero-UUID defense in the
  memberships + groups data sources and the org_group resource;
  promote the overrides DS's tflog.Debug to AddWarning so users
  see dropped rows. Tidies terraform-plugin-log back to indirect.
- Compose destroy helper now runs every sub-check via errors.Join
  so a single test run surfaces every leaked resource type.
- Add explicit plancheck for policy + membership actions in
  _OrgGroupIdRequiresReplace so another resource can't absorb the
  DestroyBeforeCreate signal silently.
- Use a bool "found" flag instead of uuid.Nil in the
  provider-Read helper so a malformed server row is distinguishable
  from a filter miss.
- Rewrite _Basic's stale RequiresReplace comment to cross-reference
  _OrgGroupIdRequiresReplace.
- Fix _AutoCreation step-3 wording — Read-path helper does not
  drive ImportState.
- Replace package-level cascade globals with a per-test
  overrideCapture{Capture, EnforceViaAPI, CheckCascaded} struct.
- New plan-only _RejectsInvalidUUID test exercises the shared
  uuidValidator regex.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

[datadog_org_group] Trim accreted defensive complexity

Four rounds of reviewer feedback accumulated defensive code guarding
against server behaviors that have never occurred. This commit removes
that ceremony and shrinks the test files to match.

Provider code:
- Drop pagination duplicate-detection (seen map) from all 4 data sources.
  Simple page-until-short-page loop is sufficient.
- Drop zero-UUID warning guards from 3 data sources + the org_group
  resource. Revert updateState back to the no-diag signature it had
  before round 3.
- Simplify the membership Create len guard from != 1 to == 0 only. The
  > 1 branch is defense against nothing.

Tests:
- Delete testAccCheckAutoCreatedOverrideViaProviderRead (~110 lines of
  synthetic tfsdk.State construction). The fact that later refreshes
  don't fail is our read-path coverage.
- Delete overrideCapture struct + 3 methods (~100 lines) and inline the
  capture as closure-scoped locals in its one consumer (_EnforceCascade).
- Delete _RejectsInvalidUUID: plan-time validator coverage is source-
  visible; an acceptance test is overbuilt for a regex check.
- Delete _UnknownOrgReturns404: FrameworkErrorDiag 404 surfacing is
  framework-standard behavior, not worth a dedicated test.
- Delete 4 stale cassettes.

Net: override test 809 → 636 lines, membership test 233 → 184, 4 data
sources ~20 lines lighter each. No HTTP traffic changed so existing
cassettes still replay clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

[datadog_org_group] Drop dedicated _OrgGroupIdRequiresReplace test

For consistency with the rest of the PR: no other resource has a
dedicated RequiresReplace test. The policy resource tests only
policy_name (1 of 3 RequiresReplace fields) via its _Basic plancheck;
the membership resource has zero plancheck coverage of its one
RequiresReplace field. The override resource's Update-unreachable error
guard already catches regressions at apply time.

Removes ~50 lines of test + 2 config builders + 1 cassette. The
override's policy_id RequiresReplace remains covered by _Basic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Remove accidentally committed local replace directive

The `replace github.com/DataDog/datadog-api-client-go/v2 => ../datadog-api-client-go`
directive was a local-development convenience that should not have been
committed. Codex flagged this every review round.

With this directive removed, the branch won't build against released
client tags until the unreleased org_groups API surface is published.
That's the expected state — this PR is blocked on the client release
anyway.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Fix go.sum conflict markers left by rebase

The restack against the updated master left merge-conflict markers in
go.sum (master moved the datadog-api-client-go pin to a new prerelease
version while our stack had an older pin). Overwrite with master's
go.sum verbatim so go.sum matches master exactly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Bump datadog-api-client-go pin and re-record affected cassettes

The client was pinned at a pre-release pseudo-version that only existed
on the local spec-generation branch. Bump to a commit on the client's
default branch (1c9eaaf30b7) that contains the Org Groups API surface.

The newer client constructor sets policy_type=org_config by default on
policy create requests, so the six policy/override cassettes needed
re-recording to match the new request body shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Apply make fmt

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Regenerate docs

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

[datadog_org_group_memberships data source] Clarify that at least one filter is required

Address review feedback: the data source requires at least one of
org_group_id or org_uuid, not "optionally either." Update the schema
descriptions to make this explicit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Address editorial review feedback on org_group docs

Apply prose and schema-description suggestions from editorial review,
and switch cross-doc links to absolute registry URLs to match the
convention used elsewhere in the provider docs.

Pin datadog-api-client-go to 2ad4eb47 to pick up Org Groups pagination fix

Pulls in DataDog/datadog-api-client-go#4023, which fixes the Org Groups
pagination response shape (adds Links and reworks Meta on list responses).
Our code only reads resp.GetData() so no behavior change is needed; this
just unblocks testing the upstream fix without waiting for a release cut.

All cassette-replay tests pass against the new pin.

Skip org_group tests on live runs (RECORD!=true|false)

These tests require a special test-org setup that isn't available on the
shared CI account, so they fail when run live. Guard each test with
`if !isRecording() && !isReplaying()` so they still run for both
cassette replay and re-recording, but skip on live or unset RECORD.

Reuses the existing isRecording/isReplaying helpers in provider_test.go
to avoid adding `os` imports across the test files.

Co-authored-by: khai.phan <khai.phan@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/Fixed Fixed features results into a bug fix version bump

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant