Azure-cli: `az curl` or `az rest` for custom REST support (coverage)

Created on 19 Oct 2018  路  14Comments  路  Source: Azure/azure-cli

Is your feature request related to a problem? Please describe.

The Azure docs have a REST API explorer, and that is helpful for one-off testing, but isn't very helpful for scripting or for REST APIs that haven't made their way into the Azure CLI.

Describe the solution you'd like

I'd like to propose adding a new subcommand, such as az curl or az rest, that allows a user to call a resource provider with a custom payload. I could see the feature looking something like this:

az {curl,rest} /subscriptions/{subscriptionId}/providers/{Resource.Provider}/{endpoint} \
  --api-version {version} \
  --payload '{"json": "payload"}'

or

az {curl,rest} /{Resource.Provider}/{endpoint} \
  --subscription {sub-id} \
  --api-version {version} \
  --payload '{"json": "payload"}'

or

az {curl,rest} {endpoint} \
  --subscription {sub-id} \
  --resource-provider {Resource.Provder} \
  --api-version {version} \
  --payload '{"json": "payload"}'

This would allow users to pass JSON payloads for scripting or for testing and validating of the REST API for custom clients.

Describe alternatives you've considered

Currently you can curl the Azure REST API, but you have to pass a lot of authentication context that will persist in your shell history, which can be a security concern. This would alleviate that and allow a user to interact with the raw REST API while letting the Azure CLI handle authentication contexts on behalf of the user.

Additional context

You can see a good example of this with the Cloud Foundry CLI, cf. You can cf curl to interact with raw API resources the CLI doesn't support out of the box.

H2-2019

Most helpful comment

folks, check out my #9490 and let me know if you have any comments. The command signature looks like:

(env) C:\sdk\azure-cli>az rest -h

Command
    az rest : Invoke custom request.

Arguments
    --method         [Required] : HTTP request method.  Allowed values: delete, get, head, options,
                                  patch, post, put.  Default: get.
    --url            [Required] : Request url.
    --body                      : Request body.
    --headers                   : Space-separated appsettings in KEY=VALUE format or JSON string.
                                  Use @{file} to load from a file.
    --output-file               : Save response payload to a file.
    --resource                  : Resource which CLI would acquire token so to put on the
                                  "Authorization" header. By default, CLI can figure this out based
                                  on --url, unless you use ones not in the list of "az cloud show".
    --skip-authorization-header : Do not auto append "Authorization" header.
    --uri-parameters            : Space-separated appsettings in KEY=VALUE format or JSON string.
                                  Use @{file} to load from a file.
Examples
    Get Audit log through Microsoft Graph
        az rest --method get --url https://graph.microsoft.com/beta/auditLogs/directoryAudits


    Update a Azure Active Directory Graph User's display name
        az rest --method patch --headers "{"Content-Type": "application/json"}" --url
        "https://graph.microsoft.com/v1.0/users/[email protected]" --body
        "{"displayName":"jondoe2"}"

All 14 comments

I would like this for setting IP restrictions for webapps. From the docs here: https://docs.microsoft.com/en-us/azure/app-service/app-service-ip-restrictions :

There currently is no CLI or PowerShell for the new IP Restrictions capability but the values can be set manually with a PUT operation on the app configuration in Resource Manager.

I'm currently scratching my head how exactly to achieve this considering authentication etc.

@mxplusb have you tried that az resource create/update commands? That is essentially what those do.

@ppanyukov if there isn't already, please open a feature request for webapps to support these properties. The article is likely referring to use of --set on generic update. Opening a specific issue will put it on their radar to add this, and may get you a workaround using --set in the meantime.

I'm struggling to achieve some of the REST calls made in https://docs.microsoft.com/en-gb/azure/storage/common/storage-metrics-in-azure-monitor using an az resource command; as far as I can tell they can't be achieved. This feature would be great in the CLI, as armclient isn't available in the Cloud Shell.

I recommend we prioritize this work as it becomes helpful not just on ARM but also any rest calls on data plane APIs like AAD Graph. Having such support will not only handle the thorny part like propagating access tokens, but also getting CLI built-in supports for free such as different output mode, jmespath query, etc.

Regarding the design, I suggest add an argument of HTTP Method like get/put/post/delete

With that, CLI can be used for more scripting scenarios even with temporary service coverage gaps.

i will take this

folks, check out my #9490 and let me know if you have any comments. The command signature looks like:

(env) C:\sdk\azure-cli>az rest -h

Command
    az rest : Invoke custom request.

Arguments
    --method         [Required] : HTTP request method.  Allowed values: delete, get, head, options,
                                  patch, post, put.  Default: get.
    --url            [Required] : Request url.
    --body                      : Request body.
    --headers                   : Space-separated appsettings in KEY=VALUE format or JSON string.
                                  Use @{file} to load from a file.
    --output-file               : Save response payload to a file.
    --resource                  : Resource which CLI would acquire token so to put on the
                                  "Authorization" header. By default, CLI can figure this out based
                                  on --url, unless you use ones not in the list of "az cloud show".
    --skip-authorization-header : Do not auto append "Authorization" header.
    --uri-parameters            : Space-separated appsettings in KEY=VALUE format or JSON string.
                                  Use @{file} to load from a file.
Examples
    Get Audit log through Microsoft Graph
        az rest --method get --url https://graph.microsoft.com/beta/auditLogs/directoryAudits


    Update a Azure Active Directory Graph User's display name
        az rest --method patch --headers "{"Content-Type": "application/json"}" --url
        "https://graph.microsoft.com/v1.0/users/[email protected]" --body
        "{"displayName":"jondoe2"}"

@yugangw-msft that looks fantastic, it definitely solves my original ask, thanks for following through!

I have merged it to release on June 18. //CC @achandmsft
@nickwalkmsft, the command for your scenario would be:

az rest --method get --url https://management.azure.com/subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/resourceGroups/yugangw/providers/Microsoft.Storage/storageAccounts/yugangwstor22/providers/microsoft.insights/metricdefinitions?api-version=2018-01-01

Hi @yugangw-msft can you provide an example of how to use the resource argument? I am not clear on what I am supposed to pass to that.

Sure, most of times, you don't need to supply values to --resource as Azure CLI is able to figure out from --uri. e.g.

az rest --method get --uri https://graph.microsoft.com/beta/auditLogs/directoryAudits

CLI will default the resource to https://graph.microsoft.com/, which is the right one, hence you have nothing to worry about.

--resource by itself is a bit confusing, but you can understand it as a service endpoint, and to send a request to it, CLI works underneath to get the appropriate token issued for accessing the service endpoint. When CLI tries to acquire the token, Azure AD requires the resource argument, you can always supply it for CLI to pass over to it, or leave to CLI to figure out.
JFYI, --resource is also called relying party, web api, audience uri, etc based on the context.

Hope this helps.

How do i specify the Authorization : bearer $token in the --headers ? i haven't found anything useful . Also is it possible to user az rest -m get on a private keyvault for example ?

@yugangw-msft how do I use this? az rest throws an error

Nice! Thank you.
Does az rest support --query?

I can't seem to get any results when I try it

Nice! Thank you.
Does az rest support --query?

I can't seem to get any results when I try it

This is what I'm trying...

az rest -m get -u "https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/HaNeCan/providers/Microsoft.Web/sites/HaNeCan/functions?api-version=2019-08-01" --query "[].{id: [].invoke_url_template}"

Was this page helpful?
0 / 5 - 0 ratings