From d88c766454674b6365b1efeea957b86e68b135fb Mon Sep 17 00:00:00 2001 From: Aron Gates Date: Sun, 12 Apr 2026 11:47:58 +0100 Subject: [PATCH 1/2] fix: minio env injection and redis volume injection --- .../kubecoderun/templates/deployment.yaml | 10 ++++ helm-deployments/kubecoderun/values.yaml | 16 ++++++ src/config/minio.py | 14 +++-- tests/unit/test_minio_config.py | 52 ++++++++++++++++++- 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/helm-deployments/kubecoderun/templates/deployment.yaml b/helm-deployments/kubecoderun/templates/deployment.yaml index 6f09351..d7ce544 100644 --- a/helm-deployments/kubecoderun/templates/deployment.yaml +++ b/helm-deployments/kubecoderun/templates/deployment.yaml @@ -96,6 +96,10 @@ spec: name: {{ .Values.minio.existingSecret }} {{- end }} {{- end }} + {{- with .Values.env }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} volumeMounts: - name: data mountPath: /data @@ -105,6 +109,9 @@ spec: mountPath: /mnt/secrets-store readOnly: true {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} volumes: - name: data emptyDir: {} @@ -117,6 +124,9 @@ spec: volumeAttributes: secretProviderClass: {{ include "kubecoderun.fullname" . }}-secrets {{- end }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm-deployments/kubecoderun/values.yaml b/helm-deployments/kubecoderun/values.yaml index acff994..2c91c5b 100644 --- a/helm-deployments/kubecoderun/values.yaml +++ b/helm-deployments/kubecoderun/values.yaml @@ -93,6 +93,22 @@ nodeSelector: {} tolerations: [] affinity: {} +# Extra environment variables for the API container +# Useful for mapping secret keys to different env var names +# Example: +# env: +# - name: MINIO_ACCESS_KEY +# valueFrom: +# secretKeyRef: +# name: my-bucket-creds +# key: AWS_ACCESS_KEY_ID +env: [] + +# Extra volumes and volume mounts for the API deployment +# Useful for mounting CA certificates (e.g. Redis TLS, S3/MinIO TLS) +extraVolumes: [] +extraVolumeMounts: [] + # External Dependencies redis: # Reference an existing Kubernetes Secret containing REDIS_URL diff --git a/src/config/minio.py b/src/config/minio.py index e9e89b0..2ad7578 100644 --- a/src/config/minio.py +++ b/src/config/minio.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from pydantic import Field, field_validator, model_validator +from pydantic import AliasChoices, Field, field_validator, model_validator from pydantic_settings import BaseSettings, SettingsConfigDict if TYPE_CHECKING: @@ -19,8 +19,16 @@ class MinIOConfig(BaseSettings): ) endpoint: str = Field(default="localhost:9000", alias="minio_endpoint") - access_key: str | None = Field(default=None, alias="minio_access_key") - secret_key: str | None = Field(default=None, alias="minio_secret_key") + access_key: str | None = Field( + default=None, + alias="minio_access_key", + validation_alias=AliasChoices("minio_access_key", "aws_access_key_id"), + ) + secret_key: str | None = Field( + default=None, + alias="minio_secret_key", + validation_alias=AliasChoices("minio_secret_key", "aws_secret_access_key"), + ) secure: bool = Field(default=False, alias="minio_secure") bucket: str = Field(default="kubecoderun-files", alias="minio_bucket") region: str = Field(default="us-east-1", alias="minio_region") diff --git a/tests/unit/test_minio_config.py b/tests/unit/test_minio_config.py index 0abf65f..e767ac6 100644 --- a/tests/unit/test_minio_config.py +++ b/tests/unit/test_minio_config.py @@ -19,10 +19,20 @@ "MINIO_USE_IAM", ] +# AWS env vars that are also used as fallbacks for MinIO credentials +AWS_CREDENTIAL_VARS = [ + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY", +] + def get_clean_env(): - """Return environment with MINIO_ vars removed.""" - return {k: v for k, v in os.environ.items() if not k.startswith("MINIO_")} + """Return environment with MINIO_ and AWS credential vars removed.""" + return { + k: v + for k, v in os.environ.items() + if not k.startswith("MINIO_") and k not in AWS_CREDENTIAL_VARS + } class TestMinIOConfigValidation: @@ -365,3 +375,41 @@ def test_loads_iam_mode_from_env(self): assert config.use_iam is True assert config.access_key is None assert config.secret_key is None + + def test_loads_from_aws_env_vars_as_fallback(self): + """Test that AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY are accepted as fallbacks.""" + clean_env = get_clean_env() + clean_env.update( + { + "MINIO_ENDPOINT": "s3.example.com:9000", + "AWS_ACCESS_KEY_ID": "aws-access-key", + "AWS_SECRET_ACCESS_KEY": "aws-secret-key-value", + "MINIO_USE_IAM": "false", + } + ) + + with patch.dict(os.environ, clean_env, clear=True): + config = MinIOConfig() + + assert config.access_key == "aws-access-key" + assert config.secret_key == "aws-secret-key-value" + + def test_minio_vars_take_precedence_over_aws_vars(self): + """Test that MINIO_* env vars take precedence over AWS_* env vars.""" + clean_env = get_clean_env() + clean_env.update( + { + "MINIO_ENDPOINT": "minio.example.com:9000", + "MINIO_ACCESS_KEY": "minio-key", + "MINIO_SECRET_KEY": "minio-secret-value", + "AWS_ACCESS_KEY_ID": "aws-key", + "AWS_SECRET_ACCESS_KEY": "aws-secret-value", + "MINIO_USE_IAM": "false", + } + ) + + with patch.dict(os.environ, clean_env, clear=True): + config = MinIOConfig() + + assert config.access_key == "minio-key" + assert config.secret_key == "minio-secret-value" From 03e02e0a3ec373031bd84ac27320a6809f29a2bc Mon Sep 17 00:00:00 2001 From: Aron Gates Date: Sun, 12 Apr 2026 11:50:07 +0100 Subject: [PATCH 2/2] fix: lint --- tests/unit/test_minio_config.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/unit/test_minio_config.py b/tests/unit/test_minio_config.py index e767ac6..db61992 100644 --- a/tests/unit/test_minio_config.py +++ b/tests/unit/test_minio_config.py @@ -28,11 +28,7 @@ def get_clean_env(): """Return environment with MINIO_ and AWS credential vars removed.""" - return { - k: v - for k, v in os.environ.items() - if not k.startswith("MINIO_") and k not in AWS_CREDENTIAL_VARS - } + return {k: v for k, v in os.environ.items() if not k.startswith("MINIO_") and k not in AWS_CREDENTIAL_VARS} class TestMinIOConfigValidation: