Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add www.ietf.org k8s configuration #453

Merged
merged 22 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions k8s/ietfweb/django-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: django-config
data:
IETFWWW_ADMINS: |-
Robert Sparks <[email protected]>
Kesara Rathnayake <[email protected]>
IETFWWW_ALLOWED_HOSTS: ".ietf.org" # newline-separated list also allowed

IETFWWW_DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk" # secret


# IETFWWW_MATOMO_SITE_ID: "1" # must be present to enable Matomo
# IETFWWW_MATOMO_DOMAIN_PATH: "analytics.ietf.org"

# use this to override default - one entry per line
# IETFWWW_CSRF_TRUSTED_ORIGINS: |-
# https://www.staging.ietf.org
13 changes: 13 additions & 0 deletions k8s/ietfweb/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace: ietfwww
namePrefix: ietfwww-
configMapGenerator:
- name: files-cfgmap
files:
- local.py
- supervisord.conf
- nginx-default.conf
- nginx.conf
resources:
- django-config.yaml
- memcached.yaml
- wagtail.yaml
111 changes: 111 additions & 0 deletions k8s/ietfweb/local.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Copyright The IETF Trust 2007-2024, All Rights Reserved
# -*- coding: utf-8 -*-

from email.utils import parseaddr
import os

def _multiline_to_list(s):
"""Helper to split at newlines and conver to list"""
return [item.strip() for item in s.split("\n")]


DEFAULT_FROM_EMAIL = "[email protected]"
SERVER_EMAIL = "[email protected]"
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = os.environ.get("IETFWWW_EMAIL_HOST", "localhost")
EMAIL_PORT = int(os.environ.get("IETFWWW_EMAIL_PORT", "2025"))

# Secrets
_SECRET_KEY = os.environ.get("IETFWWW_DJANGO_SECRET_KEY", None)
if _SECRET_KEY is not None:
SECRET_KEY = _SECRET_KEY
else:
raise RuntimeError("IETFWWW_DJANGO_SECRET_KEY must be set")


_CSRF_TRUSTED_ORIGINS_STR = os.environ.get("IETFWWW_CSRF_TRUSTED_ORIGINS", None)
if _CSRF_TRUSTED_ORIGINS_STR is not None:
CSRF_TRUSTED_ORIGINS = _multiline_to_list(_CSRF_TRUSTED_ORIGINS_STR)

FILE_UPLOAD_PERMISSIONS = 0o664
_WAGTAILADMIN_BASE_URL = os.environ.get("WAGTAILADMIN_BASE_URL", None)
kesara marked this conversation as resolved.
Show resolved Hide resolved
if _WAGTAILADMIN_BASE_URL is not None:
WAGTAILADMIN_BASE_URL = _WAGTAILADMIN_BASE_URL
else:
raise RuntimeError("WAGTAILADMIN_BASE_URL must be present")

# Set DEBUG if IETFWWW_DEBUG env var is the word "true"
DEBUG = os.environ.get("IETFWWW_DEBUG", "false").lower() == "true"

# IETFWWW_ALLOWED_HOSTS env var is a comma-separated list of allowed hosts
_ALLOWED_HOSTS_STR = os.environ.get("IETFWWW_ALLOWED_HOSTS", None)
if _ALLOWED_HOSTS_STR is not None:
ALLOWED_HOSTS = _multiline_to_list(_ALLOWED_HOSTS_STR)

DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"HOST": os.environ.get("IETFWWW_DB_HOST", "db"),
"PORT": os.environ.get("IETFWWW_DB_PORT", "5432"),
"NAME": os.environ.get("IETFWWW_DB_NAME", "ietfweb"),
"USER": os.environ.get("IETFWWW_DB_USER", "django"),
"PASSWORD": os.environ.get("IETFWWW_DB_PASS", ""),
"CONN_MAX_AGE": 600, # number of seconds database connections should persist for
},
}

# IETFWWW_ADMINS is a newline-delimited list of addresses parseable by email.utils.parseaddr
_admins_str = os.environ.get("IETFWWW_ADMINS", None)
if _admins_str is not None:
ADMINS = [parseaddr(admin) for admin in _multiline_to_list(_admins_str)]
else:
raise RuntimeError("IETFWWW_ADMINS must be set")

# Leave IETFWWW_MATOMO_SITE_ID unset to disable Matomo reporting
if "IETFWWW_MATOMO_SITE_ID" in os.environ:
MATOMO_DOMAIN_PATH = os.environ.get("IETFWWW_MATOMO_DOMAIN_PATH", "analytics.ietf.org")
MATOMO_SITE_ID = os.environ.get("IETFWWW_MATOMO_SITE_ID", None)
MATOMO_DISABLE_COOKIES = True

# Duplicating production cache from settings.py and using it whether we're in production mode or not
MEMCACHED_HOST = os.environ.get("IETFWWW_MEMCACHED_SERVICE_HOST", "127.0.0.1")
MEMCACHED_PORT = os.environ.get("IETFWWW_MEMCACHED_SERVICE_PORT", "11211")
MEMCACHED_KEY_PREFIX = "ietf"
kesara marked this conversation as resolved.
Show resolved Hide resolved
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
"LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}",
"KEY_PREFIX": MEMCACHED_KEY_PREFIX,
},
"sessions": {
"BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
"LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}",
"KEY_PREFIX": MEMCACHED_KEY_PREFIX,
},
"dummy": {"BACKEND": "django.core.cache.backends.dummy.DummyCache"},
}

# Logging

LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"mail_admins": {
"level": "ERROR",
"class": "django.utils.log.AdminEmailHandler",
},
},
"loggers": {
"django.request": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": False,
},
"django.security": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": False,
},
},
}
kesara marked this conversation as resolved.
Show resolved Hide resolved
74 changes: 74 additions & 0 deletions k8s/ietfweb/memcached.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: memcached
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app: memcached
template:
metadata:
labels:
app: memcached
spec:
securityContext:
runAsNonRoot: true
containers:
- image: "quay.io/prometheus/memcached-exporter:v0.14.3"
imagePullPolicy: IfNotPresent
name: memcached-exporter
ports:
- name: metrics
containerPort: 9150
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsUser: 65534 # nobody
runAsGroup: 65534 # nobody
- image: "memcached:1.6-alpine"
imagePullPolicy: IfNotPresent
args: ["-m", "1024"]
name: memcached
ports:
- name: memcached
containerPort: 11211
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
# memcached image sets up uid/gid 11211
runAsUser: 11211
runAsGroup: 11211
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: memcached
annotations:
k8s.grafana.com/scrape: "true" # this is not a bool
k8s.grafana.com/metrics.portName: "metrics"
spec:
type: ClusterIP
ports:
- port: 11211
targetPort: memcached
protocol: TCP
name: memcached
- port: 9150
targetPort: metrics
protocol: TCP
name: metrics
selector:
app: memcached
119 changes: 119 additions & 0 deletions k8s/ietfweb/nginx-default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
server {
listen 8080 default_server;
listen [::]:8080 default_server;
kesara marked this conversation as resolved.
Show resolved Hide resolved
server_name _;
gzip on;
access_log /dev/stdout;
error_log /dev/stdout warn;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $${keepempty}host;
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
}
location /media/ {
alias /app/media/;

error_page 404 = @error_redirect;
}
location /static/ {
alias /app/static/;

error_page 404 = @error_redirect;
}
location /charter {
alias /a/ietfdata/doc/charter/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location /cr {
alias /a/ietfdata/doc/conflict-review/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location /slides {
alias /a/ietfdata/doc/slides/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location /archive/id {
alias /a/ietfdata/draft/archive/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location /id {
alias /a/ietfdata/draft/repository;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location /ietf-ftp {
alias /a/www/ietf-ftp;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location /rfc {
alias /a/www/ietf-ftp/rfc;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location ~* \.xml$ {
add_header Content-Disposition 'attachment';
}

error_page 404 = @error_redirect;
}
location @error_redirect {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $${keepempty}host;
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
}
}
53 changes: 53 additions & 0 deletions k8s/ietfweb/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
worker_processes auto;
pid /var/lib/nginx/nginx.pid;
error_log /dev/stdout;
include /etc/nginx/modules-enabled/*.conf;

events {
worker_connections 768;
# multi_accept on;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;

# server_names_hash_bucket_size 64;
# server_name_in_redirect off;

include /etc/nginx/mime.types;
default_type application/octet-stream;

##
# SSL Settings
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

##
# Logging Settings
##

access_log /dev/stdout;

##
# Gzip Settings
##

gzip on;

##
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
kesara marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading