Common: Change AwsInstance to be a Singleton

This commit is contained in:
vakarisz 2022-04-27 18:15:03 +03:00
parent 65eb9b171b
commit 0e1ffb4051
1 changed files with 46 additions and 20 deletions

View File

@ -1,10 +1,13 @@
import json import json
import logging import logging
import re import re
from dataclasses import dataclass
from typing import Tuple, Optional
import requests import requests
from common.cloud.instance import CloudInstance from common.cloud.instance import CloudInstance
from common.utils.code_utils import Singleton
AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS = "169.254.169.254" AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS = "169.254.169.254"
AWS_LATEST_METADATA_URI_PREFIX = "http://{0}/latest/".format(AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS) AWS_LATEST_METADATA_URI_PREFIX = "http://{0}/latest/".format(AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS)
@ -15,45 +18,68 @@ logger = logging.getLogger(__name__)
AWS_TIMEOUT = 2 AWS_TIMEOUT = 2
@dataclass
class AwsInstanceInfo:
instance_id: Optional[str] = None
region: Optional[str] = None
account_id: Optional[str] = None
class AwsInstance(CloudInstance): class AwsInstance(CloudInstance):
""" """
Class which gives useful information about the current instance you're on. Class which gives useful information about the current instance you're on.
""" """
__metaclass__ = Singleton
def is_instance(self):
return self.instance_id is not None
def __init__(self): def __init__(self):
self.instance_id = None self._is_instance, instance_info = AwsInstance._fetch_instance_info()
self.region = None
self.account_id = None
self.instance_id = instance_info.instance_id
self.region = instance_info.region
self.account_id = instance_info.account_id
def is_instance(self) -> bool:
return self._is_instance
@staticmethod
def _fetch_instance_info() -> Tuple[bool, AwsInstanceInfo]:
try: try:
response = requests.get( response = requests.get(
AWS_LATEST_METADATA_URI_PREFIX + "meta-data/instance-id", AWS_LATEST_METADATA_URI_PREFIX + "meta-data/instance-id",
timeout=AWS_TIMEOUT,
)
self.instance_id = response.text if response else None
self.region = self._parse_region(
requests.get(
AWS_LATEST_METADATA_URI_PREFIX + "meta-data/placement/availability-zone",
timeout=AWS_TIMEOUT, timeout=AWS_TIMEOUT,
).text )
if not response:
return False, AwsInstanceInfo()
info = AwsInstanceInfo()
info.instance_id = response.text if response else False
info.region = AwsInstance._parse_region(
requests.get(
AWS_LATEST_METADATA_URI_PREFIX +
"meta-data/placement/availability-zone",
timeout=AWS_TIMEOUT,
).text
) )
except (requests.RequestException, IOError) as e: except (requests.RequestException, IOError) as e:
logger.debug("Failed init of AwsInstance while getting metadata: {}".format(e)) logger.debug("Failed init of AwsInstance while getting metadata: {}".format(e))
return False, AwsInstanceInfo()
try: try:
self.account_id = self._extract_account_id( info.account_id = AwsInstance._extract_account_id(
requests.get( requests.get(
AWS_LATEST_METADATA_URI_PREFIX + "dynamic/instance-identity/document", AWS_LATEST_METADATA_URI_PREFIX +
timeout=AWS_TIMEOUT, "dynamic/instance-identity/document",
).text timeout=AWS_TIMEOUT,
).text
) )
except (requests.RequestException, json.decoder.JSONDecodeError, IOError) as e: except (requests.RequestException, json.decoder.JSONDecodeError, IOError) as e:
logger.debug( logger.debug(
"Failed init of AwsInstance while getting dynamic instance data: {}".format(e) "Failed init of AwsInstance while getting dynamic instance data: {}".format(
e)
) )
return False, AwsInstanceInfo()
return True, info
@staticmethod @staticmethod
def _parse_region(region_url_response): def _parse_region(region_url_response):