Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/msal/region.py: 27%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import json
2import os
3import logging
4import re
6logger = logging.getLogger(__name__)
8_VALID_REGION_RE = re.compile(r"^[a-z][a-z0-9-]*$")
10# IMDS compute metadata API version used for region auto-discovery.
11# Bump this single constant when moving to a newer IMDS API version.
12_IMDS_API_VERSION = "2021-02-01"
15def _validate_region(region, source="unknown"):
16 """Return *region* unchanged if it looks like a valid Azure region name,
17 otherwise log a warning and return ``None``."""
18 if region and _VALID_REGION_RE.match(region):
19 return region
20 if region:
21 logger.warning(
22 "Region from %s was discarded because it contains "
23 "invalid characters: %r", source, region)
24 return None
27def _detect_region(http_client=None):
28 region = os.environ.get("REGION_NAME", "").replace(" ", "").lower() # e.g. westus2
29 if region:
30 return _validate_region(region, source="REGION_NAME env variable")
31 if http_client:
32 return _detect_region_of_azure_vm(http_client) # It could hang for minutes
33 return None
36def _detect_region_of_azure_vm(http_client):
37 url = (
38 "http://169.254.169.254/metadata/instance/compute"
40 # The region is read from the "location" field of the compute metadata.
41 # https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#response-1
42 "?api-version=" + _IMDS_API_VERSION
43 )
44 logger.info(
45 "Connecting to IMDS {}. "
46 "It may take a while if you are running outside of Azure. "
47 "You should consider opting in/out region behavior on-demand, "
48 'by loading a boolean flag "is_deployed_in_azure" '
49 'from your per-deployment config and then do '
50 '"app = ConfidentialClientApplication(..., '
51 'azure_region=is_deployed_in_azure)"'.format(url))
52 try:
53 # https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux#instance-metadata
54 resp = http_client.get(url, headers={"Metadata": "true"})
55 except:
56 logger.info(
57 "IMDS {} unavailable. Perhaps not running in Azure VM?".format(url))
58 return None
59 else:
60 try:
61 location = json.loads(resp.text).get("location")
62 except (ValueError, AttributeError, TypeError):
63 # ValueError: body is not valid JSON;
64 # AttributeError: body is valid JSON but not a JSON object;
65 # TypeError: resp.text is not a string (e.g. a custom http_client).
66 logger.info("IMDS {} returned a malformed response.".format(url))
67 return None
68 if location is not None and not isinstance(location, str):
69 logger.info("IMDS {} returned a non-string location.".format(url))
70 return None
71 return _validate_region(location, source="IMDS endpoint")