Skip to content

feat(azure/savings-plans): wire SP rec collection into scheduler #17

Open

Description

@cristim

Context

PR LeanerCloud/cloud-commitments-cli#592 added the Azure Savings Plans ServiceClient (provider client + dispatch wiring). The scheduler does not yet call it for rec collection.

Work

Wire ServiceSavingsPlans into the scheduler's Azure rec-collection path, mirroring how AWS Savings Plans recs are collected (via the Cost Explorer centralized path, or -- once the Azure Benefits Recommendations API exits preview -- via the client's GetRecommendations).

Also add the commitmentopts SP probe equivalent for Azure (mirroring probe_savingsplans*.go for AWS).

Depends on

LeanerCloud/cloud-commitments-cli#592 (must land first)

refs LeanerCloud/cloud-commitments-cli#473

Findings from the 2026-09-02 codebase audit

Added by an automated audit of 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd (tip of origin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report: docs/audits/codebase-audit-2026-09-02.md.

A05-009 (medium)

Worth knowing before anyone starts this: the Azure commitmentopts SP probe already exists as internal/commitmentopts/probe_azure.go (212 lines plus 304 lines of tests), but it is unreachable. ProbeAzure and DefaultAzureProbers have no non-test caller, and the doc comment points at Service.probeAndPersistAzure, which does not exist -- probeAndPersist (service.go:76) only ranges over s.probers, and AzureSPProber cannot join that set because Probe takes an azcore.TokenCredential rather than an aws.Config. The consequence today is that Validate("azure", "savingsplans", ...) always takes the permissive-true branch, so a reader auditing whether Azure SP term/payment combos are validated concludes they are. The wiring work here is therefore either an Azure sibling of probeAndPersist or deleting the file; leaving it as-is is the worst option. (audit finding A05-009)

Activity

  1. cristim commented on May 28, 2026

    @cristim
    MemberAuthor

    Verification: cannot-verify-autopilot. PR LeanerCloud/cloud-commitments-cli#592 (the linked PR) only added the Azure Savings Plans ServiceClient and wired it into provider.go + services.go dispatch. The scheduler's Azure rec-collection path does not call it: GetRecommendations in providers/azure/services/savingsplans/client.go returns an empty slice, and there is no scheduler probe file for Azure SP. The commitmentopts SP probe equivalent for Azure has not been added. The scheduler wiring described in this issue has not landed on origin/feat/multicloud-web-frontend.

  2. cristim commented on Jun 8, 2026

    @cristim
    MemberAuthor

    Note: PR LeanerCloud/cloud-commitments-cli#809 (merged) only wired the scheduler goroutine slot - providers/azure/services/savingsplans/client.go GetRecommendations still returns an empty slice (Azure Benefits Recommendations API is in preview), so no Azure SP recommendation reaches the user yet, and the commitmentopts SP probe equivalent is still missing. This issue correctly remains OPEN to track the real implementation when the preview API stabilizes.

  3. IAmJSD commented on Oct 23, 2026

    @IAmJSD
    Collaborator

    Claiming: working on this

  4. self-assigned this
    on Oct 23, 2026
  5. IAmJSD commented on Oct 23, 2026

    @IAmJSD
    Collaborator

    Released: needs an owner decision, no code change made. @cristim

    What I found on current main (a14dc8f, pinned providers/azure 3def3f8):

    • SP recommendation collection already works. go#373 (5b0fc26, an ancestor of the pin) added a real savingsplans.Client.GetRecommendations (Benefit Recommendations API). The provider's GetAllRecommendations includes it, and the scheduler's Azure paths (collectAzureForAccount, collectAzureAmbient) collect it. A throwaway unit test showed an SP rec survives convertRecommendations. The earlier "returns an empty slice" comments describe the pre-fix(server): advisory lock released on the request context strands a task type in permanent already_running #373 stub.
    • The commitmentopts Azure probe (A05-009) is still unreachable, and enabling it isn't a wiring job:
      • It writes all-upfront, but Azure's payments are upfront/monthly.
      • It sends sku Compute, while go#503 moved to Compute_Savings_Plan.
      • It validates against a placeholder subscription.
      • It needs a billing currency that nothing provides.
      • The single shared "probe ran" row (000039) can't hold a second provider.
      • Nothing reads Azure options.

    Decision needed: close the collection half as done (go#373), and either delete probe_azure.go or build it properly. Building it needs a per-provider probe-row migration, a currency source, corrected payment/SKU values, an AWS/Azure failure split and an API/UI follow-up. It could only be verified against Azure after the deploy pause. I'm happy to do the deletion as a small PR if you choose that.

  6. removed their assignment
    on Oct 23, 2026
  7. cristim commented on Oct 23, 2026

    @cristim
    MemberAuthor

    @IAmJSD thank you for checking this, let's build it properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions