From 93f24f658eb9233d3e5dd6579f3f009c34134198 Mon Sep 17 00:00:00 2001
From: Eduard Marbach <mail@eduard-marbach.de>
Date: Tue, 25 Jul 2023 08:41:05 +0200
Subject: [PATCH 1/2] fix: aws warnings regarding ssl connection

---
 nautobot_secrets_providers/providers/aws.py | 110 ++++++++++----------
 1 file changed, 57 insertions(+), 53 deletions(-)

diff --git a/nautobot_secrets_providers/providers/aws.py b/nautobot_secrets_providers/providers/aws.py
index 4671808..5374c6b 100644
--- a/nautobot_secrets_providers/providers/aws.py
+++ b/nautobot_secrets_providers/providers/aws.py
@@ -9,11 +9,11 @@
 except (ImportError, ModuleNotFoundError):
     boto3 = None
 
-from django import forms
+from contextlib import closing
 
+from django import forms
+from nautobot.extras.secrets import SecretsProvider, exceptions
 from nautobot.utilities.forms import BootstrapMixin
-from nautobot.extras.secrets import exceptions, SecretsProvider
-
 
 __all__ = ("AWSSecretsManagerSecretsProvider", "AWSSystemsManagerParameterStore")
 
@@ -53,42 +53,44 @@ def get_value_for_secret(cls, secret, obj=None, **kwargs):
 
         # Create a Secrets Manager client.
         session = boto3.session.Session()
-        client = session.client(service_name="secretsmanager", region_name=region_name)
 
-        # This is based on sample code to only handle the specific exceptions for the 'GetSecretValue' API.
-        # See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
-        # We rethrow the exception by default.
-        try:
-            get_secret_value_response = client.get_secret_value(SecretId=secret_name)
-        except ClientError as err:
-            if err.response["Error"]["Code"] == "DecryptionFailureException":  # pylint: disable=no-else-raise
-                # Secrets Manager can't decrypt the protected secret text using the provided KMS key.
-                # Deal with the exception here, and/or rethrow at your discretion.
-                raise exceptions.SecretProviderError(secret, cls, str(err))
-            elif err.response["Error"]["Code"] == "InternalServiceErrorException":
-                # An error occurred on the server side.
-                # Deal with the exception here, and/or rethrow at your discretion.
-                raise exceptions.SecretProviderError(secret, cls, str(err))
-            elif err.response["Error"]["Code"] == "InvalidParameterException":
-                # You provided an invalid value for a parameter.
-                # Deal with the exception here, and/or rethrow at your discretion.
-                raise exceptions.SecretParametersError(secret, cls, str(err))
-            elif err.response["Error"]["Code"] == "InvalidRequestException":
-                # You provided a parameter value that is not valid for the current state of the resource.
-                # Deal with the exception here, and/or rethrow at your discretion.
-                raise exceptions.SecretProviderError(secret, cls, str(err))
-            elif err.response["Error"]["Code"] == "ResourceNotFoundException":
-                # We can't find the resource that you asked for.
-                # Deal with the exception here, and/or rethrow at your discretion.
-                raise exceptions.SecretValueNotFoundError(secret, cls, str(err))
-        else:
-            # Decrypts secret using the associated KMS CMK.
-            # Depending on whether the secret is a string or binary, one of these fields will be populated.
-            if "SecretString" in get_secret_value_response:
-                secret_value = get_secret_value_response["SecretString"]
+        # https://github.com/boto/boto3/issues/454
+        with closing(session.client(service_name="secretsmanager", region_name=region_name)) as client:
+
+            # This is based on sample code to only handle the specific exceptions for the 'GetSecretValue' API.
+            # See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
+            # We rethrow the exception by default.
+            try:
+                get_secret_value_response = client.get_secret_value(SecretId=secret_name)
+            except ClientError as err:
+                if err.response["Error"]["Code"] == "DecryptionFailureException":  # pylint: disable=no-else-raise
+                    # Secrets Manager can't decrypt the protected secret text using the provided KMS key.
+                    # Deal with the exception here, and/or rethrow at your discretion.
+                    raise exceptions.SecretProviderError(secret, cls, str(err))
+                elif err.response["Error"]["Code"] == "InternalServiceErrorException":
+                    # An error occurred on the server side.
+                    # Deal with the exception here, and/or rethrow at your discretion.
+                    raise exceptions.SecretProviderError(secret, cls, str(err))
+                elif err.response["Error"]["Code"] == "InvalidParameterException":
+                    # You provided an invalid value for a parameter.
+                    # Deal with the exception here, and/or rethrow at your discretion.
+                    raise exceptions.SecretParametersError(secret, cls, str(err))
+                elif err.response["Error"]["Code"] == "InvalidRequestException":
+                    # You provided a parameter value that is not valid for the current state of the resource.
+                    # Deal with the exception here, and/or rethrow at your discretion.
+                    raise exceptions.SecretProviderError(secret, cls, str(err))
+                elif err.response["Error"]["Code"] == "ResourceNotFoundException":
+                    # We can't find the resource that you asked for.
+                    # Deal with the exception here, and/or rethrow at your discretion.
+                    raise exceptions.SecretValueNotFoundError(secret, cls, str(err))
             else:
-                # TODO(jathan): Do we care about this? Let's figure out what to do about a binary value?
-                secret_value = base64.b64decode(get_secret_value_response["SecretBinary"])  # noqa
+                # Decrypts secret using the associated KMS CMK.
+                # Depending on whether the secret is a string or binary, one of these fields will be populated.
+                if "SecretString" in get_secret_value_response:
+                    secret_value = get_secret_value_response["SecretString"]
+                else:
+                    # TODO(jathan): Do we care about this? Let's figure out what to do about a binary value?
+                    secret_value = base64.b64decode(get_secret_value_response["SecretBinary"])  # noqa
 
         # If we get this far it should be valid JSON.
         data = json.loads(secret_value)
@@ -136,24 +138,26 @@ def get_value_for_secret(cls, secret, obj=None, **kwargs):
 
         # Create a SSM client.
         session = boto3.session.Session()
-        client = session.client(service_name="ssm", region_name=parameters.get("region"))
-        try:
-            get_secret_value_response = client.get_parameter(Name=parameters.get("name"), WithDecryption=True)
-        except ClientError as err:
-            if err.response["Error"]["Code"] == "ParameterNotFound":
-                raise exceptions.SecretParametersError(secret, cls, str(err))
 
-            if err.response["Error"]["Code"] == "ParameterVersionNotFound":
-                raise exceptions.SecretValueNotFoundError(secret, cls, str(err))
-
-            raise exceptions.SecretProviderError(secret, cls, str(err))
-        else:
+        # https://github.com/boto/boto3/issues/454
+        with closing(session.client(service_name="ssm", region_name=parameters.get("region"))) as client:
             try:
-                # Fetch the Value field from the parameter which must be a json field.
-                data = json.loads(get_secret_value_response["Parameter"]["Value"])
-            except ValueError as err:
-                msg = "InvalidJson"
-                raise exceptions.SecretValueNotFoundError(secret, cls, msg) from err
+                get_secret_value_response = client.get_parameter(Name=parameters.get("name"), WithDecryption=True)
+            except ClientError as err:
+                if err.response["Error"]["Code"] == "ParameterNotFound":
+                    raise exceptions.SecretParametersError(secret, cls, str(err))
+
+                if err.response["Error"]["Code"] == "ParameterVersionNotFound":
+                    raise exceptions.SecretValueNotFoundError(secret, cls, str(err))
+
+                raise exceptions.SecretProviderError(secret, cls, str(err))
+            else:
+                try:
+                    # Fetch the Value field from the parameter which must be a json field.
+                    data = json.loads(get_secret_value_response["Parameter"]["Value"])
+                except ValueError as err:
+                    msg = "InvalidJson"
+                    raise exceptions.SecretValueNotFoundError(secret, cls, msg) from err
         try:
             # Return the value of the secret key configured in the nautobot secret.
             return data[parameters.get("key")]

From 4547bd41d815abde71ba4ff385538a26ebf269fd Mon Sep 17 00:00:00 2001
From: Glenn Matthews <glenn.matthews@networktocode.com>
Date: Fri, 8 Dec 2023 11:18:52 -0500
Subject: [PATCH 2/2] Update aws.py for black

---
 nautobot_secrets_providers/providers/aws.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/nautobot_secrets_providers/providers/aws.py b/nautobot_secrets_providers/providers/aws.py
index eef5a47..dc6a0bf 100644
--- a/nautobot_secrets_providers/providers/aws.py
+++ b/nautobot_secrets_providers/providers/aws.py
@@ -59,7 +59,6 @@ def get_value_for_secret(cls, secret, obj=None, **kwargs):
 
         # https://github.com/boto/boto3/issues/454
         with closing(session.client(service_name="secretsmanager", region_name=region_name)) as client:
-
             # This is based on sample code to only handle the specific exceptions for the 'GetSecretValue' API.
             # See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
             # We rethrow the exception by default.