azure-cli icon indicating copy to clipboard operation
azure-cli copied to clipboard

Cannot update existing APIM api with import command: `(ValidationError) API with specified version 'v1' already exists`

Open rgembalik opened this issue 1 year ago • 4 comments

Describe the bug

I imported an api into a versionset with import command:

az apim api import --subscription <sub-id> -g <rg-name> --service-name <apim-name> -o table --path '/spec' --specification-format "OpenApiJson" --specification-path spec.json --api-version-set-id echo-v1 --api-version v1

I wanted to update it so that the endpoints are updated in the portal within the same version (ideally as a new revision), so I used the same command.

However, the cli returns an error specified below.

If add manually a revision id ( --api-revision 2) the import succeeds, but it is added into a new entry to the versionset instead of adding a revision to existing version:

image

Am I under a wrong impression that this is supposed to work this way? Is there any other command I should use to update existing api/version using openapi schema?

Related command

az apim api import

Errors

cli.azure.cli.core.azclierror: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
az_command_data_logger: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists

Issue script & Debug output

Show debug output
cli.knack.cli: Command arguments: ['apim', 'api', 'import', '--subscription', '<sub-id>', '-g', '<rg-name>', '--service-name', '<apim-name>', '-o', 'table', '--path', '/spec', '--specification-format', 'OpenApiJson', '--specification-path', '.\\Downloads\\spec.json', '--api-version-set-id', 'echo-v1', '--api-version', 'v1', '--debug']
cli.knack.cli: __init__ debug log:
Enable color in terminal.
cli.knack.cli: Event: Cli.PreExecute []
cli.knack.cli: Event: CommandParser.OnGlobalArgumentsCreate [<function CLILogging.on_global_arguments at 0x000001703FA6B880>, <function OutputProducer.on_global_arguments at 0x000001703FBF6020>, <function CLIQuery.on_global_arguments at 0x000001703FC23BA0>]
cli.knack.cli: Event: CommandInvoker.OnPreCommandTableCreate []
cli.azure.cli.core: Modules found from index for 'apim': ['azure.cli.command_modules.apim']
cli.azure.cli.core: Loading command modules:
cli.azure.cli.core: Name                  Load Time    Groups  Commands
cli.azure.cli.core: apim                      0.008        14        69
cli.azure.cli.core: Total (1)                 0.008        14        69
cli.azure.cli.core: Loaded 14 groups, 69 commands.
cli.azure.cli.core: Found a match in the command table.
cli.azure.cli.core: Raw command  : apim api import
cli.azure.cli.core: Command table: apim api import
cli.knack.cli: Event: CommandInvoker.OnPreCommandTableTruncate [<function AzCliLogging.init_command_file_logging at 0x0000017042B4EE80>]
cli.azure.cli.core.azlogging: metadata file logging enabled - writing logs to 'C:\Users\<user_dir>\.azure\commands\2024-05-07.12-16-54.apim_api_import.15920.log'.
az_command_data_logger: command args: apim api import --subscription {} -g {} --service-name {} -o {} --path {} --specification-format {} --specification-path {} --api-version-set-id {} --api-version {} --debug
cli.knack.cli: Event: CommandInvoker.OnPreArgumentLoad [<function register_global_subscription_argument.<locals>.add_subscription_parameter at 0x0000017042B5B4C0>]
cli.knack.cli: Event: CommandInvoker.OnPostArgumentLoad []
cli.knack.cli: Event: CommandInvoker.OnPostCommandTableCreate [<function register_ids_argument.<locals>.add_ids_arguments at 0x0000017042B9D3A0>, <function register_cache_arguments.<locals>.add_cache_arguments at 0x0000017042B9D4E0>]
cli.knack.cli: Event: CommandInvoker.OnCommandTableLoaded []
cli.knack.cli: Event: CommandInvoker.OnPreParseArgs []
cli.knack.cli: Event: CommandInvoker.OnPostParseArgs [<function OutputProducer.handle_output_argument at 0x000001703FBF60C0>, <function CLIQuery.handle_query_parameter at 0x000001703FC23C40>, <function register_ids_argument.<locals>.parse_ids_arguments at 0x0000017042B9D440>]
cli.azure.cli.core.commands.client_factory: Getting management service client client_type=ApiManagementClient
cli.azure.cli.core.auth.persistence: build_persistence: location='C:\\Users\\<user_dir>\\.azure\\msal_token_cache.bin', encrypt=True
cli.azure.cli.core.auth.binary_cache: load: C:\Users\<user_dir>\.azure\msal_http_cache.bin
urllib3.util.retry: Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
msal.authority: openid_config = {'token_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token', 'token_endpoint_auth_methods_supported': ['client_secret_post', 'private_key_jwt', 'client_secret_basic'], 'jwks_uri': 'https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys', 'response_modes_supported': ['query', 'fragment', 'form_post'], 'subject_types_supported': ['pairwise'], 'id_token_signing_alg_values_supported': ['RS256'], 'response_types_supported': ['code', 'id_token', 'code id_token', 'id_token token'], 'scopes_supported': ['openid', 'profile', 'email', 'offline_access'], 'issuer': 'https://login.microsoftonline.com/<tenant-id>/v2.0', 'request_uri_parameter_supported': False, 'userinfo_endpoint': 'https://graph.microsoft.com/oidc/userinfo', 'authorization_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize', 'device_authorization_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/devicecode', 'http_logout_supported': True, 'frontchannel_logout_supported': True, 'end_session_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/logout', 'claims_supported': ['sub', 'iss', 'cloud_instance_name', 'cloud_instance_host_name', 'cloud_graph_host_name', 'msgraph_host', 'aud', 'exp', 'iat', 'auth_time', 'acr', 'nonce', 'preferred_username', 'name', 'tid', 'ver', 'at_hash', 'c_hash', 'email'], 'kerberos_endpoint': 'https://login.microsoftonline.com/<tenant-id>/kerberos', 'tenant_region_scope': 'EU', 'cloud_instance_name': 'microsoftonline.com', 'cloud_graph_host_name': 'graph.windows.net', 'msgraph_host': 'graph.microsoft.com', 'rbac_url': 'https://pas.windows.net'}
msal.application: Broker enabled? None
cli.azure.cli.core.auth.credential_adaptor: CredentialAdaptor.get_token: scopes=('https://management.core.windows.net//.default',), kwargs={}
cli.azure.cli.core.auth.msal_authentication: UserCredential.get_token: scopes=('https://management.core.windows.net//.default',), claims=None, kwargs={}
msal.application: Cache hit an AT
msal.telemetry: Generate or reuse correlation_id: b6ea7651-7728-4f2c-8285-409de63ad64d
cli.azure.cli.core.sdk.policies: Request URL: 'https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01'
cli.azure.cli.core.sdk.policies: Request method: 'PUT'
cli.azure.cli.core.sdk.policies: Request headers:
cli.azure.cli.core.sdk.policies:     'Content-Type': 'application/json'
cli.azure.cli.core.sdk.policies:     'Content-Length': '68824'
cli.azure.cli.core.sdk.policies:     'Accept': 'application/json'
cli.azure.cli.core.sdk.policies:     'x-ms-client-request-id': 'edb33bac-0c5a-11ef-9e5f-a002a54c8717'
cli.azure.cli.core.sdk.policies:     'CommandName': 'apim api import'
cli.azure.cli.core.sdk.policies:     'ParameterSetName': '--subscription -g --service-name -o --path --specification-format --specification-path --api-version-set-id --api-version --debug'
cli.azure.cli.core.sdk.policies:     'User-Agent': 'AZURECLI/2.59.0 (MSI) azsdk-python-core/1.28.0 Python/3.11.8 (Windows-10-10.0.22631-SP0)'
cli.azure.cli.core.sdk.policies:     'Authorization': '*****'
cli.azure.cli.core.sdk.policies: Request body:
cli.azure.cli.core.sdk.policies: <content of the openapi schema>
urllib3.connectionpool: Starting new HTTPS connection (1): management.azure.com:443
urllib3.connectionpool: https://management.azure.com:443 "PUT /subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01 HTTP/1.1" 202 0
cli.azure.cli.core.sdk.policies: Response status: 202
cli.azure.cli.core.sdk.policies: Response headers:
cli.azure.cli.core.sdk.policies:     'Cache-Control': 'no-cache'
cli.azure.cli.core.sdk.policies:     'Pragma': 'no-cache'
cli.azure.cli.core.sdk.policies:     'Expires': '-1'
cli.azure.cli.core.sdk.policies:     'Location': 'https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01&asyncId=6639ff9746346104641f9da9&asyncCode=201'
cli.azure.cli.core.sdk.policies:     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
cli.azure.cli.core.sdk.policies:     'X-Content-Type-Options': 'nosniff'
cli.azure.cli.core.sdk.policies:     'x-ms-request-id': 'e51b0f55-a130-4051-9481-3ce2e15d9fa0'
cli.azure.cli.core.sdk.policies:     'x-ms-ratelimit-remaining-subscription-writes': '1199'
cli.azure.cli.core.sdk.policies:     'x-ms-correlation-request-id': 'e51b0f55-a130-4051-9481-3ce2e15d9fa0'
cli.azure.cli.core.sdk.policies:     'x-ms-routing-request-id': 'GERMANYWESTCENTRAL:20240507T101655Z:e51b0f55-a130-4051-9481-3ce2e15d9fa0'
cli.azure.cli.core.sdk.policies:     'X-Cache': 'CONFIG_NOCACHE'
cli.azure.cli.core.sdk.policies:     'X-MSEdge-Ref': 'Ref A: 52B5618F68424B94BFBE52D67046B6CF Ref B: VIEEDGE1618 Ref C: 2024-05-07T10:16:54Z'
cli.azure.cli.core.sdk.policies:     'Date': 'Tue, 07 May 2024 10:16:54 GMT'
cli.azure.cli.core.sdk.policies:     'Content-Length': '0'
cli.azure.cli.core.sdk.policies: Response content:
cli.azure.cli.core.sdk.policies:
cli.azure.cli.core.sdk.policies: Request URL: 'https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01&asyncId=6639ff9746346104641f9da9&asyncCode=201'
cli.azure.cli.core.sdk.policies: Request method: 'GET'
cli.azure.cli.core.sdk.policies: Request headers:
cli.azure.cli.core.sdk.policies:     'x-ms-client-request-id': 'edb33bac-0c5a-11ef-9e5f-a002a54c8717'
cli.azure.cli.core.sdk.policies:     'CommandName': 'apim api import'
cli.azure.cli.core.sdk.policies:     'ParameterSetName': '--subscription -g --service-name -o --path --specification-format --specification-path --api-version-set-id --api-version --debug'
cli.azure.cli.core.sdk.policies:     'User-Agent': 'AZURECLI/2.59.0 (MSI) azsdk-python-core/1.28.0 Python/3.11.8 (Windows-10-10.0.22631-SP0)'
cli.azure.cli.core.sdk.policies:     'Authorization': '*****'
cli.azure.cli.core.sdk.policies: Request body:
cli.azure.cli.core.sdk.policies: This request has no body
urllib3.connectionpool: https://management.azure.com:443 "GET /subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01&asyncId=6639ff9746346104641f9da9&asyncCode=201 HTTP/1.1" 400 110
cli.azure.cli.core.sdk.policies: Response status: 400
cli.azure.cli.core.sdk.policies: Response headers:
cli.azure.cli.core.sdk.policies:     'Cache-Control': 'no-cache'
cli.azure.cli.core.sdk.policies:     'Pragma': 'no-cache'
cli.azure.cli.core.sdk.policies:     'Content-Length': '110'
cli.azure.cli.core.sdk.policies:     'Content-Type': 'application/json; charset=utf-8'
cli.azure.cli.core.sdk.policies:     'Expires': '-1'
cli.azure.cli.core.sdk.policies:     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
cli.azure.cli.core.sdk.policies:     'X-Content-Type-Options': 'nosniff'
cli.azure.cli.core.sdk.policies:     'x-ms-request-id': '25b70b20-347c-4a65-b271-184e0620584d'
cli.azure.cli.core.sdk.policies:     'x-ms-ratelimit-remaining-subscription-reads': '11998'
cli.azure.cli.core.sdk.policies:     'x-ms-correlation-request-id': '25b70b20-347c-4a65-b271-184e0620584d'
cli.azure.cli.core.sdk.policies:     'x-ms-routing-request-id': 'GERMANYWESTCENTRAL:20240507T101655Z:25b70b20-347c-4a65-b271-184e0620584d'
cli.azure.cli.core.sdk.policies:     'X-Cache': 'CONFIG_NOCACHE'
cli.azure.cli.core.sdk.policies:     'X-MSEdge-Ref': 'Ref A: 56C2B27E493C4052BBE432B46C337196 Ref B: VIEEDGE1618 Ref C: 2024-05-07T10:16:55Z'
cli.azure.cli.core.sdk.policies:     'Date': 'Tue, 07 May 2024 10:16:55 GMT'
cli.azure.cli.core.sdk.policies: Response content:
cli.azure.cli.core.sdk.policies: {"error":{"code":"ValidationError","message":"API with specified version 'v1' already exists","details":null}}
cli.azure.cli.core.azclierror: Traceback (most recent call last):
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 730, in run
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 756, in _poll
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 782, in update_status
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 156, in _raise_if_bad_http_status_and_method
azure.core.polling.base_polling.BadStatus: Invalid return status 400 for 'GET' operation

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\knack/cli.py", line 233, in invoke
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 664, in execute
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 731, in _run_jobs_serially
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 712, in _run_job
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 1048, in __call__
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 1035, in __call__
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/_poller.py", line 242, in result
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/tracing/decorator.py", line 76, in wrapper_use_tracer
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/_poller.py", line 261, in wait
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/_poller.py", line 176, in _start
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 734, in run
azure.core.exceptions.HttpResponseError: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists

cli.azure.cli.core.azclierror: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
az_command_data_logger: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
cli.knack.cli: Event: Cli.PostExecute [<function AzCliLogging.deinit_cmd_metadata_logging at 0x0000017042B4F100>]
az_command_data_logger: exit code: 1
cli.__main__: Command ran in 2.601 seconds (init: 0.213, invoke: 2.389)
telemetry.main: Begin splitting cli events and extra events, total events: 1
telemetry.client: Accumulated 0 events. Flush the clients.
telemetry.main: Finish splitting cli events and extra events, cli events: 1
telemetry.save: Save telemetry record of length 3962 in cache
telemetry.main: Begin creating telemetry upload process.
telemetry.process: Creating upload process: "C:\Program Files\Microsoft SDKs\Azure\CLI2\python.exe C:\Program Files\Microsoft SDKs\Azure\CLI2\Lib\site-packages\azure\cli\telemetry\__init__.pyc C:\Users\<user_dir>\.azure"
telemetry.process: Return from creating process
telemetry.main: Finish creating telemetry upload process.

Expected behavior

I was expecting, that the new revision will be created for existing version v1 and it would contain new schema.

Environment Summary

azure-cli                         2.59.0 *

core                              2.59.0 *
telemetry                          1.1.0

Dependencies:
msal                              1.27.0
azure-mgmt-resource             23.1.0b2

Python location 'C:\Program Files\Microsoft SDKs\Azure\CLI2\python.exe'
Extensions directory 'C:\Users\<user_dir>\.azure\cliextensions'

Python (Windows) 3.11.8 (tags/v3.11.8:db85d51, Feb  6 2024, 22:03:32) [MSC v.1937 64 bit (AMD64)]

Legal docs and information: aka.ms/AzureCliLegal

Additional context

No response

rgembalik avatar May 07 '24 10:05 rgembalik

Hi @rgembalik,

2.59.0 is not the latest Azure CLI(2.60.0).

If you haven't already attempted to do so, please upgrade to the latest Azure CLI version by following https://learn.microsoft.com/en-us/cli/azure/update-azure-cli.

Thank you for opening this issue, we will look into it.

yonzhan avatar May 07 '24 10:05 yonzhan

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @solankisamir, @mikebudzynski, @KedarJoshi, @yingru97.

A small update: the same happens on version 2.60.0

rgembalik avatar May 07 '24 10:05 rgembalik

I realized today that when I use az apim api import together with --api-revision, all revisions are overwritten with the referenced api spec. Might this be related?

eflavio avatar Jun 14 '24 21:06 eflavio

@rgembalik I ran into the same issue for a versioned API, setup with a named versionset. Not sure if it is a workaround or as intended, but I seem to be able to get it up and running by providing the --api-id parameter constructed out of the parts

  • The (internal) name (=underlying resource name) of the API, in your example test-echo
  • The target version like v1

So --api-id test-echo-v1, which is also reported as .name property of that versioned API if you would execute a az apim api list --resource-group rg-something --service-name apim-something

Then the --path parameter, which also is a required parameter. That needs to be provided unversioned, so test-echo in your example. Which is also matching the reported .path property of above mentioned API listing. ... Or at least in my setup it does match.

p.s. What is not clear to me based on the documentation of command here: is that the --api-version-set-id needs to be provided as name of the version set, and not the full resourceId (with subscription, resourcegroup, namespace etc) as is needed in the BICEP/ARM templates with which we setup the API initially.

Hope it helps!

markdebruijne avatar Jul 11 '24 11:07 markdebruijne