From 666fcce784ebf6318bf088d6c1f961d4b56fd2bd Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Wed, 18 Dec 2024 15:14:54 +0100 Subject: [PATCH 1/2] opentelemetry-sdk-extension-aws: make ec2 resource detector silent when loaded outside AWS Assume that if we fail to get the token quickly we are not on AWS. --- .../sdk/extension/aws/resource/ec2.py | 28 ++++++++++++++----- .../tests/resource/test_ec2.py | 11 ++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py index b0cfeeb312..b10ada8089 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py @@ -14,6 +14,7 @@ import json import logging +from urllib.error import URLError from urllib.request import Request, urlopen from opentelemetry.sdk.resources import Resource, ResourceDetector @@ -27,39 +28,47 @@ _AWS_METADATA_TOKEN_HEADER = "X-aws-ec2-metadata-token" _GET_METHOD = "GET" +_AWS_METADATA_HOST = "169.254.169.254" -def _aws_http_request(method, path, headers): +def _aws_http_request(method, path, headers, timeout=None): + if timeout is None: + timeout = 5 with urlopen( Request( - "http://169.254.169.254" + path, headers=headers, method=method + "http://" + _AWS_METADATA_HOST + path, + headers=headers, + method=method, ), - timeout=5, + timeout=timeout, ) as response: return response.read().decode("utf-8") -def _get_token(): +def _get_token(timeout=None): return _aws_http_request( "PUT", "/latest/api/token", {"X-aws-ec2-metadata-token-ttl-seconds": "60"}, + timeout, ) -def _get_identity(token): +def _get_identity(token, timeout=None): return _aws_http_request( _GET_METHOD, "/latest/dynamic/instance-identity/document", {_AWS_METADATA_TOKEN_HEADER: token}, + timeout, ) -def _get_host(token): +def _get_host(token, timeout=None): return _aws_http_request( _GET_METHOD, "/latest/meta-data/hostname", {_AWS_METADATA_TOKEN_HEADER: token}, + timeout, ) @@ -72,7 +81,12 @@ class AwsEc2ResourceDetector(ResourceDetector): def detect(self) -> "Resource": try: - token = _get_token() + # If can't get a token quick assume we are not on ec2 + try: + token = _get_token(timeout=1) + except URLError: + return Resource.get_empty() + identity_dict = json.loads(_get_identity(token)) hostname = _get_host(token) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py index 300f963ac5..70034849a2 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py @@ -15,6 +15,7 @@ import unittest from collections import OrderedDict from unittest.mock import patch +from urllib.error import URLError from opentelemetry.sdk.extension.aws.resource.ec2 import ( # pylint: disable=no-name-in-module AwsEc2ResourceDetector, @@ -73,3 +74,13 @@ def test_simple_create( self.assertDictEqual( actual.attributes.copy(), OrderedDict(MockEc2ResourceAttributes) ) + + @patch( + "opentelemetry.sdk.extension.aws.resource.ec2._get_token", + side_effect=URLError("Something went wrong"), + ) + def test_empty_resource_if_token_returns_an_url_error( + self, mock_get_token + ): + actual = AwsEc2ResourceDetector().detect() + self.assertDictEqual(actual.attributes.copy(), OrderedDict()) From e7c28539f74aa08ccd500c2ebddaf30d05f76929 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 19 Dec 2024 10:25:48 +0100 Subject: [PATCH 2/2] Add changelog --- sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md index c1c8286894..25201d51d1 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md +++ b/sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Make ec2 resource detector silent when loaded outside AWS + ([#3120](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3120)) - Make ecs and beanstalk resource detector silent when loaded outside AWS ([#3076](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3076)) - Make EKS resource detector don't warn when not running in EKS