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

Update region retrieving logic and add logging to it for better debugging options. #35

Merged
merged 2 commits into from
Dec 26, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from typing import Union

import boto3
import requests
Expand All @@ -20,48 +21,78 @@ def __init__(self, **kwargs) -> None:
)
aws_region = kwargs.get("region_name")

self._region_name = os.getenv(
"AWS_REGION",
self._dynamically_get_aws_region(aws_region),
)
self._region_name = self._get_aws_region(aws_region)
self._collector_settings_parameter_name = self._ensure_leading_slash(
collector_settings_parameter_name
)
self._collector_plugins_prefix = self._ensure_leading_slash(
collector_plugins_prefix
)
self._ssm_client = boto3.client("ssm", region_name=self._region_name)
logger.info(
f"Successfully created boto3 SSM client with region = {self._region_name}"
)

@staticmethod
def _dynamically_get_aws_region(check_region_argument: str) -> str:
def _get_aws_region(config_aws_region: str) -> Union[str, None]:
"""
This method attempts to fetch the AWS region using the Instance Metadata Service (IMDS)
if the region is not explicitly provided.
This method attempts to retrieve AWS region information with the following priority:
1) getting region from environment variables;
2) getting region from collector configuration .yaml file;
3) getting region from IMDS.

Parameters:
check_region_argument: the explicitly provided region or None if not provided.
config_aws_region: the region provided from collector configuration .yaml file.

Returns:
The AWS region, either fetched dynamically or from the provided argument.
The AWS region, or None if any of retrieving methods worked.
"""
if check_region_argument is None:
try:
# Token is required for IMDSv2
token_response = requests.put(
"http://169.254.169.254/latest/api/token",
headers={"X-aws-ec2-metadata-token-ttl-seconds": "21600"},
)
token = token_response.text

# Fetch the region
region_response = requests.get(
"http://169.254.169.254/latest/meta-data/placement/region",
headers={"X-aws-ec2-metadata-token": token},
)
return region_response.text
except requests.RequestException as e:
logger.debug(f"Failed to fetch AWS region dynamically from IMDS: {e}")
return check_region_argument
env_aws_region = os.getenv("AWS_REGION")
if env_aws_region:
logger.info(
"Successfully got AWS region information from evironment variable 'AWS_REGION'. "
f"Region = {env_aws_region}."
)
return env_aws_region
logger.info(
"No 'AWS_REGION' evironment variable was provided. "
"Attempting to get region from config."
)

if config_aws_region is not None:
logger.info(
"Successfully got AWS region information from config. "
f"Region = {config_aws_region}."
)
return config_aws_region
logger.info(
"No region_name variable was provided in config. "
"Attempting to retrieve region from IMDS."
)

try:
# Token is required for IMDSv2
token_response = requests.put(
"http://169.254.169.254/latest/api/token",
headers={"X-aws-ec2-metadata-token-ttl-seconds": "21600"},
)
token = token_response.text

# Fetch the region
region_response = requests.get(
"http://169.254.169.254/latest/meta-data/placement/region",
headers={"X-aws-ec2-metadata-token": token},
)
imds_aws_region = region_response.text
logger.info(
"Successfully got AWS region information from IMDS. "
f"Region = {imds_aws_region}."
)
return imds_aws_region
except requests.RequestException as e:
logger.info(f"Failed to retrieve AWS region dynamically from IMDS: {e}")
logger.info("No AWS region information was retrieved. Region = None")
return None

@staticmethod
def _ensure_leading_slash(secret_name: str) -> str:
Expand Down
Loading