feat: update Helm chart version to 0.1.5 and add values schema for configuration

Signed-off-by: Noste <83548733+Noooste@users.noreply.github.com>
This commit is contained in:
Noste
2025-12-22 00:10:27 +01:00
parent 62b76769d0
commit b4bdd13743
2 changed files with 811 additions and 1 deletions
+2 -1
View File
@@ -1,8 +1,9 @@
apiVersion: v2
name: garage-ui
description: A Helm chart for Garage UI - Web interface for Garage S3 object storage
icon: https://helm.noste.dev/garage.png
type: application
version: 0.1.4
version: 0.1.5
appVersion: "v0.0.10"
keywords:
- garage
+809
View File
@@ -0,0 +1,809 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Garage UI Helm Chart Values",
"description": "Configuration values for the Garage UI Helm chart deployment",
"type": "object",
"required": ["replicaCount", "image", "config"],
"properties": {
"replicaCount": {
"type": "integer",
"description": "Number of replica pods to run. Increase for high availability (recommended: 2-3 for production)",
"minimum": 1,
"default": 1
},
"image": {
"type": "object",
"description": "Docker image configuration",
"required": ["repository", "pullPolicy"],
"properties": {
"repository": {
"type": "string",
"description": "Container registry and image name",
"default": "noooste/garage-ui"
},
"pullPolicy": {
"type": "string",
"description": "Image pull policy",
"enum": ["Always", "IfNotPresent", "Never"],
"default": "IfNotPresent"
},
"tag": {
"type": "string",
"description": "Image tag to use (defaults to chart appVersion if empty)",
"default": ""
}
}
},
"imagePullSecrets": {
"type": "array",
"description": "Credentials for accessing private container registries",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"default": []
},
"nameOverride": {
"type": "string",
"description": "Override the default chart name in resource names",
"default": ""
},
"fullnameOverride": {
"type": "string",
"description": "Override the full resource name (includes release name)",
"default": ""
},
"config": {
"type": "object",
"description": "Main application configuration",
"required": ["server", "garage", "auth", "cors", "logging"],
"properties": {
"server": {
"type": "object",
"description": "Server configuration",
"required": ["host", "port", "environment", "protocol"],
"properties": {
"host": {
"type": "string",
"description": "Network interface to bind to (0.0.0.0 for all interfaces)",
"default": "0.0.0.0"
},
"port": {
"type": "integer",
"description": "Port the application listens on",
"minimum": 1,
"maximum": 65535,
"default": 8080
},
"environment": {
"type": "string",
"description": "Deployment environment",
"enum": ["production", "development", "staging"],
"default": "production"
},
"domain": {
"type": "string",
"description": "Domain name for the application",
"default": "garage-ui.example.com"
},
"protocol": {
"type": "string",
"description": "Protocol for internal communication",
"enum": ["http", "https"],
"default": "http"
},
"root_url": {
"type": "string",
"description": "Full external URL for OAuth2 redirects (REQUIRED when OIDC is enabled)",
"pattern": "^https?://",
"default": "https://garage-ui.example.com"
}
}
},
"garage": {
"type": "object",
"description": "Garage S3 storage configuration",
"required": ["endpoint", "region", "admin_endpoint"],
"properties": {
"endpoint": {
"type": "string",
"description": "Garage S3 API endpoint",
"pattern": "^https?://",
"default": "http://garage:3900"
},
"region": {
"type": "string",
"description": "S3 region name (can be any value for Garage)",
"default": "garage"
},
"admin_endpoint": {
"type": "string",
"description": "Garage Admin API endpoint",
"pattern": "^https?://",
"default": "http://garage:3903"
},
"admin_token": {
"type": "string",
"description": "Admin API bearer token (ignored if existingSecret is configured)",
"default": ""
},
"existingSecret": {
"type": "object",
"description": "Use an existing Kubernetes secret for the admin token",
"properties": {
"name": {
"type": "string",
"description": "Name of the existing secret containing the admin token",
"default": ""
},
"key": {
"type": "string",
"description": "Key within the secret that contains the admin token value",
"default": "admin-token"
}
}
}
}
},
"auth": {
"type": "object",
"description": "Authentication configuration (one or both methods can be enabled)",
"required": ["admin", "oidc"],
"properties": {
"admin": {
"type": "object",
"description": "Admin authentication settings (username/password)",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable admin authentication",
"default": false
},
"username": {
"type": "string",
"description": "Username for admin login",
"default": "admin"
},
"password": {
"type": "string",
"description": "Password for admin login (ignored if existingSecret is configured)",
"default": "changeme"
},
"existingSecret": {
"type": "object",
"description": "Use an existing Kubernetes secret for the admin password",
"properties": {
"name": {
"type": "string",
"description": "Name of the existing secret containing the admin password",
"default": ""
},
"key": {
"type": "string",
"description": "Key within the secret that contains the admin password value",
"default": "admin-password"
}
}
}
}
},
"oidc": {
"type": "object",
"description": "OpenID Connect (OIDC) configuration",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable OIDC authentication",
"default": false
},
"provider_name": {
"type": "string",
"description": "Display name of your OIDC provider",
"default": "Keycloak"
},
"client_id": {
"type": "string",
"description": "OAuth2 client ID registered with your OIDC provider",
"default": "garage-ui"
},
"client_secret": {
"type": "string",
"description": "OAuth2 client secret (ignored if existingSecret is configured)",
"default": "your-client-secret"
},
"existingSecret": {
"type": "object",
"description": "Use an existing Kubernetes secret for the client secret",
"properties": {
"name": {
"type": "string",
"description": "Name of the existing secret containing the client secret",
"default": ""
},
"key": {
"type": "string",
"description": "Key within the secret that contains the client secret value",
"default": "client-secret"
}
}
},
"scopes": {
"type": "array",
"description": "OAuth2/OIDC scopes to request during authentication",
"items": {
"type": "string"
},
"default": ["openid", "email", "profile"]
},
"issuer_url": {
"type": "string",
"description": "OIDC issuer URL (base URL for OIDC discovery)",
"pattern": "^https?://",
"default": "https://keycloak.example.com/realms/master"
},
"auth_url": {
"type": "string",
"description": "Authorization endpoint URL",
"pattern": "^https?://",
"default": "https://keycloak.example.com/realms/master/protocol/openid-connect/auth"
},
"token_url": {
"type": "string",
"description": "Token endpoint URL",
"pattern": "^https?://",
"default": "https://keycloak.example.com/realms/master/protocol/openid-connect/token"
},
"userinfo_url": {
"type": "string",
"description": "User info endpoint URL",
"pattern": "^https?://",
"default": "https://keycloak.example.com/realms/master/protocol/openid-connect/userinfo"
},
"skip_issuer_check": {
"type": "boolean",
"description": "Skip issuer validation (not recommended for production)",
"default": false
},
"skip_expiry_check": {
"type": "boolean",
"description": "Skip token expiry validation (not recommended for production)",
"default": false
},
"email_attribute": {
"type": "string",
"description": "Claim containing user's email address",
"default": "email"
},
"username_attribute": {
"type": "string",
"description": "Claim containing user's username/login ID",
"default": "preferred_username"
},
"name_attribute": {
"type": "string",
"description": "Claim containing user's display name",
"default": "name"
},
"role_attribute_path": {
"type": "string",
"description": "Path to roles in the OIDC token claims",
"default": "resource_access.garage-ui.roles"
},
"admin_role": {
"type": "string",
"description": "Role name that grants admin privileges",
"default": "admin"
},
"tls_skip_verify": {
"type": "boolean",
"description": "Skip TLS certificate verification (only for testing)",
"default": false
},
"session_max_age": {
"type": "integer",
"description": "Session validity duration in seconds",
"minimum": 60,
"default": 86400
},
"cookie_name": {
"type": "string",
"description": "Name of the session cookie",
"default": "garage_session"
},
"cookie_secure": {
"type": "boolean",
"description": "Only send cookie over HTTPS connections",
"default": true
},
"cookie_http_only": {
"type": "boolean",
"description": "Prevent JavaScript access to the cookie",
"default": true
},
"cookie_same_site": {
"type": "string",
"description": "SameSite cookie attribute for CSRF protection",
"enum": ["lax", "strict", "none"],
"default": "lax"
}
}
}
}
},
"cors": {
"type": "object",
"description": "CORS (Cross-Origin Resource Sharing) configuration",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable CORS",
"default": true
},
"allowed_origins": {
"type": "array",
"description": "List of allowed origins",
"items": {
"type": "string"
},
"default": ["*"]
},
"allowed_methods": {
"type": "array",
"description": "HTTP methods allowed in CORS requests",
"items": {
"type": "string",
"enum": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"]
},
"default": ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
},
"allowed_headers": {
"type": "array",
"description": "HTTP headers allowed in CORS requests",
"items": {
"type": "string"
},
"default": ["Origin", "Content-Type", "Accept", "Authorization"]
},
"allow_credentials": {
"type": "boolean",
"description": "Allow credentials in CORS requests (cannot be true when allowed_origins contains '*')",
"default": false
},
"max_age": {
"type": "integer",
"description": "Cache duration for CORS preflight responses in seconds",
"minimum": 0,
"default": 3600
}
}
},
"logging": {
"type": "object",
"description": "Logging configuration",
"required": ["level", "format"],
"properties": {
"level": {
"type": "string",
"description": "Log verbosity level",
"enum": ["debug", "info", "warn", "error"],
"default": "info"
},
"format": {
"type": "string",
"description": "Log output format",
"enum": ["json", "text"],
"default": "json"
}
}
}
}
},
"podAnnotations": {
"type": "object",
"description": "Annotations to add to the pod",
"additionalProperties": {
"type": "string"
},
"default": {}
},
"podSecurityContext": {
"type": "object",
"description": "Pod-level security context",
"properties": {
"runAsNonRoot": {
"type": "boolean",
"description": "Run containers as non-root user",
"default": true
},
"runAsUser": {
"type": "integer",
"description": "User ID to run containers as",
"minimum": 0,
"default": 1000
},
"fsGroup": {
"type": "integer",
"description": "Group ID for filesystem access",
"minimum": 0,
"default": 1000
}
}
},
"securityContext": {
"type": "object",
"description": "Container-level security context",
"properties": {
"allowPrivilegeEscalation": {
"type": "boolean",
"description": "Allow privilege escalation",
"default": false
},
"capabilities": {
"type": "object",
"properties": {
"drop": {
"type": "array",
"items": {
"type": "string"
},
"default": ["ALL"]
}
}
},
"readOnlyRootFilesystem": {
"type": "boolean",
"description": "Mount root filesystem as read-only",
"default": false
}
}
},
"service": {
"type": "object",
"description": "Kubernetes Service configuration",
"required": ["type", "port"],
"properties": {
"type": {
"type": "string",
"description": "Service type",
"enum": ["ClusterIP", "NodePort", "LoadBalancer"],
"default": "ClusterIP"
},
"port": {
"type": "integer",
"description": "Port the service listens on",
"minimum": 1,
"maximum": 65535,
"default": 80
}
}
},
"ingress": {
"type": "object",
"description": "Ingress configuration",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable ingress",
"default": false
},
"className": {
"type": "string",
"description": "Ingress class name",
"default": "nginx"
},
"annotations": {
"type": "object",
"description": "Additional annotations for the ingress",
"additionalProperties": {
"type": "string"
},
"default": {}
},
"hosts": {
"type": "array",
"description": "Hostname and path configuration",
"items": {
"type": "object",
"required": ["host"],
"properties": {
"host": {
"type": "string",
"description": "Hostname for the ingress"
},
"paths": {
"type": "array",
"items": {
"type": "object",
"required": ["path", "pathType"],
"properties": {
"path": {
"type": "string",
"description": "URL path"
},
"pathType": {
"type": "string",
"description": "Path type",
"enum": ["Prefix", "Exact", "ImplementationSpecific"]
}
}
}
}
}
},
"default": [
{
"host": "garage-ui.local",
"paths": [
{
"path": "/",
"pathType": "Prefix"
}
]
}
]
},
"tls": {
"type": "array",
"description": "TLS/SSL configuration",
"items": {
"type": "object",
"properties": {
"secretName": {
"type": "string",
"description": "Name of the TLS secret"
},
"hosts": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"default": []
}
}
},
"resources": {
"type": "object",
"description": "CPU and memory resource limits and requests",
"properties": {
"limits": {
"type": "object",
"description": "Maximum resources the container can use",
"properties": {
"cpu": {
"type": "string",
"description": "Maximum CPU cores",
"pattern": "^[0-9]+(m|[0-9]*\\.?[0-9]+)?$",
"default": "500m"
},
"memory": {
"type": "string",
"description": "Maximum memory",
"pattern": "^[0-9]+(Ki|Mi|Gi|Ti|Pi|Ei)?$",
"default": "512Mi"
}
}
},
"requests": {
"type": "object",
"description": "Guaranteed resources allocated to the container",
"properties": {
"cpu": {
"type": "string",
"description": "Guaranteed CPU",
"pattern": "^[0-9]+(m|[0-9]*\\.?[0-9]+)?$",
"default": "100m"
},
"memory": {
"type": "string",
"description": "Guaranteed memory",
"pattern": "^[0-9]+(Ki|Mi|Gi|Ti|Pi|Ei)?$",
"default": "128Mi"
}
}
}
}
},
"livenessProbe": {
"type": "object",
"description": "Liveness probe configuration",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable liveness probe",
"default": true
},
"httpGet": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Health check endpoint path",
"default": "/health"
},
"port": {
"type": "string",
"description": "Port name",
"default": "http"
}
}
},
"initialDelaySeconds": {
"type": "integer",
"description": "Wait time before starting liveness checks",
"minimum": 0,
"default": 30
},
"periodSeconds": {
"type": "integer",
"description": "How often to perform the probe",
"minimum": 1,
"default": 10
},
"timeoutSeconds": {
"type": "integer",
"description": "Maximum time to wait for probe completion",
"minimum": 1,
"default": 3
},
"failureThreshold": {
"type": "integer",
"description": "Consecutive failures before restarting",
"minimum": 1,
"default": 3
}
}
},
"readinessProbe": {
"type": "object",
"description": "Readiness probe configuration",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable readiness probe",
"default": true
},
"httpGet": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Readiness check endpoint path",
"default": "/health"
},
"port": {
"type": "string",
"description": "Port name",
"default": "http"
}
}
},
"initialDelaySeconds": {
"type": "integer",
"description": "Wait time before starting readiness checks",
"minimum": 0,
"default": 10
},
"periodSeconds": {
"type": "integer",
"description": "How often to perform the probe",
"minimum": 1,
"default": 5
},
"timeoutSeconds": {
"type": "integer",
"description": "Maximum time to wait for probe completion",
"minimum": 1,
"default": 3
},
"failureThreshold": {
"type": "integer",
"description": "Consecutive failures before marking as not ready",
"minimum": 1,
"default": 3
}
}
},
"serviceMonitor": {
"type": "object",
"description": "ServiceMonitor for Prometheus Operator",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable ServiceMonitor creation",
"default": false
},
"interval": {
"type": "string",
"description": "How often Prometheus should scrape metrics",
"pattern": "^[0-9]+(s|m|h)$",
"default": "30s"
},
"path": {
"type": "string",
"description": "Metrics endpoint path",
"default": "/api/v1/monitoring/metrics"
},
"labels": {
"type": "object",
"description": "Additional labels for the ServiceMonitor",
"additionalProperties": {
"type": "string"
},
"default": {}
}
}
},
"networkPolicy": {
"type": "object",
"description": "NetworkPolicy configuration",
"required": ["enabled"],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable or disable NetworkPolicy creation",
"default": false
},
"policyTypes": {
"type": "array",
"description": "Types of policies to enforce",
"items": {
"type": "string",
"enum": ["Ingress", "Egress"]
},
"default": ["Ingress", "Egress"]
}
}
},
"nodeSelector": {
"type": "object",
"description": "Node selector labels",
"additionalProperties": {
"type": "string"
},
"default": {}
},
"tolerations": {
"type": "array",
"description": "Tolerations for pod scheduling",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string",
"enum": ["Exists", "Equal"]
},
"value": {
"type": "string"
},
"effect": {
"type": "string",
"enum": ["NoSchedule", "PreferNoSchedule", "NoExecute"]
}
}
},
"default": []
},
"affinity": {
"type": "object",
"description": "Affinity rules for pod scheduling",
"default": {}
}
}
}