Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

400 Client Error when calling resources.check_existence/check_existence_by_id on virtual machine #2808

Closed
dharmab opened this issue Jun 24, 2018 · 4 comments
Labels
Docs question The issue doesn't require a change to the product in order to be resolved. Most issues start as that

Comments

@dharmab
Copy link

dharmab commented Jun 24, 2018

When calling resources.check_existence or resource.check_existence_by_id on a resource of type Microsoft.Compute/virtualMachines, the following exception is raised:

msrestazure.azure_exceptions.CloudError: 400 Client Error: Bad Request for url: https://management.azure.com/subscriptions/REDACTED_GUID/resourceGroups/REDACTED/providers/Microsoft.Compute/virtualMachines/REDACTED?api-version=2017-05-10

I've tested with both (azure-mgmt-resource==1.2.1, api_version=='2017-05-10') and (azure-mgmt-resource==2.0.0rc2, api_version='2018-05-10').

@lmazuel
Copy link
Member

lmazuel commented Jun 26, 2018

Hi @dharmab
I know it's confusing, but the api-version to use when using any methods in the "resources" operation group is the one of the provide, not the generic one of ARM.
If you case, this should be (random example) 2017-12-01

client.resources.check_existence_by_id(
    '/subscriptions/REDACTED_GUID/resourceGroups/REDACTED/providers/Microsoft.Compute/virtualMachines/REDACTED',
    '2017-12-01'
)

Could you confirm?

@lmazuel lmazuel added Docs question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Jun 26, 2018
@dharmab
Copy link
Author

dharmab commented Jun 26, 2018

Ah, that makes sense! I retried using the same API version that the VM was provisioned with, and don't get the 400 error. However, I now get a 405:

  File "/usr/local/lib/python3.6/site-packages/azure/mgmt/resource/resources/v2017_05_10/operations/resources_operations.py", line 793, in check_existence_by_id
    raise exp
msrestazure.azure_exceptions.CloudError: 405 Client Error: Method Not Allowed for url: https://management.azure.com/subscriptions/REDACTED_GUID/resourceGroups/REDACTED/providers/Microsoft.Compute/virtualMachines/REDACTED?api-version=2017-12-01

A code snippet to demonstrate my usage:

    vm_resource_args = {
        'resource_id': '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Compute/virtualMachines/{}'.format(config['Subscription'], config['ResourceGroup'], vm_name),
        'api_version': azutil.resource.ApiVersion.VMSS.value
    }

    try:
        if resource_client.resources.check_existence_by_id(**vm_resource_args):
            logger.info(f'Deleting VM: {vm_name}')
            poller = resource_client.resources.delete_by_id(**vm_resource_args)
            __wait_for_long_azure_operation('Deletion', poller=poller)
        else:
            logger.info(f'Could not find etcd VM: {vm_name} (previously deleted?)')
    except CloudError as e:
        __log_inner_azure_errors_and_rethrow(e)

@lmazuel
Copy link
Member

lmazuel commented Jun 26, 2018

"check existence" is implemented as HTTP HEAD, which is basically a HTTP GET without body (for performance). Not all RP supports this.
The approach I would suggest is to try "check existence", and if not allowed try a "get_by_id". Something like

def resource_exists(**vm_resource_args):
    try:
        return resource_client.resources.check_existence_by_id(**vm_resource_args)
    except CloudError as e:
        if e.status_code == 405: # HEAD not supported
            try:
                resource_client.resources.get_by_id(**vm_resource_args)
                return True
            except CloudError:
                return False  # Likely 404, might want to test it explicitly
        raise # If not 405, not expected

This should still raise for unrelated problems (connection, credentials, etc.), and return True/False if applicable.
Note that it's not an official sample, it's just an example of the possible approach if you want to try the approach HEAD/GET.

@dharmab
Copy link
Author

dharmab commented Jun 26, 2018

Adapting the get_by_id fallback worked great! Is it possible for check_existence_by_id to fallback?

In any case, the workaround is usable and I can accomplish what I initially wanted to do. Thanks!

@github-actions github-actions bot locked and limited conversation to collaborators Apr 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Docs question The issue doesn't require a change to the product in order to be resolved. Most issues start as that
Projects
None yet
Development

No branches or pull requests

3 participants