- Ensure prefix is passed for all services
- Add eveai-tem secret (Scaleway Transactional Email) to allow sending emails - Adapted security URLs - Certification problem in regions solved - Redis insight added to tools in k8s - Introduced new way of connection pooling for Redis - TRA-79 - intrernal server error bij registreren catalog
This commit is contained in:
71
common/utils/cache/regions.py
vendored
71
common/utils/cache/regions.py
vendored
@@ -1,63 +1,49 @@
|
||||
# common/utils/cache/regions.py
|
||||
import time
|
||||
|
||||
import redis
|
||||
from dogpile.cache import make_region
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import ssl
|
||||
|
||||
def get_redis_config(app):
|
||||
"""
|
||||
Create Redis configuration dict based on app config.
|
||||
Handles both authenticated and non-authenticated setups.
|
||||
"""
|
||||
app.logger.debug(f"Creating Redis config")
|
||||
# Parse the REDIS_BASE_URI to get all components
|
||||
redis_uri = urlparse(app.config['REDIS_BASE_URI'])
|
||||
# redis_uri = urlparse(app.config['REDIS_BASE_URI'])
|
||||
|
||||
config = {
|
||||
'host': redis_uri.hostname,
|
||||
'port': int(redis_uri.port or 6379),
|
||||
'db': 0,
|
||||
'redis_expiration_time': 3600,
|
||||
'distributed_lock': True,
|
||||
'thread_local_lock': False,
|
||||
# Built-in connection pooling parameters
|
||||
'connection_pool_class': 'redis.BlockingConnectionPool',
|
||||
'connection_pool_class_kwargs': {
|
||||
'max_connections': 20,
|
||||
'timeout': 20,
|
||||
'retry_on_timeout': True,
|
||||
'socket_connect_timeout': 5,
|
||||
'socket_timeout': 5,
|
||||
},
|
||||
|
||||
# Key prefix for namespace isolation
|
||||
'key_mangler': lambda key: f"cache:workers:{key}"
|
||||
'host': app.config['REDIS_URL'],
|
||||
'port': app.config['REDIS_PORT'],
|
||||
'max_connections': 20,
|
||||
'retry_on_timeout': True,
|
||||
'socket_keepalive': True,
|
||||
'socket_keepalive_options': {},
|
||||
}
|
||||
|
||||
# Add authentication if provided
|
||||
if redis_uri.username and redis_uri.password:
|
||||
un = app.config.get('REDIS_USER')
|
||||
pw = app.config.get('REDIS_PASS')
|
||||
if un and pw:
|
||||
config.update({
|
||||
'username': redis_uri.username,
|
||||
'password': redis_uri.password
|
||||
'username': un,
|
||||
'password': pw
|
||||
})
|
||||
|
||||
# SSL support using centralised config
|
||||
cert_path = app.config.get('REDIS_CA_CERT_PATH')
|
||||
if cert_path and redis_uri.scheme == 'rediss':
|
||||
import ssl
|
||||
# Create SSL context
|
||||
ssl_context = ssl.create_default_context()
|
||||
ssl_context.load_verify_locations(cert_path)
|
||||
ssl_context.verify_mode = ssl.CERT_REQUIRED
|
||||
ssl_context.check_hostname = app.config.get('REDIS_SSL_CHECK_HOSTNAME', True)
|
||||
redis_scheme = app.config.get('REDIS_SCHEME')
|
||||
if cert_path and redis_scheme == 'rediss':
|
||||
config.update({
|
||||
'connection_class': redis.SSLConnection,
|
||||
'ssl_cert_reqs': ssl.CERT_REQUIRED,
|
||||
'ssl_check_hostname': app.config.get('REDIS_SSL_CHECK_HOSTNAME', True),
|
||||
'ssl_ca_certs': cert_path,
|
||||
})
|
||||
|
||||
# Add SSL to connection pool kwargs (correct for redis-py)
|
||||
config['connection_pool_class_kwargs']['ssl'] = True
|
||||
config['connection_pool_class_kwargs']['ssl_cert_reqs'] = ssl.CERT_REQUIRED
|
||||
config['connection_pool_class_kwargs']['ssl_ca_certs'] = cert_path
|
||||
config['connection_pool_class_kwargs']['ssl_check_hostname'] = app.config.get('REDIS_SSL_CHECK_HOSTNAME', True)
|
||||
# Also pass explicit context (preferred when available)
|
||||
config['connection_pool_class_kwargs']['ssl_context'] = ssl_context
|
||||
app.logger.debug(f"config for Redis connection: {config}")
|
||||
|
||||
return config
|
||||
|
||||
@@ -65,13 +51,14 @@ def get_redis_config(app):
|
||||
def create_cache_regions(app):
|
||||
"""Initialise all cache regions with app config"""
|
||||
redis_config = get_redis_config(app)
|
||||
redis_pool = redis.ConnectionPool(**redis_config)
|
||||
regions = {}
|
||||
startup_time = int(time.time())
|
||||
|
||||
# Region for model-related caching (ModelVariables etc)
|
||||
model_region = make_region(name='eveai_model').configure(
|
||||
'dogpile.cache.redis',
|
||||
arguments=redis_config,
|
||||
arguments={'connection_pool': redis_pool},
|
||||
replace_existing_backend=True
|
||||
)
|
||||
regions['eveai_model'] = model_region
|
||||
@@ -79,7 +66,7 @@ def create_cache_regions(app):
|
||||
# Region for eveai_chat_workers components (Specialists, Retrievers, ...)
|
||||
eveai_chat_workers_region = make_region(name='eveai_chat_workers').configure(
|
||||
'dogpile.cache.redis',
|
||||
arguments=redis_config,
|
||||
arguments={'connection_pool': redis_pool},
|
||||
replace_existing_backend=True
|
||||
)
|
||||
regions['eveai_chat_workers'] = eveai_chat_workers_region
|
||||
@@ -87,14 +74,14 @@ def create_cache_regions(app):
|
||||
# Region for eveai_workers components (Processors, ...)
|
||||
eveai_workers_region = make_region(name='eveai_workers').configure(
|
||||
'dogpile.cache.redis',
|
||||
arguments=redis_config, # Same config for now
|
||||
arguments={'connection_pool': redis_pool}, # Same config for now
|
||||
replace_existing_backend=True
|
||||
)
|
||||
regions['eveai_workers'] = eveai_workers_region
|
||||
|
||||
eveai_config_region = make_region(name='eveai_config').configure(
|
||||
'dogpile.cache.redis',
|
||||
arguments=redis_config,
|
||||
arguments={'connection_pool': redis_pool},
|
||||
replace_existing_backend=True
|
||||
)
|
||||
regions['eveai_config'] = eveai_config_region
|
||||
|
||||
@@ -32,6 +32,7 @@ class Config(object):
|
||||
REDIS_USER = environ.get('REDIS_USER')
|
||||
REDIS_PASS = environ.get('REDIS_PASS')
|
||||
REDIS_CERT_DATA = environ.get('REDIS_CERT')
|
||||
REDIS_SCHEME = None
|
||||
|
||||
# Determine if REDIS_URL is an IP; use it to control hostname checking
|
||||
REDIS_IS_IP = False
|
||||
@@ -52,8 +53,10 @@ class Config(object):
|
||||
REDIS_CA_CERT_PATH = _tmp.name
|
||||
|
||||
if not REDIS_CERT_DATA: # We are in a simple dev/test environment
|
||||
REDIS_SCHEME = 'redis'
|
||||
REDIS_BASE_URI = f'redis://{REDIS_URL}:{REDIS_PORT}'
|
||||
else: # We are in a scaleway environment, providing name, user and certificate
|
||||
REDIS_SCHEME = 'rediss'
|
||||
REDIS_BASE_URI = f'rediss://{REDIS_USER}:{REDIS_PASS}@{REDIS_URL}:{REDIS_PORT}'
|
||||
|
||||
# Central SSL options dict for reuse (Celery/Dogpile/etc.)
|
||||
@@ -94,12 +97,8 @@ class Config(object):
|
||||
SESSION_REFRESH_EACH_REQUEST = True
|
||||
# Configure SESSION_REDIS with SSL when cert is provided
|
||||
if REDIS_CERT_DATA and REDIS_CA_CERT_PATH:
|
||||
SESSION_REDIS = redis.Redis(
|
||||
host=REDIS_URL,
|
||||
port=int(REDIS_PORT or 6379),
|
||||
username=REDIS_USER,
|
||||
password=REDIS_PASS,
|
||||
ssl=True,
|
||||
SESSION_REDIS = redis.from_url(
|
||||
f'{REDIS_BASE_URI}/0', # REDIS_BASE_URI is reeds rediss://user:pass@host:port
|
||||
ssl_cert_reqs=ssl.CERT_REQUIRED,
|
||||
ssl_ca_certs=REDIS_CA_CERT_PATH,
|
||||
ssl_check_hostname=REDIS_SSL_CHECK_HOSTNAME,
|
||||
@@ -136,7 +135,7 @@ class Config(object):
|
||||
SECURITY_CONFIRMABLE = True
|
||||
SECURITY_TRACKABLE = True
|
||||
SECURITY_PASSWORD_COMPLEXITY_CHECKER = 'zxcvbn'
|
||||
SECURITY_POST_LOGIN_VIEW = '/user/tenant_overview'
|
||||
SECURITY_POST_LOGIN_VIEW = '/admin/user/tenant_overview'
|
||||
SECURITY_RECOVERABLE = True
|
||||
SECURITY_EMAIL_SENDER = "eveai_super@flow-it.net"
|
||||
SECURITY_EMAIL_SUBJECT_PASSWORD_RESET = 'Reset Your Password'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pcupFROM registry.ask-eve-ai-local.com/josakola/eveai-base:latest
|
||||
FROM registry.ask-eve-ai-local.com/josakola/eveai-base:latest
|
||||
|
||||
# Service-specific packages (ffmpeg only needed for this service)
|
||||
USER root
|
||||
|
||||
@@ -18,13 +18,29 @@ kubectl cluster-info
|
||||
- Kubernetes cluster running
|
||||
- Managed services configured (PostgreSQL, Redis, MinIO)
|
||||
- Secrets stored in Scaleway Secret Manager:
|
||||
- `eveai-app-keys`, `eveai-mistral`, `eveai-object-storage`
|
||||
- `eveai-app-keys`, `eveai-mistral`, `eveai-object-storage`, `eveai-tem`
|
||||
- `eveai-openai`, `eveai-postgresql`, `eveai-redis`, `eveai-redis-certificate`
|
||||
- Flexible IP address (LoadBalancer)
|
||||
- Eerst een loadbalancer aanmaken met publiek IP
|
||||
- Daarna de loadbalancer verwijderen maar flexible IPs behouden
|
||||
- Dit externe IP is het IP adres dat moet worden verwerkt in ingress-values.yaml!
|
||||
|
||||
## CDN Setup (Bunny.net - Optional)
|
||||
|
||||
### Configure Pull Zone
|
||||
- Create Pull zone: evie-staging
|
||||
- Origin: https://[LoadBalancer-IP] (note HTTPS!) -> pas later in het proces gekend
|
||||
- Host header: evie-staging.askeveai.com
|
||||
- Force SSL: Enabled
|
||||
- In the pull zone's Caching - General settings, ensure to disable 'Strip Response Cookies'
|
||||
- Define edge rules for
|
||||
- Redirecting the root
|
||||
- Redirecting security urls
|
||||
|
||||
### Update DNS (eurodns) for CDN
|
||||
- Change A-record to CNAME pointing to CDN endpoint
|
||||
- Or update A-record to CDN IP
|
||||
|
||||
## New Modular Deployment Process
|
||||
|
||||
### Phase 1: Infrastructure Foundation
|
||||
@@ -230,7 +246,7 @@ kubectl create secret generic scaleway-credentials \
|
||||
|
||||
#### Stap 3: Verifieer SecretStore configuratie
|
||||
|
||||
Verifieer bestand: `scaleway/manifests/base/secrets/scaleway-secret-store.yaml`. Daar moet de juiste project ID worden ingevoerd.
|
||||
Verifieer bestand: `scaleway/manifests/base/secrets/clustersecretstore-scaleway.yaml`. Daar moet de juiste project ID worden ingevoerd.
|
||||
|
||||
#### Stap 4: Verifieer ExternalSecret resource
|
||||
|
||||
@@ -245,7 +261,7 @@ Verifieer bestand: `scaleway/manifests/base/secrets/eveai-external-secrets.yaml`
|
||||
|
||||
```bash
|
||||
# Deploy SecretStore
|
||||
kubectl apply -f scaleway/manifests/base/secrets/scaleway-secret-store.yaml
|
||||
kubectl apply -f scaleway/manifests/base/secrets/clustersecretstore-scaleway.yaml
|
||||
|
||||
# Deploy ExternalSecret
|
||||
kubectl apply -f scaleway/manifests/base/secrets/eveai-external-secrets.yaml
|
||||
@@ -281,7 +297,13 @@ metadata:
|
||||
name: eveai-app
|
||||
namespace: eveai-staging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: eveai-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: eveai-app
|
||||
spec:
|
||||
containers:
|
||||
- name: eveai-app
|
||||
@@ -296,14 +318,16 @@ spec:
|
||||
Voor SSL Redis connecties met het certificaat:
|
||||
|
||||
```python
|
||||
# In je config.py
|
||||
# Voorbeeld in je config.py
|
||||
import tempfile
|
||||
import ssl
|
||||
import redis
|
||||
from os import environ
|
||||
|
||||
class StagingConfig(Config):
|
||||
REDIS_CERT_DATA = environ.get('REDIS_CERT')
|
||||
class StagingConfig:
|
||||
def __init__(self):
|
||||
self.REDIS_CERT_DATA = environ.get('REDIS_CERT')
|
||||
self.REDIS_BASE_URI = environ.get('REDIS_BASE_URI', 'redis://localhost:6379/0')
|
||||
|
||||
def create_redis_connection(self):
|
||||
if self.REDIS_CERT_DATA:
|
||||
@@ -322,7 +346,9 @@ class StagingConfig(Config):
|
||||
return redis.from_url(self.REDIS_BASE_URI)
|
||||
|
||||
# Gebruik voor session Redis
|
||||
SESSION_REDIS = property(lambda self: self.create_redis_connection())
|
||||
@property
|
||||
def SESSION_REDIS(self):
|
||||
return self.create_redis_connection()
|
||||
```
|
||||
|
||||
#### Scaleway Secret Manager Vereisten
|
||||
@@ -389,8 +415,20 @@ kubectl -n eveai-staging describe certificate evie-staging-tls
|
||||
|
||||
Dit kan even duren. Maar zodra het certificaat is aangemaakt, kan je de de https-only ingress opzetten:
|
||||
|
||||
#### Apply per-prefix headers (moet bestaan vóór de Ingress die ernaar verwijst)
|
||||
```bash
|
||||
kubectl apply -f scaleway/manifests/base/networking/headers-configmaps.yaml
|
||||
```
|
||||
kubectl apply -f scaleway/manifests/base/networking/ingress-https.yaml
|
||||
|
||||
#### Apply ingresses
|
||||
```bash
|
||||
kubectl apply -f scaleway/manifests/base/networking/ingress-https.yaml # alleen /verify
|
||||
kubectl apply -f scaleway/manifests/base/networking/ingress-admin.yaml # /admin → eveai-app-service
|
||||
kubectl apply -f scaleway/manifests/base/networking/ingress-api.yaml # /api → eveai-api-service
|
||||
kubectl apply -f scaleway/manifests/base/networking/ingress-chat-client.yaml # /chat-client → eveai-chat-client-service
|
||||
|
||||
# Alternatief: via overlay (mits kustomization.yaml is bijgewerkt)
|
||||
kubectl apply -k scaleway/manifests/overlays/staging/
|
||||
```
|
||||
|
||||
Om bunny.net te gebruiken:
|
||||
@@ -418,6 +456,30 @@ kubectl get ingress -n eveai-staging
|
||||
kubectl get certificates -n eveai-staging
|
||||
```
|
||||
|
||||
### Verificatie commando's
|
||||
|
||||
Controleer ingresses en headers:
|
||||
|
||||
```bash
|
||||
kubectl -n eveai-staging get ing
|
||||
kubectl -n eveai-staging describe ing eveai-admin-ingress
|
||||
kubectl -n eveai-staging describe ing eveai-api-ingress
|
||||
kubectl -n eveai-staging describe ing eveai-chat-client-ingress
|
||||
kubectl -n eveai-staging describe ing eveai-staging-ingress # bevat /verify
|
||||
kubectl -n eveai-staging get cm eveai-admin-headers eveai-api-headers eveai-chat-headers -o yaml
|
||||
```
|
||||
|
||||
- In elke prefix-Ingress moeten de annotations zichtbaar zijn: use-regex: true, rewrite-target: /$2, proxy-set-headers: eveai-staging/eveai--headers.
|
||||
- In de ConfigMaps moet de key X-Forwarded-Prefix de juiste waarde hebben (/admin, /api, /chat-client).
|
||||
End-to-end testen:
|
||||
|
||||
- https://evie-staging.askeveai.com/admin/login → loginpagina. In app-logs zie je PATH zonder /admin (door rewrite) maar URL met /admin.
|
||||
- Na login: 302 Location: /admin/user/tenant_overview.
|
||||
- API: https://evie-staging.askeveai.com/api/… → backend ontvangt pad zonder /api.
|
||||
- Chat client: https://evie-staging.askeveai.com/chat-client/… → juiste service.
|
||||
- Verify: https://evie-staging.askeveai.com/verify → ongewijzigd via ingress-https.yaml.
|
||||
- Root: zolang Bunny rule niet actief is, geen automatische redirect op / (verwacht gedrag).
|
||||
|
||||
### Phase 7: Install PgAdmin Tool
|
||||
|
||||
#### Secret eveai-pgadmin-admin in Scaleway Secret Manager aanmaken (indien niet bestaat)
|
||||
@@ -464,6 +526,52 @@ kubectl -n tools port-forward svc/pgadmin-pgadmin4 8080:80
|
||||
|
||||
### Phase 8: RedisInsight Tool Deployment
|
||||
|
||||
#### Installatie via kubectl (zonder Helm)
|
||||
Gebruik een eenvoudig manifest met Deployment + Service + PVC in de `tools` namespace. Dit vermijdt externe chart repositories en extra authenticatie.
|
||||
```bash
|
||||
# Apply manifest (maakt namespace tools aan indien nodig)
|
||||
kubectl apply -f scaleway/manifests/base/tools/redisinsight/redisinsight.yaml
|
||||
|
||||
# Controleer resources
|
||||
kubectl -n tools get pods,svc,pvc
|
||||
```
|
||||
|
||||
#### (Optioneel) ExternalSecrets voor gemak (eigenlijk niet nodig)
|
||||
Indien je de Redis-credentials en CA-cert in namespace `tools` wil spiegelen (handig om het CA-bestand eenvoudig te exporteren en/of later provisioning te doen):
|
||||
```bash
|
||||
kubectl apply -f scaleway/manifests/base/tools/redisinsight/externalsecrets.yaml
|
||||
kubectl -n tools get externalsecret
|
||||
kubectl -n tools get secret | grep redisinsight
|
||||
```
|
||||
|
||||
CA-bestand lokaal opslaan voor UI-upload (alleen nodig als je ExternalSecrets gebruikte):
|
||||
```bash
|
||||
kubectl -n tools get secret redisinsight-ca -o jsonpath='{.data.REDIS_CERT}' | base64 -d > /tmp/redis-ca.pem
|
||||
```
|
||||
|
||||
#### Port Forward, Local Access
|
||||
```bash
|
||||
# RedisInsight v2 luistert op poort 5540
|
||||
kubectl -n tools port-forward svc/redisinsight 5540:5540
|
||||
# Browser: http://localhost:5540
|
||||
```
|
||||
|
||||
#### UI: Redis verbinden
|
||||
- Host: `172.16.16.2`
|
||||
- Port: `6379`
|
||||
- Auth: username `luke`, password uit secret (eveai-redis of redisinsight-redis)
|
||||
- TLS: zet TLS aan en upload het CA-certificaat (PEM)
|
||||
- Certificaatverificatie: omdat je via IP verbindt en geen hostname in het certificaat staat, kan strict verify falen. Zet dan "Verify server certificate"/"Check server identity" uit in de UI. Dit is normaal bij private networking via IP.
|
||||
|
||||
#### Troubleshooting
|
||||
- Controleer pods, service en PVC in `tools`:
|
||||
```bash
|
||||
kubectl -n tools get pods,svc,pvc
|
||||
```
|
||||
- NetworkPolicies: indien actief, laat egress toe van `tools` → `172.16.16.2:6379`.
|
||||
- TLS-issues via IP: zet verify uit of gebruik een DNS-hostnaam die met het cert overeenkomt (indien beschikbaar).
|
||||
- PVC niet bound: specificeer een geldige `storageClassName` in het manifest.
|
||||
|
||||
|
||||
### Phase 9: Application Services Deployment
|
||||
|
||||
@@ -663,21 +771,6 @@ nslookup evie-staging.askeveai.com
|
||||
curl https://evie-staging.askeveai.com/verify/
|
||||
```
|
||||
|
||||
## CDN Setup (Bunny.net - Optional)
|
||||
|
||||
### Configure Pull Zone
|
||||
- Create Pull zone: evie-staging
|
||||
- Origin: https://[LoadBalancer-IP] (note HTTPS!)
|
||||
- Host header: evie-staging.askeveai.com
|
||||
- Force SSL: Enabled
|
||||
|
||||
### Update DNS for CDN
|
||||
- Change A-record to CNAME pointing to CDN endpoint
|
||||
- Or update A-record to CDN IP
|
||||
|
||||
## Bunny.net notes
|
||||
|
||||
- In the pull zone's Caching - General settings, ensure to disable 'Strip Response Cookies'
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ def create_app(config_file=None):
|
||||
return
|
||||
|
||||
app.logger.debug(f"Before request - URL: {request.url}")
|
||||
app.logger.debug(f"Before request - PATH: {request.path}")
|
||||
app.logger.debug(f"Before request - Session permanent: {session.permanent}")
|
||||
|
||||
@app.route('/debug/session')
|
||||
|
||||
@@ -45,7 +45,7 @@ python-iso639~=2024.4.27
|
||||
python-magic~=0.4.27
|
||||
pytz~=2024.1
|
||||
PyYAML~=6.0.2
|
||||
redis~=5.0.4
|
||||
redis~=6.4.0
|
||||
requests~=2.32.3
|
||||
SQLAlchemy~=2.0.40
|
||||
tiktoken~=0.7.0
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
Routing alignment notes (staging/prod)
|
||||
|
||||
Summary
|
||||
- Root (/) issues a 301 redirect to /admin/ via server-snippet on the apps ingress.
|
||||
- Prefixes /admin, /api, /chat-client are stripped at the edge and forwarded to their backends on /. The applications do not need to be prefix-aware.
|
||||
- Root (/) redirect will be handled at Bunny (edge). No server-snippet is used in the ingress.
|
||||
- Prefixes /admin, /api, /chat-client are stripped at the ingress and forwarded to their backends on /. The applications do not need to be prefix-routed internally.
|
||||
- For consistent external URLs (especially after POST/redirect), each prefix Ingress injects X-Forwarded-Prefix via nginx.ingress.kubernetes.io/proxy-set-headers and a per-prefix ConfigMap.
|
||||
- /verify remains available (Prefix) without any rewrite in a separate Ingress.
|
||||
- No CORS annotations at ingress. Static assets are served by Bunny CDN; API CORS is not handled here.
|
||||
- /flower is intentionally NOT exposed on k8s.
|
||||
|
||||
Files
|
||||
- ingress-https.yaml: NGINX Ingress (apps) with regex paths and rewrite-target to strip prefixes; includes server-snippet to 301 redirect root to /admin/.
|
||||
- ingress-admin.yaml: Ingress for /admin with regex paths, rewrite-target to strip prefix, and proxy-set-headers pointing to eveai-admin-headers.
|
||||
- ingress-api.yaml: Ingress for /api with regex paths, rewrite-target to strip prefix, and proxy-set-headers pointing to eveai-api-headers.
|
||||
- ingress-chat-client.yaml: Ingress for /chat-client with regex paths, rewrite-target to strip prefix, and proxy-set-headers pointing to eveai-chat-headers.
|
||||
- headers-configmaps.yaml: ConfigMaps defining X-Forwarded-Prefix per ingress.
|
||||
- ingress-https.yaml: Legacy combined ingress retained for reference; server-snippet removed. Consider deprecating once split ingresses are applied.
|
||||
- ingress-verify.yaml: Separate Ingress for /verify without regex/rewrite.
|
||||
|
||||
Paths behavior
|
||||
|
||||
24
scaleway/manifests/base/networking/headers-configmaps.yaml
Normal file
24
scaleway/manifests/base/networking/headers-configmaps.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# ConfigMaps defining per-ingress proxy-set-headers
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: eveai-admin-headers
|
||||
namespace: eveai-staging
|
||||
data:
|
||||
X-Forwarded-Prefix: /admin
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: eveai-api-headers
|
||||
namespace: eveai-staging
|
||||
data:
|
||||
X-Forwarded-Prefix: /api
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: eveai-chat-headers
|
||||
namespace: eveai-staging
|
||||
data:
|
||||
X-Forwarded-Prefix: /chat-client
|
||||
36
scaleway/manifests/base/networking/ingress-admin.yaml
Normal file
36
scaleway/manifests/base/networking/ingress-admin.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Ingress for /admin prefix with X-Forwarded-Prefix header
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: eveai-admin-ingress
|
||||
namespace: eveai-staging
|
||||
labels:
|
||||
app: eveai
|
||||
environment: staging
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
|
||||
nginx.ingress.kubernetes.io/proxy-set-headers: "eveai-staging/eveai-admin-headers"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- evie-staging.askeveai.com
|
||||
secretName: evie-staging-tls
|
||||
rules:
|
||||
- host: evie-staging.askeveai.com
|
||||
http:
|
||||
paths:
|
||||
- path: /admin(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: eveai-app-service
|
||||
port:
|
||||
number: 80
|
||||
36
scaleway/manifests/base/networking/ingress-api.yaml
Normal file
36
scaleway/manifests/base/networking/ingress-api.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Ingress for /api prefix with X-Forwarded-Prefix header (optional but consistent)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: eveai-api-ingress
|
||||
namespace: eveai-staging
|
||||
labels:
|
||||
app: eveai
|
||||
environment: staging
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
|
||||
nginx.ingress.kubernetes.io/proxy-set-headers: "eveai-staging/eveai-api-headers"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- evie-staging.askeveai.com
|
||||
secretName: evie-staging-tls
|
||||
rules:
|
||||
- host: evie-staging.askeveai.com
|
||||
http:
|
||||
paths:
|
||||
- path: /api(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: eveai-api-service
|
||||
port:
|
||||
number: 80
|
||||
36
scaleway/manifests/base/networking/ingress-chat-client.yaml
Normal file
36
scaleway/manifests/base/networking/ingress-chat-client.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Ingress for /chat-client prefix with X-Forwarded-Prefix header (optional but consistent)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: eveai-chat-client-ingress
|
||||
namespace: eveai-staging
|
||||
labels:
|
||||
app: eveai
|
||||
environment: staging
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
|
||||
nginx.ingress.kubernetes.io/proxy-set-headers: "eveai-staging/eveai-chat-headers"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- evie-staging.askeveai.com
|
||||
secretName: evie-staging-tls
|
||||
rules:
|
||||
- host: evie-staging.askeveai.com
|
||||
http:
|
||||
paths:
|
||||
- path: /chat-client(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: eveai-chat-client-service
|
||||
port:
|
||||
number: 80
|
||||
@@ -16,10 +16,6 @@ metadata:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
|
||||
nginx.ingress.kubernetes.io/server-snippet: |
|
||||
location = / {
|
||||
return 301 /admin/;
|
||||
}
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
@@ -30,28 +26,12 @@ spec:
|
||||
- host: evie-staging.askeveai.com
|
||||
http:
|
||||
paths:
|
||||
# Application services (strip prefix)
|
||||
- path: /admin(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
- path: /verify
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: eveai-app-service
|
||||
port:
|
||||
number: 80
|
||||
|
||||
- path: /api(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: eveai-api-service
|
||||
port:
|
||||
number: 80
|
||||
|
||||
- path: /chat-client(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: eveai-chat-client-service
|
||||
name: verify-service
|
||||
port:
|
||||
number: 80
|
||||
# Application services (strip prefix) are now defined in dedicated ingress files
|
||||
|
||||
@@ -31,6 +31,9 @@ spec:
|
||||
# Alle keys uit eveai-object-storage secret
|
||||
- extract:
|
||||
key: name:eveai-object-storage
|
||||
# Alle keys uit eveai-tem secret
|
||||
- extract:
|
||||
key: name:eveai-tem
|
||||
data:
|
||||
# Certificaat als aparte data entry
|
||||
- secretKey: REDIS_CERT
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: redisinsight-redis
|
||||
namespace: tools
|
||||
spec:
|
||||
refreshInterval: 5m
|
||||
secretStoreRef:
|
||||
kind: ClusterSecretStore
|
||||
name: scaleway-secret-store
|
||||
target:
|
||||
name: redisinsight-redis
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: REDIS_USER
|
||||
remoteRef:
|
||||
key: eveai-redis
|
||||
property: REDIS_USER
|
||||
- secretKey: REDIS_PASS
|
||||
remoteRef:
|
||||
key: eveai-redis
|
||||
property: REDIS_PASS
|
||||
- secretKey: REDIS_URL
|
||||
remoteRef:
|
||||
key: eveai-redis
|
||||
property: REDIS_URL
|
||||
- secretKey: REDIS_PORT
|
||||
remoteRef:
|
||||
key: eveai-redis
|
||||
property: REDIS_PORT
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: redisinsight-ca
|
||||
namespace: tools
|
||||
spec:
|
||||
refreshInterval: 5m
|
||||
secretStoreRef:
|
||||
kind: ClusterSecretStore
|
||||
name: scaleway-secret-store
|
||||
target:
|
||||
name: redisinsight-ca
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: REDIS_CERT
|
||||
remoteRef:
|
||||
key: eveai-redis-certificate
|
||||
property: REDIS_CERT
|
||||
95
scaleway/manifests/base/tools/redisinsight/redisinsight.yaml
Normal file
95
scaleway/manifests/base/tools/redisinsight/redisinsight.yaml
Normal file
@@ -0,0 +1,95 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: tools
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: redisinsight-data
|
||||
namespace: tools
|
||||
labels:
|
||||
app: redisinsight
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
# storageClassName: default # uncomment and set if your cluster requires an explicit storage class
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redisinsight
|
||||
namespace: tools
|
||||
labels:
|
||||
app: redisinsight
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redisinsight
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redisinsight
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: 1001
|
||||
containers:
|
||||
- name: redisinsight
|
||||
image: redis/redisinsight:2.54.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 5540
|
||||
resources:
|
||||
requests:
|
||||
cpu: "200m"
|
||||
memory: "256Mi"
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "512Mi"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
readOnlyRootFilesystem: false
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 2
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 2
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: redisinsight-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redisinsight
|
||||
namespace: tools
|
||||
labels:
|
||||
app: redisinsight
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: redisinsight
|
||||
ports:
|
||||
- name: http
|
||||
port: 5540
|
||||
targetPort: http
|
||||
Reference in New Issue
Block a user