From d62491f327345c662f73a2e9e1bd23a2e806769e Mon Sep 17 00:00:00 2001 From: "Jonathan M. Henson" Date: Mon, 30 Oct 2023 08:51:52 -0700 Subject: [PATCH] Env Detection (#507) Co-authored-by: Michael Graeb Co-authored-by: Waqar Ahmed Khan --- awscrt/s3.py | 31 ++++++++++++++++++++++++++++++- crt/aws-c-auth | 2 +- crt/aws-c-common | 2 +- crt/aws-c-s3 | 2 +- crt/aws-lc | 2 +- source/module.c | 2 ++ source/s3.h | 3 +++ source/s3_client.c | 27 +++++++++++++++++++++++++++ 8 files changed, 66 insertions(+), 5 deletions(-) diff --git a/awscrt/s3.py b/awscrt/s3.py index 26432270a..c06f7bf4c 100644 --- a/awscrt/s3.py +++ b/awscrt/s3.py @@ -10,7 +10,8 @@ from awscrt import NativeResource from awscrt.http import HttpRequest from awscrt.io import ClientBootstrap, TlsConnectionOptions -from awscrt.auth import AwsCredentialsProvider, AwsSignatureType, AwsSignedBodyHeaderType, AwsSignedBodyValue, AwsSigningAlgorithm, AwsSigningConfig +from awscrt.auth import AwsCredentialsProvider, AwsSignatureType, AwsSignedBodyHeaderType, AwsSignedBodyValue, \ + AwsSigningAlgorithm, AwsSigningConfig import awscrt.exceptions from dataclasses import dataclass import threading @@ -178,6 +179,7 @@ def __init__( def on_shutdown(): shutdown_event.set() + self._region = region self.shutdown_event = shutdown_event @@ -503,3 +505,30 @@ def create_default_s3_signing_config(*, region: str, credential_provider: AwsCre use_double_uri_encode=False, should_normalize_uri_path=False, ) + + +def get_ec2_instance_type(): + """ + First this function will check it's running on EC2 via. attempting to read DMI info to avoid making IMDS calls. + + If the function detects it's on EC2, and it was able to detect the instance type without a call to IMDS + it will return it. + + Finally, it will call IMDS and return the instance type from there. + Note that in the case of the IMDS call, a new client stack is spun up using 1 background thread. The call is made + synchronously with a 1 second timeout: It's not cheap. To make this easier, the underlying result is cached + internally and will be freed when this module is unloaded is called. + + Returns: + A string indicating the instance type or None if it could not be determined. + """ + return _awscrt.s3_get_ec2_instance_type() + + +def is_optimized_for_system(): + """ + Returns: + true if the current build of this module has an optimized configuration + for the current system. + """ + return _awscrt.s3_is_crt_s3_optimized_for_system() diff --git a/crt/aws-c-auth b/crt/aws-c-auth index c75e00804..ecbb37fe6 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit c75e00804da02fef8275b29509bd7180cb7e4667 +Subproject commit ecbb37fe6549e7a0f5814050be076a2312118b38 diff --git a/crt/aws-c-common b/crt/aws-c-common index 4c0a9f579..e381a7bee 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 4c0a9f579d3064f086b42a2d39aaea721e7e71ca +Subproject commit e381a7beeacb070f1816989dcb0e2c0ae6eccaea diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 684484e39..ecaf3f754 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 684484e39dbc1a7414907f0af4001a89e85d9708 +Subproject commit ecaf3f7549c8339f678ed348706fcc62038a5a5e diff --git a/crt/aws-lc b/crt/aws-lc index e42a4ef22..40f0eb69c 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit e42a4ef2270c4873e98101098edd1f0aaece966d +Subproject commit 40f0eb69cfbdb201308c51bf12feffc247fb4186 diff --git a/source/module.c b/source/module.c index 132f1353d..182b50860 100644 --- a/source/module.c +++ b/source/module.c @@ -799,6 +799,8 @@ static PyMethodDef s_module_methods[] = { AWS_PY_METHOD_DEF(s3_client_new, METH_VARARGS), AWS_PY_METHOD_DEF(s3_client_make_meta_request, METH_VARARGS), AWS_PY_METHOD_DEF(s3_meta_request_cancel, METH_VARARGS), + AWS_PY_METHOD_DEF(s3_get_ec2_instance_type, METH_NOARGS), + AWS_PY_METHOD_DEF(s3_is_crt_s3_optimized_for_system, METH_NOARGS), /* WebSocket */ AWS_PY_METHOD_DEF(websocket_client_connect, METH_VARARGS), diff --git a/source/s3.h b/source/s3.h index 7a35c26e0..85543adc0 100644 --- a/source/s3.h +++ b/source/s3.h @@ -7,6 +7,9 @@ #include "module.h" +PyObject *aws_py_s3_get_ec2_instance_type(PyObject *self, PyObject *args); +PyObject *aws_py_s3_is_crt_s3_optimized_for_system(PyObject *self, PyObject *args); + PyObject *aws_py_s3_client_new(PyObject *self, PyObject *args); PyObject *aws_py_s3_client_make_meta_request(PyObject *self, PyObject *args); diff --git a/source/s3_client.c b/source/s3_client.c index 4761c59ff..171c66608 100644 --- a/source/s3_client.c +++ b/source/s3_client.c @@ -10,6 +10,33 @@ static const char *s_capsule_name_s3_client = "aws_s3_client"; +PyObject *aws_py_s3_get_ec2_instance_type(PyObject *self, PyObject *args) { + (void)self; + (void)args; + + const struct aws_s3_platform_info *platform_info = aws_s3_get_current_platform_info(); + + if (platform_info->instance_type.len) { + PyObject *ret_value = PyUnicode_FromAwsByteCursor(&platform_info->instance_type); + return ret_value; + } + + Py_RETURN_NONE; +} + +PyObject *aws_py_s3_is_crt_s3_optimized_for_system(PyObject *self, PyObject *args) { + (void)self; + (void)args; + + const struct aws_s3_platform_info *platform_info = aws_s3_get_current_platform_info(); + + if (platform_info->has_recommended_configuration) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + struct s3_client_binding { struct aws_s3_client *native;