Skip to content

feat: let kosli snapshot azure be pointed at other Azure endpoints #1327

Closed

Description

@gsavage

What problem are you trying to solve?

kosli snapshot azure can only talk to the Azure public cloud. Its endpoints are fixed in
internal/azure/azure_apps.go:

  • getBearerToken posts a hand-written client-credentials request to
    https://login.microsoftonline.com/<tenant>/oauth2/token with the resource
    https://management.azure.com/;
  • downloadAppPackage builds the Kudu URL as https://<app>.scm.azurewebsites.net/...;
  • NewAzureClient passes nil options to azidentity.NewClientSecretCredential and to
    armappservice.NewClientFactory, so the SDK's public-cloud authority and Resource Manager
    endpoint are used.

Two consequences:

  1. Cloud Capture cannot run the real CLI against a stand-in. Cloud Capture
    (kosli-dev/cloud-capture#177) runs the built image through all three of its stages in its
    end-to-end job against local stand-ins: moto for AWS, a fake Kosli API. The Searcher's own
    Azure adapter takes its authority and Resource Manager URLs from the environment for that
    reason, but the Snapshotter's last step is the CLI, and the CLI cannot be pointed anywhere but
    Azure itself. The Azure path therefore stops one step short of the end in make e2e, and is
    covered only by unit tests on both sides.
  2. Customers on a sovereign cloud cannot use the command. The ACR login-server check already
    accepts .azurecr.cn and .azurecr.us registries (acrLoginServerSuffixes), but a tenant in
    Azure China or Azure Government authenticates against a different authority and a different
    Resource Manager, so the command fails before it reaches the registry.

Proposed solution

Make the endpoints configurable in the way the SDK already supports, and remove the hand-written
token request so there is one place that knows the authority:

  • A --azure-cloud flag (values public, china, usgov, default public) that selects
    cloud.AzurePublic, cloud.AzureChina or cloud.AzureGovernment from
    github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud, passed through
    azidentity.ClientSecretCredentialOptions.ClientOptions.Cloud and
    arm.ClientOptions.Cloud on the App Service client factory.
  • Overrides for the two hosts, for stand-ins and private clouds: flags or environment variables
    along the lines of KOSLI_AZURE_AUTHORITY_HOST and KOSLI_AZURE_RESOURCE_MANAGER_URL, applied
    as a custom cloud.Configuration. azidentity already honours AZURE_AUTHORITY_HOST from the
    environment when the cloud configuration leaves the authority empty, so the authority half may
    only need documenting.
  • Replace getBearerToken with GetToken on the credential the client factory already holds,
    asking for the Resource Manager audience from the chosen cloud configuration, so the Kudu
    download uses the same authority as everything else.
  • Derive the Kudu host from the site's own properties.hostNameSslStates (the entry with
    hostType Repository) rather than the fixed .scm.azurewebsites.net suffix, which differs
    per cloud.

With that, Cloud Capture's end-to-end job would set the two overrides in the Snapshotter's
environment and point them at the stand-in that already serves the token endpoint and the site
list for the Searcher, and the Azure path would run end to end through the real CLI.

Alternatives considered

  • Cloud Capture skips the CLI for Azure in its end-to-end job and asserts on the arguments the
    Snapshotter would have passed. That loses exactly the coverage the job exists for.
  • An injectable HTTP transport for Go tests only (as acrClientOptions does for the ACR arm).
    Useful inside the CLI's own tests (see Azure: add fake + contract tests, remove credential gate from CLI tests #812) but not reachable from another process, so it does
    not help Cloud Capture or sovereign-cloud customers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions