Auto-detach policy from watches on delete to fix circular dependency(#358) - #428
Open
soumyas-dev wants to merge 3 commits into
Open
Auto-detach policy from watches on delete to fix circular dependency(#358)#428soumyas-dev wants to merge 3 commits into
soumyas-dev wants to merge 3 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Auto-detach policy from watches before deletion to resolve circular dependency between policy and watch resources.
Fixes #358
Problem
When a policy (
xray_security_policy,xray_license_policy, orxray_operational_risk_policy) is attached to a watch via theassigned_policyblock,terraform destroyfails because the Xray API rejects policy deletion with"Policy is assigned to N watches". Users had to manually detach policies from watches before destroying them, making automated teardown impossible.Implementation
Changed files
pkg/xray/resource/policies.go(3 new functions/constants, 1 modified function)deletePolicy(policyName, projectKey) (int, string, error)Extracted helper that sends
DELETE /xray/api/v2/policies/{name}and returns the HTTP status code, error message, and any transport error. Used by both the initial optimistic attempt and the retry after detach.detachPolicyFromWatches(ctx, policyName, projectKey) diag.DiagnosticsHandles the detach-from-watches flow:
GET /xray/api/v2/watches(single API call, scoped byprojectKeyif set)assigned_policiescontain the target policy name, and builds a list of watches to update with the policy removedmaxConcurrentWatchUpdates = 10concurrent requests using a buffered channel as a semaphore. Each goroutine sendsPUT /xray/api/v2/watches/{name}with the policy removed fromassigned_policiessync.Mutexto collect errors from all goroutines. Returns all failures as Terraform diagnostics rather than failing fast, so the user sees every watch that failed to updateConcurrency primitives used:
sync.WaitGroup— waits for all goroutines to completechan struct{}(buffered, size 10) — semaphore to limit concurrent API callssync.Mutex— protects the shared error sliceDelete(ctx, req, resp)(modified)Now implements an optimistic-delete-then-detach strategy:
deletePolicy()directly"assigned"(matches"Policy is assigned to N watches"), OR"attached"(future-proofing for API wording changes)detachPolicyFromWatches()then retriesdeletePolicy()API call count by scenario:
CHANGELOG.mdAdded entry under
## 3.1.12documenting the fix.Test details
pkg/xray/resource/resource_xray_security_policy_test.goTestAccSecurityPolicy_deleteDetachesFromWatchAcceptance test that verifies the auto-detach logic works end-to-end against a live Xray instance.
Step 1 — Uses
policyWithWatchTemplateto create:xray_security_policy.<resource_name>— A security policy with CVSS criteriaxray_watch.test— A watch on all repos with the policy attached viaassigned_policyblock (references the policy by name, creating an implicit Terraform dependency)Checks:
assigned_policy.0.namereferences the original policyStep 2 — Uses
watchWithReplacementPolicyTemplatewhich:xray_security_policy.replacementwith a different namexray_watch.testto reference the replacement policyThis forces Terraform to:
Checks:
assigned_policy.0.namenow references the replacement policyCheckDestroy — Verifies the replacement policy (the one that exists in the final state) is properly cleaned up after the test. The original policy was already verified deleted by step 2 succeeding.
Templates
policyWithWatchTemplate— Creates a security policy + watch with the policy attachedwatchWithReplacementPolicyTemplate— Creates a different policy + same watch pointing to the new policy (original policy removed from config)Test plan
TestAccSecurityPolicy_deleteDetachesFromWatchpassesTestAccSecurityPolicy_*tests still passTestAccWatch_*tests still pass (watch CRUD unaffected)go build ./...andgo vet ./...pass cleanly