Skip to content

Filter stale link provider intents during a deploy - #2823

Merged
a-hassanin merged 2 commits into
mainfrom
fix-stale-link-provider-intents
Oct 15, 2026
Merged

a-hassanin merged 2 commits into
mainfrom
fix-stale-link-provider-intents

Conversation

@KauzClay

@KauzClay KauzClay commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

What is this change about?

When a deploy removes a provided link, the link stays in records.json and in the .bosh/links.json file of the job. It goes away only on the next deploy. Until then, the stale link group keeps the BOSH DNS link alias for the removed link alive.

The next deploy then renders a links.json without the link. The templates change, so the job restarts with no manifest change. For example, cloud_controller_ng restarted on an Apply Changes after a release removed a link.

The cause is the order of the deploy steps:

  • The links parser gives each intent in the manifest the current links_serial_id.
  • The update stage renders the DNS links and links.json from Planner#link_provider_intents. That method did not filter by serial_id.
  • The deploy deletes the unused providers in the cleanup step, after the update stage.

The consumer path already filters by serial_id in LinksManager. The provider path got the unfiltered list in 5297d5c, when links.json and the link groups in records.json were added.

The fix filters the intents by links_serial_id only for a deploy action. A deploy action always runs the links parser, so each current intent has the current serial.

Other actions, such as cck and recreate, do not run the parser. A deploy can fail after it increments the serial and before it parses the links. Then no intent has the new serial. A filter on those actions would give empty DNS links and an empty links.json.

Alternatives ruled out:

  • Call remove_unused_links before the update stage. That method deletes each consumer link that has no InstancesLink at the current serial. The update stage sets those serials. An early call deletes nearly all consumer links, and a failed deploy cannot restore them.
  • Filter for all actions. This fails for cck and recreate after a failed deploy, as described above.

Please provide contextual information.

  • Regression from 5297d5c ([bosh-dns] add metadata about link based dns names). Related: 3974876, 4675288.

What tests have you run against this PR?

  • started a test pipeline here: https://bosh.ci.cloudfoundry.org/teams/main/pipelines/test-delete-when-finished-removed-link-provider
  • planner_spec.rb: 34 examples, 0 failures. Without the fix, the new deploy-action example fails.
  • Related unit specs (update_deployment_spec, deployment_plan/, links/, errand/, cloudcheck_helper_spec): 1775 examples, 0 failures.
  • Integration spec spec/integration/links/removed_link_provider_spec.rb, with 2 examples. One example removes custom_provider_definitions from the manifest. The other uploads a release version that no longer provides the link. After the removal deploy, each example deploys again with no change. The output must not contain Updating instance mysql.
    • With the fix: 2 examples, 0 failures.
    • Without the fix: 2 examples, 2 failures. .bosh/links.json still has the link: expected ["my-custom-link", "db"] not to include ....

How should this change be described in bosh release notes?

When a deploy removes a provided link, the Director now removes the link from the BOSH DNS records and from .bosh/links.json in the same deploy. The next deploy no longer restarts the job.

Does this PR introduce a breaking change?

No.

Tag your pair, your PM, and/or team!

AI Review Feedback

🤖 Generated with Claude Code

When a deploy removes a provided link, the link stays in records.json
and in the .bosh/links.json file of the job until the next deploy. The
stale link group keeps the BOSH DNS link alias for the removed link
alive.

The cause is the order of the deploy steps. The links parser gives each
intent in the manifest the current links_serial_id. The deploy deletes
the unused providers in the cleanup step, after the update stage.
Planner#link_provider_intents did not filter by serial_id. Thus the
update stage rendered the DNS links and links.json from intents that the
manifest no longer has. The consumer path already filters by serial_id
in LinksManager. The provider path got the unfiltered list in 5297d5c,
when links.json and the link groups in records.json were added.

The fix filters the intents by links_serial_id only for a deploy action.
A deploy action always runs the links parser, so each current intent has
the current serial_id. Other actions, such as cck and recreate, do not
run the parser. If a deploy fails after it increments the serial and
before it parses the links, no intent has the new serial. A filter on
these actions would then give empty DNS links and an empty links.json.

Alternatives ruled out:
- Call remove_unused_links before the update stage. That method deletes
  each consumer link that has no InstancesLink at the current serial.
  The update stage sets these serials, so an early call deletes nearly
  all consumer links, and a failed deploy cannot restore them.
- Filter for all actions. This fails as described above for cck and
  recreate after a failed deploy.

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

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 62bdc671-0c9c-495f-8f90-f680e26ce2ab
📥 Commits

Reviewing files that changed from the base of the PR and between b40d089 and 84cc1af.

📒 Files selected for processing (1)
  • src/spec/integration/links/removed_link_provider_spec.rb

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

For deploy actions, Planner#link_provider_intents now returns intents that match the deployment model’s links serial ID. For non-deploy actions, it returns all provider intents. Unit and integration specs cover these results and verify that removing a link provider removes its link and DNS group ID after redeployment.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 84cc1

Deploys filter removed provider links while preserving existing link data for non-deploy actions. The reviewed change has no identified material regression and appears ready to merge after normal checks.

Security architecture risk: 🔵 Low · up to 84cc1

The change narrows deploy-time output to current link providers without adding a public endpoint or increasing privileges. Existing recovery behavior is preserved. Risk remains low because interrupted deployments can leave mixed persisted and rendered state, and recovery scenarios are not demonstrated by the added tests.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The directly changed data is provider metadata owned by the deployment being planned, with downstream effects on job link files and DNS discovery for dependent consumers. The change narrows deploy-time output; it does not grant additional control over other deployments or introduce a new production invocation path.

Security Findings and Attack Paths

  • inferred — No introduced or materially worsened attack path was established in the inspected change. The public-entrypoint routing corresponds to test code, and the production branch removes older intent entries rather than accepting new input or increasing sink authority.

Trust Boundaries and Controls

  • observed — The deployment operation encloses serial advancement, parsing, and updates in a deployment-named lock. Serial matching acts as a freshness control over deployment-owned metadata, not an authentication or authorization mechanism.

Hardening Proposals

  • proposed — Exercise interruption after serial advancement and after a partial instance update, followed by non-deploy repair and redeploy. Check persisted intents, rendered link files, DNS groups, and metadata aliases together to document recovery and prevent discovery-state drift. This is additional assurance, not a verified vulnerability.
Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely describes the main change: filtering stale link provider intents during deploys.
Description check Passed The description covers the change, rationale, context, alternatives, tests, release notes, and breaking-change status. The team-tag section is empty, but this is non-critical and the description is ot…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@KauzClay

KauzClay commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

@KauzClay
KauzClay marked this pull request as ready for review October 8, 2026 21:33
coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 8, 2026
TNZ-164428 reports a restart of cloud_controller_ng on an Apply Changes
with no manifest change. The release removed a link. The deploy with the
new release still rendered the old link in .bosh/links.json. Cleanup
then removed the link metadata, so the next deploy rendered different
templates and restarted the job. Commit b40d089 fixes this. It
filters the stale provider intents during a deploy.

The spec now covers the two paths to a removed link:
- A manifest removes custom_provider_definitions.
- A new release version removes a provides entry from the job spec.
  This is the TNZ-164428 case.

After the removal deploy, each example deploys again with no change.
The output must not contain "Updating instance mysql".

Without b40d089, both examples fail at the links.json check. The
removed link stays in links.json until the next deploy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KauzClay
KauzClay force-pushed the fix-stale-link-provider-intents branch from e20f6f3 to 84cc1af Compare October 13, 2026 15:17
@aramprice
aramprice requested a balanced review from Copilot October 15, 2026 14:51

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@rkoster
rkoster requested a balanced review from Copilot October 15, 2026 14:51
@aramprice aramprice moved this from Pending Merge | Prioritized to Pending Review | Discussion in Foundational Infrastructure Working Group Oct 15, 2026
@a-hassanin a-hassanin moved this from Pending Review | Discussion to Waiting for Changes | Open for Contribution in Foundational Infrastructure Working Group Oct 15, 2026
@a-hassanin a-hassanin moved this from Waiting for Changes | Open for Contribution to Pending Review | Discussion in Foundational Infrastructure Working Group Oct 15, 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.

🟢 Approval recommended

The narrow filter matches the deploy lifecycle, preserves other actions, and includes focused regression coverage with no unresolved findings.

0 open findings

🧠 Review effort: Balanced

@a-hassanin
a-hassanin requested review from a team, ragaskar and selzoc and removed request for a team October 15, 2026 14:53
@a-hassanin

Copy link
Copy Markdown
Contributor

Thank you for your contribution!

@a-hassanin
a-hassanin merged commit 45ae5e6 into main Oct 15, 2026
19 checks passed
@a-hassanin
a-hassanin deleted the fix-stale-link-provider-intents branch October 15, 2026 14:59
@github-project-automation github-project-automation Bot moved this from Pending Review | Discussion to Done in Foundational Infrastructure Working Group Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

4 participants