Skip to content

feat(organization_nav_order): add cycloid_organization_nav_order resource (TFPRO-55) - #131

Merged
fhacloid merged 4 commits into
masterfrom
fhacloid-tfpro-55-terraform-configurable-ordering-of-sidebar-menu-entries
Jul 2, 2026
Merged

fhacloid merged 4 commits into
masterfrom
fhacloid-tfpro-55-terraform-configurable-ordering-of-sidebar-menu-entries

Conversation

@fhacloid

@fhacloid fhacloid commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ DO NOT MERGE — depends on two unmerged upstream PRs, opened for review now per request

  1. cycloidio/youdeploy-http-api#5977 — restores the /organizations/{org}/nav endpoint itself. It's currently missing from develop due to a regression: ENGBE-282.
  2. feat(middleware): add per-org sidebar nav ordering (GetOrgNav/UpdateOrgNav) cycloid-cli#471 — adds GetOrgNav/UpdateOrgNav to the Middleware interface.

go.mod currently points at a throwaway integration branch (fhacloid-tfpro-55-cli-nav-order-onto-pinned), not cycloid-cli#471's real branch. Here's why: cycloid-cli's develop has moved ~2 weeks ahead of this repo's currently-pinned commit since the TFPRO-51 work, and bumping straight to develop's tip pulled in unrelated breaking API changes (a GetComponentConfig signature change, etc.) that are out of scope for this PR. The throwaway branch is cycloid-cli#471's exact commit cherry-picked onto the commit this repo already pins, so this PR's diff stays minimal and isolated to nav ordering.

Once cycloid-cli#471 merges, this needs:

go get github.com/cycloidio/cycloid-cli@develop && go mod tidy

to point at the real merged commit — and separately, someone should reconcile the ~2-week drift between this repo's pin and cycloid-cli's develop, but that's unrelated to this feature and shouldn't block it.

What

New resource cycloid_organization_nav_order to manage per-organization sidebar navigation ordering (PROD-774) via Terraform — TFPRO-55.

Design: a singleton settings resource, mirroring cycloid_oidc_organization_settings exactly — Create/Update both call the same upsert method, Read via GET, Delete resets to defaults since there's no real delete endpoint (an empty items array is what resets ordering to defaults per the API contract).

items is Required, not Optional. After spending this session fixing the "Optional+Computed collection can't be cleared by omission" bug class twice today (TFPRO-42, on both organization_role and organization_api_key), the simplest way to avoid it entirely in a brand-new resource is to never allow omission in the first place. Users write items = [] explicitly to reset to defaults — there's no null-vs-empty ambiguity to get wrong.

navItemsFromData always returns a non-nil (possibly empty) slice for null/unknown input, so the request body always sends an explicit [] rather than JSON null, matching the pattern confirmed correct in today's TFPRO-42 fixes.

Tests

  • Unit (provider/organization_nav_order_resource_test.go): null/unknown items always produce a non-nil empty slice on the request side; API-side field mapping in both directions; empty API response maps to a non-null empty list in state.
  • Acceptance (provider/organization_nav_order_acceptance_test.go): create with a scoped ordering, clean second plan, reset to defaults. Cannot pass until dependency 1 above lands — I ran it against the local docker-compose backend and confirmed it fails with the expected 404 (Path /organizations/cycloid/nav was not found), proving the resource/schema/middleware wiring is correct and the only blocker is the missing backend endpoint, not a bug on this side.
  • go build / go vet / golangci-lint run all clean.

🤖 Generated with a fleet worker session — https://claude.ai/code/session_014CST9mw3ABSA4aYHNy96EV

fhacloid and others added 4 commits July 2, 2026 01:18
…urce (TFPRO-55)

New resource to manage per-organization sidebar navigation ordering
(PROD-774) via Terraform: GET/PUT /organizations/{org}/nav.

Design: a singleton settings resource, mirroring
oidc_organization_settings exactly (Create/Update both call the same
upsert method, Read via GET, Delete resets to defaults since there's
no real delete endpoint -- an empty items array is what resets
ordering to defaults per the API contract).

items is Required rather than Optional -- after spending tonight
fixing the "Optional+Computed collection can't be cleared by omission"
bug class twice (TFPRO-42, organization_role and organization_api_key),
the simplest way to avoid it entirely in a brand-new resource is to
never allow omission in the first place. Users write `items = []`
explicitly to reset to defaults; there's no null-vs-empty ambiguity to
get wrong.

navItemsFromData always returns a non-nil (possibly empty) slice for
null/unknown input, so the request body always sends an explicit []
rather than JSON null, matching the pattern confirmed correct in
tonight's TFPRO-42 fixes.

## Depends on two unmerged upstream PRs -- do not merge yet

1. cycloidio/youdeploy-http-api#5977 -- restores the /nav endpoint
   itself, which is currently missing from develop due to a regression
   (ENGBE-282). Confirmed by running the new acceptance test against
   the local docker-compose backend: clean 404
   ("Path /organizations/cycloid/nav was not found"), proving the
   resource/schema/middleware wiring is correct and the only blocker
   is the missing backend endpoint.
2. cycloidio/cycloid-cli#471 -- adds GetOrgNav/UpdateOrgNav to the
   Middleware interface.

go.mod currently points at a throwaway integration branch
(fhacloid-tfpro-55-cli-nav-order-onto-pinned), NOT cycloid-cli#471's
real branch -- cycloid-cli's develop has moved ~2 weeks ahead of this
repo's pinned commit since TFPRO-51, and bumping straight to develop's
tip pulled in unrelated breaking API changes (GetComponentConfig
signature, etc.) that are out of scope here. The throwaway branch is
cycloid-cli#471's exact commit cherry-picked onto the commit this repo
already pins, so this PR's diff is minimal and isolated. Once
cycloid-cli#471 merges, this needs:
    go get github.com/cycloidio/cycloid-cli@develop && go mod tidy
to point at the real merged commit (and separately reconcile the
~2-week drift, which is unrelated to this feature).

## Tests

- Unit tests (provider/organization_nav_order_resource_test.go):
  null/unknown items always produce a non-nil empty slice on the
  request side; API-side field mapping in both directions; empty API
  response maps to a non-null empty list in state.
- Acceptance test (provider/organization_nav_order_acceptance_test.go):
  create with a scoped ordering, clean second plan, reset to defaults.
  Cannot pass until dependency 1 above lands -- confirmed it fails
  with the expected 404, not some other error.
- go build / go vet / golangci-lint all clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CST9mw3ABSA4aYHNy96EV
The self-hosted runner caches docker images across runs, and
cycloid-backend is pinned to a floating tag (staging). Without an
explicit pull, docker compose up kept reusing a stale image even
after ENGBE-282's nav-ordering fix (youdeploy-http-api#5977) shipped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bump google.golang.org/grpc to v1.79.3 (fixes an authorization bypass
via missing leading slash in :path) and cloudflare/circl to v1.6.3
(fixes an incorrect secp384r1 CombinedMult calculation). Both were
indirect deps already one patch behind.

Also skip TestAccOrganizationNavOrderResource: it's blocked on
ENGBE-282 (youdeploy-http-api#5977, still open) the same way PROD-789
blocked a plugin_resource_test.go step — the code and unit tests are
correct, only the live backend endpoint is missing. Un-skip once that
lands.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Repoints go.mod from the throwaway cherry-pick branch used to unblock
development to cycloid-cli's actual PR #471 merge commit
(2645bbbef25746cf1b20e0fc27eafe638597ddd2) — shipping a release built
against a disposable personal branch isn't acceptable.

That pin also carries unrelated middleware changes already merged to
cycloid-cli develop ahead of #471:

- GetComponentConfig gained version-selector params (versionTag,
  versionBranch, versionCommitHash, versionID). Pass through the
  zero-value ("", "", "", 0) at all 3 call sites, matching how
  cycloid-cli's own create/update commands call it (auto-resolve
  current version).
- models.NewEnvironment.Type changed from *string to string; drop the
  now-unnecessary ptr.Ptr() wrapping at both call sites.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@fhacloid
fhacloid merged commit 9b54151 into master Jul 2, 2026
8 checks passed
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