Skip to content

Commit e5e8dc2

Browse files
authored
Merge pull request #1230 from clowder-framework/feature/aws_iam
Use AWS IAM when connecting to S3
2 parents 93d9a20 + 14c3573 commit e5e8dc2

File tree

4 files changed

+128
-19
lines changed

4 files changed

+128
-19
lines changed

backend/app/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class Settings(BaseSettings):
3636
MINIO_EXPIRES: int = 3600 # seconds
3737
MINIO_SECURE: str = "False" # http vs https
3838

39+
# If AWS_IAM is set to True, the MINIO_ACCESS_KEY and MINIO_SECRET_KEY will be ignored and AWS IAM will be used
40+
AWS_IAM: bool = False
41+
3942
# Files in the listed directories can be added to Clowder without copying them elsewhere
4043
LOCAL_WHITELIST: List[str] = []
4144

backend/app/dependencies.py

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
from typing import Generator
1+
import logging
2+
from typing import AsyncGenerator
23

4+
import boto3
35
import pika
46
from app.config import settings
57
from app.search.connect import connect_elasticsearch
@@ -8,14 +10,32 @@
810
from minio.versioningconfig import VersioningConfig
911
from pika.adapters.blocking_connection import BlockingChannel
1012

13+
logger = logging.getLogger(__name__)
14+
logger.setLevel(logging.DEBUG)
1115

12-
async def get_fs() -> Generator:
13-
file_system = Minio(
14-
settings.MINIO_SERVER_URL,
15-
access_key=settings.MINIO_ACCESS_KEY,
16-
secret_key=settings.MINIO_SECRET_KEY,
17-
secure=False,
18-
)
16+
17+
async def get_fs() -> AsyncGenerator[Minio, None]:
18+
# Either use AWS Identity and Access Management (IAM) to connect to S3 or connect to Minio server
19+
if settings.AWS_IAM:
20+
logger.debug("AWS IAM enabled for s3 authentication")
21+
session = boto3.Session()
22+
credentials = session.get_credentials()
23+
credentials = credentials.get_frozen_credentials()
24+
file_system = Minio(
25+
settings.MINIO_EXTERNAL_SERVER_URL,
26+
access_key=credentials.access_key,
27+
secret_key=credentials.secret_key,
28+
session_token=credentials.token,
29+
secure=settings.MINIO_SECURE.lower() == "true",
30+
)
31+
else:
32+
logger.debug("Local MinIO authentication")
33+
file_system = Minio(
34+
settings.MINIO_EXTERNAL_SERVER_URL,
35+
access_key=settings.MINIO_ACCESS_KEY,
36+
secret_key=settings.MINIO_SECRET_KEY,
37+
secure=settings.MINIO_SECURE.lower() == "true",
38+
)
1939
clowder_bucket = settings.MINIO_BUCKET_NAME
2040
if not file_system.bucket_exists(clowder_bucket):
2141
file_system.make_bucket(clowder_bucket)
@@ -24,14 +44,30 @@ async def get_fs() -> Generator:
2444

2545

2646
# This will be needed for generating presigned URL for sharing
27-
async def get_external_fs() -> Generator:
28-
file_system = Minio(
29-
settings.MINIO_EXTERNAL_SERVER_URL,
30-
access_key=settings.MINIO_ACCESS_KEY,
31-
secret_key=settings.MINIO_SECRET_KEY,
32-
secure=settings.MINIO_SECURE.lower() == "true",
33-
)
47+
async def get_external_fs() -> AsyncGenerator[Minio, None]:
48+
# Either use AWS Identity and Access Management (IAM) to connect to S3 or connect to Minio server
49+
if settings.AWS_IAM:
50+
logger.debug("AWS IAM enabled for s3 authentication")
51+
session = boto3.Session()
52+
credentials = session.get_credentials()
53+
credentials = credentials.get_frozen_credentials()
54+
file_system = Minio(
55+
settings.MINIO_EXTERNAL_SERVER_URL,
56+
access_key=credentials.access_key,
57+
secret_key=credentials.secret_key,
58+
session_token=credentials.token,
59+
secure=settings.MINIO_SECURE.lower() == "true",
60+
)
61+
else:
62+
logger.debug("Local MinIO authentication")
63+
file_system = Minio(
64+
settings.MINIO_EXTERNAL_SERVER_URL,
65+
access_key=settings.MINIO_ACCESS_KEY,
66+
secret_key=settings.MINIO_SECRET_KEY,
67+
secure=settings.MINIO_SECURE.lower() == "true",
68+
)
3469
clowder_bucket = settings.MINIO_BUCKET_NAME
70+
logger.debug("Connecting to bucket %s", clowder_bucket)
3571
if not file_system.bucket_exists(clowder_bucket):
3672
file_system.make_bucket(clowder_bucket)
3773
file_system.set_bucket_versioning(clowder_bucket, VersioningConfig(ENABLED))
@@ -44,6 +80,7 @@ def get_rabbitmq() -> BlockingChannel:
4480
parameters = pika.ConnectionParameters(
4581
settings.RABBITMQ_HOST, credentials=credentials
4682
)
83+
logger.debug("Connecting to rabbitmq at %s", settings.RABBITMQ_HOST)
4784
connection = pika.BlockingConnection(parameters)
4885
channel = connection.channel()
4986
return channel

pyproject.toml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,28 @@ description = """Clowder is a cloud native data management framework to support
66
metadata, and automatic data pipelines."""
77
readme = "README.md"
88
requires-python = ">=3.10"
9-
dependencies = ["fastapi==0.95.1", "pydantic==1.10.13", "uvicorn==0.21.1", "motor==3.1.2", "pymongo==4.8.0",
10-
"beanie==1.18.0", "passlib==1.7.4", "bcrypt==4.0.1", "pyjwt==2.6.0", "minio==7.1.14", "python-multipart==0.0.6",
11-
"email-validator==2.0.0.post2", "python-keycloak==2.15.3", "pika==1.3.1", "aio-pika==9.0.5", "elasticsearch==8.7.0",
12-
"rocrate==0.7.0", "itsdangerous==2.1.2", "setuptools"]
9+
dependencies = [
10+
"fastapi==0.95.1",
11+
"pydantic==1.10.13",
12+
"uvicorn==0.21.1",
13+
"motor==3.1.2",
14+
"pymongo==4.8.0",
15+
"beanie==1.18.0",
16+
"passlib==1.7.4",
17+
"bcrypt==4.0.1",
18+
"pyjwt==2.6.0",
19+
"minio==7.1.14",
20+
"python-multipart==0.0.6",
21+
"email-validator==2.0.0.post2",
22+
"python-keycloak==2.15.3",
23+
"pika==1.3.1",
24+
"aio-pika==9.0.5",
25+
"elasticsearch==8.7.0",
26+
"rocrate==0.7.0",
27+
"itsdangerous==2.1.2",
28+
"setuptools",
29+
"boto3>=1.37.8",
30+
]
1331

1432
[dependency-groups]
1533
dev = [

uv.lock

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)