mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-03 04:10:49 +08:00
feat: add AWS Secrets Manager Integration
This commit is contained in:
@ -13,5 +13,12 @@ def get_secret_provider():
|
||||
return GoogleCloudStorageSecretProvider()
|
||||
except Exception as e:
|
||||
raise ValueError(f"Failed to initialize google_cloud_storage secret provider {provider_id}") from e
|
||||
elif provider_id == 'aws_secrets_manager':
|
||||
try:
|
||||
from pr_agent.secret_providers.aws_secrets_manager_provider import \
|
||||
AWSSecretsManagerProvider
|
||||
return AWSSecretsManagerProvider()
|
||||
except Exception as e:
|
||||
raise ValueError(f"Failed to initialize aws_secrets_manager secret provider {provider_id}") from e
|
||||
else:
|
||||
raise ValueError("Unknown SECRET_PROVIDER")
|
||||
|
79
pr_agent/secret_providers/aws_secrets_manager_provider.py
Normal file
79
pr_agent/secret_providers/aws_secrets_manager_provider.py
Normal file
@ -0,0 +1,79 @@
|
||||
import json
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
from pr_agent.config_loader import get_settings
|
||||
from pr_agent.log import get_logger
|
||||
from pr_agent.secret_providers.secret_provider import SecretProvider
|
||||
|
||||
|
||||
class AWSSecretsManagerProvider(SecretProvider):
|
||||
def __init__(self):
|
||||
try:
|
||||
# AWS credentials are automatically retrieved from environment variables or IAM roles
|
||||
# Region configuration is flexible like Google Cloud Storage pattern
|
||||
region_name = get_settings().get("aws_secrets_manager.region_name") or \
|
||||
get_settings().get("aws.AWS_REGION_NAME")
|
||||
if region_name:
|
||||
self.client = boto3.client('secretsmanager', region_name=region_name)
|
||||
else:
|
||||
self.client = boto3.client('secretsmanager')
|
||||
|
||||
# Require secret_arn similar to Google Cloud Storage pattern
|
||||
self.secret_arn = get_settings().aws_secrets_manager.secret_arn
|
||||
|
||||
except Exception as e:
|
||||
get_logger().error(f"Failed to initialize AWS Secrets Manager Provider: {e}")
|
||||
raise e
|
||||
|
||||
def get_secret(self, secret_name: str) -> str:
|
||||
"""
|
||||
Retrieve individual secret by name (for webhook tokens)
|
||||
Same error handling pattern as Google Cloud Storage
|
||||
"""
|
||||
try:
|
||||
response = self.client.get_secret_value(SecretId=secret_name)
|
||||
return response['SecretString']
|
||||
except Exception as e:
|
||||
get_logger().warning(f"Failed to get secret {secret_name} from AWS Secrets Manager: {e}")
|
||||
return ""
|
||||
|
||||
def get_all_secrets(self) -> dict:
|
||||
"""
|
||||
Retrieve all secrets for configuration override
|
||||
AWS Secrets Manager specific method (not available in Google Cloud Storage)
|
||||
"""
|
||||
try:
|
||||
response = self.client.get_secret_value(SecretId=self.secret_arn)
|
||||
return json.loads(response['SecretString'])
|
||||
except Exception as e:
|
||||
get_logger().error(f"Failed to get secrets from AWS Secrets Manager {self.secret_arn}: {e}")
|
||||
return {}
|
||||
|
||||
def store_secret(self, secret_name: str, secret_value: str):
|
||||
"""
|
||||
Same error handling pattern as Google Cloud Storage
|
||||
"""
|
||||
try:
|
||||
# Update existing secret
|
||||
self.client.update_secret(
|
||||
SecretId=secret_name,
|
||||
SecretString=secret_value
|
||||
)
|
||||
except ClientError as e:
|
||||
if e.response['Error']['Code'] == 'ResourceNotFoundException':
|
||||
# Create new secret if it doesn't exist
|
||||
try:
|
||||
self.client.create_secret(
|
||||
Name=secret_name,
|
||||
SecretString=secret_value
|
||||
)
|
||||
except Exception as create_error:
|
||||
get_logger().error(f"Failed to store secret {secret_name} in AWS Secrets Manager: {create_error}")
|
||||
raise create_error
|
||||
else:
|
||||
get_logger().error(f"Failed to store secret {secret_name} in AWS Secrets Manager: {e}")
|
||||
raise e
|
||||
except Exception as e:
|
||||
get_logger().error(f"Failed to store secret {secret_name} in AWS Secrets Manager: {e}")
|
||||
raise e
|
Reference in New Issue
Block a user