diff --git a/wb/Chart.yaml b/wb/Chart.yaml index 42fb1255..6e97463a 100644 --- a/wb/Chart.yaml +++ b/wb/Chart.yaml @@ -1,7 +1,8 @@ -apiVersion: v1 -description: WaterButler is a Python web application for interacting with various file storage services via a single RESTful API +apiVersion: v2 name: wb -version: 0.9.1 +description: WaterButler is a Python web application for interacting with various file storage services via a single RESTful API +type: application +version: 1.0.0 keywords: - files - storage @@ -18,5 +19,18 @@ maintainers: - name: Uditi Mehta email: uditi@cos.io url: https://github.com/uditijmehta -engine: gotpl -tillerVersion: '>=2.7.0' +dependencies: + - name: cos-common + version: 1.0.0 + repository: https://centerforopenscience.github.io/helm-charts/ + # - name: cos-common + # version: 1.0.0 + # repository: "file://../cos-common" + - name: maintenance + version: 0.2.0 + repository: https://centerforopenscience.github.io/helm-charts/ + condition: maintenance.enabled, global.maintenance.enabled + - name: redis + version: 1.1.3 + repository: https://centerforopenscience.github.io/helm-charts/ + condition: redis.enabled, global.redis.enabled diff --git a/wb/files/nginx.conf b/wb/files/nginx.conf new file mode 100644 index 00000000..400a9126 --- /dev/null +++ b/wb/files/nginx.conf @@ -0,0 +1,113 @@ +user nginx; +worker_processes {{ .Values.nginx.workerCount }}; + +load_module /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so; +{{- if .Values.nginx.vts.enabled }} +load_module /usr/lib/nginx/modules/ngx_http_geoip_module.so; +load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so; +{{- end }} + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $upstream_cache_status $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"'; + access_log /var/log/nginx/access.log main; + + real_ip_header {{ .Values.nginx.realIpHeader }}; + real_ip_recursive {{ .Values.nginx.realIpRecursive }}; + {{- range .Values.nginx.proxySourceRanges }} + set_real_ip_from {{ . }}; + {{- end }} + + {{- if .Values.nginx.vts.enabled }} + geoip_country /etc/nginx/GeoIP.dat; + geoip_city /etc/nginx/GeoLiteCity.dat; + geoip_proxy_recursive on; + {{- range .Values.nginx.proxySourceRanges }} + geoip_proxy {{ . }}; + {{- end }} + + vhost_traffic_status_zone shared:vhost_traffic_status:{{ .Values.nginx.vts.statusZoneSize }}; + vhost_traffic_status_filter_by_set_key {{ .Values.nginx.vts.defaultFilterKey }}; + {{- end }} + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 620s; + keepalive_requests 10000; + types_hash_max_size 2048; + server_tokens off; + + gzip on; + gzip_proxied any; + gzip_disable "msie6"; + gzip_min_length 1400; + gzip_vary off; + gzip_buffers 4 32k; + gzip_types text/plain text/css image/svg+xml application/javascript application/x-javascript text/xml text/javascript application/json application/vnd.api+json; + + brotli on; + brotli_types text/plain text/css image/svg+xml application/javascript application/x-javascript text/xml text/javascript application/json application/vnd.api+json; + + {{- if .Values.nginx.vts.enabled }} + server { + listen {{ .Values.nginx.vts.internalPort }}; + server_name _; + + location /healthz { + access_log off; + return 200; + } + + location /nginx_status { + vhost_traffic_status_display; + vhost_traffic_status_display_format html; + } + } + {{- end }} + + server { + listen {{ .Values.main.http.containers.nginx.internalPort }}; + keepalive_timeout 620s; + client_max_body_size 9999m; + server_name _; + + if ($http_x_forwarded_proto = "http") { + return 301 https://$host$request_uri; + } + + location = /healthz { + access_log off; + return 200; + } + + location = /robots.txt { + alias /usr/share/nginx/html/robots.txt; + } + + location / { + add_header Cache-Control "no-cache, no-store, max-age=0, must-revalidate"; + add_header Expires "-1"; + add_header Pragma "no-cache"; + + proxy_buffering off; + proxy_request_buffering off; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout {{ .Values.nginx.readTimeout }}s; + proxy_pass http://127.0.0.1:{{ .Values.main.http.containers.nginx.externalPort }}; + } + } +} diff --git a/wb/requirements.lock b/wb/requirements.lock deleted file mode 100644 index d7a399e5..00000000 --- a/wb/requirements.lock +++ /dev/null @@ -1,9 +0,0 @@ -dependencies: -- name: maintenance - repository: https://centerforopenscience.github.io/helm-charts/ - version: 0.2.0 -- name: redis - repository: https://centerforopenscience.github.io/helm-charts/ - version: 1.1.3 -digest: sha256:252b9835080950ac504357281f207b11ac4d401e5962f451548c38e38d0a8b8d -generated: 2023-01-24T17:11:53.481645-05:00 diff --git a/wb/requirements.yaml b/wb/requirements.yaml deleted file mode 100644 index f49b5137..00000000 --- a/wb/requirements.yaml +++ /dev/null @@ -1,9 +0,0 @@ -dependencies: - - name: maintenance - version: 0.2.0 - repository: https://centerforopenscience.github.io/helm-charts/ - condition: maintenance.enabled, global.maintenance.enabled - - name: redis - version: 1.1.3 - repository: https://centerforopenscience.github.io/helm-charts/ - condition: redis.enabled, global.redis.enabled diff --git a/wb/templates/NOTES.txt b/wb/templates/NOTES.txt index 0a142d6e..17a43b24 100644 --- a/wb/templates/NOTES.txt +++ b/wb/templates/NOTES.txt @@ -1,17 +1,23 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.hostname }} - http://{{- .Values.ingress.hostname }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "wb.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get svc -w {{ template "wb.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "wb.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.service.externalPort }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "wb.fullname" . }}" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} +{{- $fullname := include "cos-common.fullname" (dict "root" . "name" "") | trim -}} +{{- $service := .Values.main.service -}} +{{- $externalPort := .Values.main.http.containers.nginx.externalPort -}} +{{- $internalPort := .Values.main.http.containers.nginx.internalPort -}} + +1. Main service: {{ $fullname }} +{{- if and $service (eq $service.enabled true) }} +{{- if contains "LoadBalancer" $service.type }} + Wait for the external IP, then: + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ $fullname }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ $externalPort }} +{{- else if contains "NodePort" $service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ $fullname }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "cos-common.chartName" (dict "root" .) }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:{{ $internalPort }} +{{- end }} +{{- else }} + Service disabled. {{- end }} diff --git a/wb/templates/_helpers.tpl b/wb/templates/_helpers.tpl deleted file mode 100644 index 833fc222..00000000 --- a/wb/templates/_helpers.tpl +++ /dev/null @@ -1,102 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "wb.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "wb.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified certificate name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "wb.certificate.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s-%s" .Release.Name $name .Values.certificate.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified maintenance name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "maintenance.fullname" -}} -{{- $name := "maintenance" -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified rabbitmq name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "rabbitmq.fullname" -}} -{{- $name := "rabbitmq" -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Overridable deployment annotations -*/}} -{{- define "wb.deploymentAnnotations" -}} -checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} -checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} -{{- end -}} - -{{/* -Create a default fully qualified redis name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "redis.fullname" -}} -{{- $name := "redis" -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{- define "redis.service" -}} -{{- $name := "redis" -}} -{{- printf "%s-%s.%s.%s" .Release.Name $name .Release.Namespace "svc.cluster.local" -}} -{{- end -}} - -{{- $rateLimitingEnabled := .Values.rateLimiting.enabled -}} - -{{- define "wb.environment" -}} -{{- if .Values.rateLimiting.enabled }} -- name: SERVER_CONFIG_ENABLE_RATE_LIMITING - value: "1" -{{- end }} -{{- if .Values.redis.enabled }} -- name: SERVER_CONFIG_REDIS_HOST - value: {{ template "redis.service" . }} -- name: SERVER_CONFIG_REDIS_PORT - value: {{ .Values.redis.service.port | quote }} -{{- if hasKey .Values.redis.secretEnvs "REDIS_PASSWORD" }} -- name: SERVER_CONFIG_REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "redis.fullname" . }} - key: REDIS_PASSWORD -{{- end }} -{{- end }} -{{- $fullname := include "wb.fullname" . -}} -{{- range $key, $value := .Values.configEnvs }} -- name: {{ $key }} - valueFrom: - configMapKeyRef: - name: {{ $fullname }} - key: {{ $key }} -{{- end }} -{{- range $key, $value := .Values.secretEnvs }} -- name: {{ $key }} - valueFrom: - secretKeyRef: - name: {{ $fullname }} - key: {{ $key }} -{{- end }} -{{- end -}} diff --git a/wb/templates/certificate-networkpolicy.yaml b/wb/templates/certificate-networkpolicy.yaml deleted file mode 100644 index 8b10d622..00000000 --- a/wb/templates/certificate-networkpolicy.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if (and .Values.networkPolicy.enabled .Values.certificate.enabled) }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: "{{ template "wb.certificate.fullname" . }}" - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - component: "{{ .Values.certificate.name }}" - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - policyTypes: - - Ingress - podSelector: - matchExpressions: - - {key: acme.cert-manager.io/http01-solver, operator: Exists} - ingress: - - from: [] -{{- end }} diff --git a/wb/templates/certificate.yaml b/wb/templates/certificate.yaml deleted file mode 100644 index 4f216f3b..00000000 --- a/wb/templates/certificate.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if and .Values.certificate.enabled .Values.certificate.createCert -}} -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: "{{ template "wb.certificate.fullname" . }}" - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - component: "{{ .Values.certificate.name }}" - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - secretName: "{{ template "wb.certificate.fullname" . }}" - issuerRef: - name: {{ .Values.certificate.issuerRef.name }} - kind: {{ .Values.certificate.issuerRef.kind }} - commonName: {{ .Values.certificate.commonName }} - dnsNames: - {{- range .Values.certificate.dnsNames }} - - {{ . }} - {{- end }} - acme: - config: - - http01: - {{- if hasKey .Values.certificate.acmeConfig.http01 "ingress" }} - ingress: {{ .Values.certificate.acmeConfig.http01.ingress }} - {{- else }} - ingress: {{ template "wb.fullname" . }} - {{- end }} - domains: - {{- range .Values.certificate.acmeConfig.domains }} - - {{ . }} - {{- end }} -{{- end -}} diff --git a/wb/templates/configmap.yaml b/wb/templates/configmap.yaml deleted file mode 100644 index 05bd63b5..00000000 --- a/wb/templates/configmap.yaml +++ /dev/null @@ -1,134 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -data: -{{- define "wb.inlineconfigs" }} -nginx.conf: |- - user nginx; - worker_processes {{ .Values.nginx.workerCount }}; - - load_module /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so; - {{- if .Values.nginx.vts.enabled }} - load_module /usr/lib/nginx/modules/ngx_http_geoip_module.so; - load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so; - {{- end }} - - error_log /var/log/nginx/error.log warn; - pid /var/run/nginx.pid; - - events { - worker_connections 1024; - } - - http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $upstream_cache_status $remote_user [$time_local] ' - '"$request" $status $body_bytes_sent ' - '"$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' - 'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"'; - access_log /var/log/nginx/access.log main; - - real_ip_header {{ .Values.nginx.realIpHeader }}; - real_ip_recursive {{ .Values.nginx.realIpRecursive }}; - {{- range .Values.nginx.proxySourceRanges }} - set_real_ip_from {{ . }}; - {{- end }} - - {{- if .Values.nginx.vts.enabled }} - geoip_country /etc/nginx/GeoIP.dat; - geoip_city /etc/nginx/GeoLiteCity.dat; - geoip_proxy_recursive on; - {{- range .Values.nginx.proxySourceRanges }} - geoip_proxy {{ . }}; - {{- end }} - - vhost_traffic_status_zone shared:vhost_traffic_status:{{ .Values.nginx.vts.statusZoneSize }}; - vhost_traffic_status_filter_by_set_key {{ .Values.nginx.vts.defaultFilterKey }}; - {{- end }} - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 620s; - keepalive_requests 10000; - types_hash_max_size 2048; - server_tokens off; - - gzip on; - gzip_proxied any; - gzip_disable "msie6"; - gzip_min_length 1400; - gzip_vary off; # Needs to be off because some files will not render properly when it's on (sets the Accept header) - gzip_buffers 4 32k; - gzip_types text/plain text/css image/svg+xml application/javascript application/x-javascript text/xml text/javascript application/json application/vnd.api+json; - - brotli on; - brotli_types text/plain text/css image/svg+xml application/javascript application/x-javascript text/xml text/javascript application/json application/vnd.api+json; - - {{- if .Values.nginx.vts.enabled }} - server { - listen {{ .Values.nginx.vts.internalPort }}; - server_name _; - - location /healthz { - access_log off; - return 200; - } - - location /nginx_status { - vhost_traffic_status_display; - vhost_traffic_status_display_format html; - } - } - {{- end }} - - server { - listen {{ .Values.service.internalPort }}; - keepalive_timeout 620s; - client_max_body_size 9999m; - server_name _; - - if ($http_x_forwarded_proto = "http") { - return 301 https://$host$request_uri; - } - - location = /healthz { - access_log off; - return 200; - } - - location = /robots.txt { - alias /usr/share/nginx/html/robots.txt; - } - - location / { - # Disable caching of application requests - add_header Cache-Control "no-cache, no-store, max-age=0, must-revalidate"; - add_header Expires "-1"; - add_header Pragma "no-cache"; - - proxy_buffering off; - proxy_request_buffering off; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout {{ .Values.nginx.readTimeout }}s; - proxy_pass http://127.0.0.1:{{ .Values.service.externalPort }}; - } - } - } -{{- end -}} - {{- range $key, $value := .Values.configEnvs }} - {{ $key }}: {{ $value | quote }} - {{- end }} - {{- range $key, $value := merge .Values.configFiles (include "wb.inlineconfigs" . | fromYaml) ((.Files.Glob "files/*").AsConfig | fromYaml) }} - {{ $key }}: |- - {{- $value | nindent 4 }} - {{- end }} diff --git a/wb/templates/deployment.yaml b/wb/templates/deployment.yaml deleted file mode 100644 index 675ba422..00000000 --- a/wb/templates/deployment.yaml +++ /dev/null @@ -1,245 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - selector: - matchLabels: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} - - replicas: {{ .Values.replicaCount }} - {{- if .Values.strategy }} - strategy: - {{- toYaml .Values.strategy | nindent 4 }} - {{- end }} - template: - metadata: - labels: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} - annotations: - {{- include "wb.deploymentAnnotations" . | nindent 8 }} - spec: - affinity: - {{- if .Values.additionalAffinities }} - {{- toYaml .Values.additionalAffinities | nindent 8 }} - {{- end }} - {{- if eq .Values.antiAffinity "hard" }} - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: kubernetes.io/hostname - labelSelector: - matchLabels: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} - {{- else if eq .Values.antiAffinity "soft" }} - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - podAffinityTerm: - topologyKey: kubernetes.io/hostname - labelSelector: - matchLabels: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} - {{- end }} - initContainers: - - name: chown - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: - - /bin/sh - - -c - - chown -R www-data:www-data /pickles - volumeMounts: - - name: pickles - mountPath: /pickles - containers: - - name: nginx - image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}" - imagePullPolicy: {{ .Values.nginx.image.pullPolicy }} - command: - - nginx - - -c - - /etc/nginx/nginx.conf - - -g - - daemon off; - ports: - - name: http - containerPort: {{ .Values.service.internalPort }} - readinessProbe: - httpGet: - path: /healthz - port: {{ .Values.service.internalPort }} - volumeMounts: - - name: config - subPath: nginx.conf - mountPath: /etc/nginx/nginx.conf - readOnly: true - - name: config - subPath: robots.txt - mountPath: /usr/share/nginx/html/robots.txt - readOnly: true - {{- if .Values.nginx.resources }} - resources: - {{- toYaml .Values.nginx.resources | nindent 12 }} - {{- end }} - - name: tornado - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: - - /bin/sh - - -c - - |- - set -e - PREFIX='' - if [ -f /code/newrelic.ini ]; then - PREFIX='newrelic-admin run-program' - fi - $PREFIX gosu www-data invoke server - env: - {{- include "wb.environment" . | nindent 12 }} - - name: ENV - value: kube - - name: TASKS_CONFIG_BROKER_URL - value: "amqp://{{ .Values.rabbitmq.rabbitmqUsername }}:{{ .Values.rabbitmq.rabbitmqPassword }}@127.0.0.1:{{ .Values.rabbitmq.rabbitmqNodePort }}/{{ .Values.rabbitmq.rabbitmqVhost }}" - {{- range $key, $value := .Values.tornado.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - ports: - - name: http - containerPort: {{ .Values.service.externalPort }} - readinessProbe: - httpGet: - path: /status - port: {{ .Values.service.externalPort }} - volumeMounts: - - name: secret - subPath: settings.json - mountPath: /home/.cos/waterbutler-kube.json - readOnly: true - - name: data - mountPath: /data - - name: pickles - mountPath: /pickles - {{- if .Values.tornado.volumeMounts }} - {{- toYaml .Values.tornado.volumeMounts | nindent 12 }} - {{- end }} - {{- if .Values.tornado.resources }} - resources: - {{- toYaml .Values.tornado.resources | nindent 12 }} - {{- end }} - - name: worker - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: - - /bin/sh - - -c - - |- - set -e - PREFIX='' - if [ -f /code/newrelic.ini ]; then - PREFIX='newrelic-admin run-program' - fi - $PREFIX gosu www-data celery -A waterbutler.tasks.app worker \ - -c "{{ .Values.worker.concurrency }}" -l "{{ .Values.worker.logLevel }}" \ - -n worker.%h --without-gossip - {{- if .Values.worker.maxTasksPerChild }} --max-tasks-per-child "{{ .Values.worker.maxTasksPerChild }}" {{- end }} - env: - {{- include "wb.environment" . | nindent 12 }} - - name: ENV - value: kube - - name: TASKS_CONFIG_BROKER_URL - value: "amqp://{{ .Values.rabbitmq.rabbitmqUsername }}:{{ .Values.rabbitmq.rabbitmqPassword }}@127.0.0.1:{{ .Values.rabbitmq.rabbitmqNodePort }}/{{ .Values.rabbitmq.rabbitmqVhost }}" - {{- range $key, $value := .Values.worker.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - volumeMounts: - - name: secret - subPath: settings.json - mountPath: /home/.cos/waterbutler-kube.json - readOnly: true - - name: data - mountPath: /data - - name: pickles - mountPath: /pickles - {{- if .Values.worker.volumeMounts }} - {{- toYaml .Values.worker.volumeMounts | nindent 12 }} - {{- end }} - {{- if .Values.worker.resources }} - resources: - {{- toYaml .Values.worker.resources | nindent 12 }} - {{- end }} - - name: rabbitmq - image: "{{ .Values.rabbitmq.image.repository }}:{{ .Values.rabbitmq.image.tag }}" - imagePullPolicy: {{ .Values.rabbitmq.image.pullPolicy }} - env: - - name: RABBITMQ_USERNAME - value: {{ default "" .Values.rabbitmqUsername | quote }} - - name: RABBITMQ_PASSWORD - value: {{ default "" .Values.rabbitmqPassword | quote }} - - name: RABBITMQ_NODE_PORT_NUMBER - value: {{ default "5672" .Values.rabbitmq.rabbitmqNodePort | quote }} - - name: RABBITMQ_NODE_TYPE - value: {{ default "stats" .Values.rabbitmq.rabbitmqNodeType | quote }} - - name: RABBITMQ_NODE_NAME - value: {{ printf "%s@%s" (default "rabbit" .Values.rabbitmq.rabbitmqNodeName) "localhost" | quote }} - - name: RABBITMQ_CLUSTER_NODE_NAME - value: {{ default "" .Values.rabbitmq.rabbitmqClusterNodeName | quote }} - - name: RABBITMQ_VHOST - value: {{ default "/" .Values.rabbitmq.rabbitmqVhost | quote }} - - name: RABBITMQ_MANAGER_PORT_NUMBER - value: {{ default "15672" .Values.rabbitmq.rabbitmqManagerPort | quote }} - ports: - - name: amqp - containerPort: {{ default "5672" .Values.rabbitmq.rabbitmqNodePort }} - - name: stats - containerPort: {{ default "15672" .Values.rabbitmq.rabbitmqManagerPort }} - livenessProbe: - exec: - command: - - rabbitmqctl - - status - initialDelaySeconds: 120 - timeoutSeconds: 5 - failureThreshold: 6 - readinessProbe: - exec: - command: - - rabbitmqctl - - status - initialDelaySeconds: 10 - timeoutSeconds: 3 - periodSeconds: 5 - volumeMounts: - - name: rabbitmq-data - mountPath: /bitnami/rabbitmq - {{- if .Values.rabbitmq.resources }} - resources: - {{- toYaml .Values.rabbitmq.resources | nindent 12 }} - {{- end }} - volumes: - - name: rabbitmq-data - emptyDir: {} - - name: data - emptyDir: {} - - name: pickles - emptyDir: {} - - name: config - configMap: - name: {{ template "wb.fullname" . }} - - name: secret - secret: - secretName: {{ template "wb.fullname" . }} - {{- if .Values.nodeSelector }} - nodeSelector: - {{- toYaml .Values.nodeSelector | nindent 8 }} - {{- end }} diff --git a/wb/templates/hpa.yaml b/wb/templates/hpa.yaml deleted file mode 100644 index 84e7cfcf..00000000 --- a/wb/templates/hpa.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if .Values.horizontalPodAutoscaler.enabled -}} -apiVersion: autoscaling/v1 -kind: HorizontalPodAutoscaler -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ template "wb.fullname" . }} - minReplicas: {{ .Values.replicaCount }} - maxReplicas: {{ .Values.horizontalPodAutoscaler.maxReplicas }} - targetCPUUtilizationPercentage: {{ .Values.horizontalPodAutoscaler.targetCPUUtilizationPercentage }} -{{- end -}} diff --git a/wb/templates/ingress.yaml b/wb/templates/ingress.yaml deleted file mode 100644 index 812f01c1..00000000 --- a/wb/templates/ingress.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $serviceName := include "wb.fullname" . -}} -{{- $servicePort := .Values.service.externalPort -}} -{{- $ingressPaths := .Values.ingress.paths -}} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - annotations: - {{- range $key, $value := .Values.ingress.annotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - rules: - {{- if .Values.maintenance.enabled }} - {{- $serviceName := include "maintenance.fullname" . -}} - {{- $servicePort := .Values.maintenance.service.externalPort -}} - {{- range .Values.ingress.hosts }} - - host: {{ . }} - http: - paths: - {{- range $ingressPaths }} - - path: {{ . }} - pathType: ImplementationSpecific - backend: - service: - name: {{ $serviceName }} - port: - number: {{ $servicePort }} - {{- end -}} - {{- end -}} - {{- else -}} - {{- $serviceName := include "wb.fullname" . -}} - {{- $servicePort := .Values.service.externalPort -}} - {{- range .Values.ingress.hosts }} - - host: {{ . }} - http: - paths: - {{- range $ingressPaths }} - - path: {{ . }} - pathType: ImplementationSpecific - backend: - service: - name: {{ $serviceName }} - port: - number: {{ $servicePort }} - {{- end -}} - {{- end -}} - {{- end -}} - {{- if (or .Values.ingress.tls (and .Values.certificate.enabled .Values.certificate.tls)) }} - tls: - {{- if .Values.ingress.tls }} - {{- toYaml .Values.ingress.tls | nindent 4 }} - {{- end -}} - {{- if (and .Values.certificate.enabled .Values.certificate.tls) }} - - secretName: "{{ template "wb.certificate.fullname" . }}" - hosts: - {{- range .Values.certificate.acmeConfig.domains }} - - {{ . }} - {{- end }} - {{- end -}} - {{- end -}} -{{- end -}} diff --git a/wb/templates/main.yaml b/wb/templates/main.yaml new file mode 100644 index 00000000..544451fb --- /dev/null +++ b/wb/templates/main.yaml @@ -0,0 +1,10 @@ +{{- include "cos-common.configmap" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.secret" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.deployment" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.service" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.ingress" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.hpa" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.pdb" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.networkpolicy" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.pvc" (dict "root" . "name" "" "values" .Values.main) }} +{{- include "cos-common.certificate" (dict "root" . "name" "cert" "values" .Values.main) }} diff --git a/wb/templates/networkpolicy.yaml b/wb/templates/networkpolicy.yaml deleted file mode 100644 index 7fa5b92e..00000000 --- a/wb/templates/networkpolicy.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - podSelector: - matchLabels: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} - ingress: - - ports: - - port: {{ .Values.service.internalPort }} - {{- if not .Values.networkPolicy.allowExternal }} - from: - - podSelector: - matchLabels: - {{ template "wb.fullname" . }}-client: "true" - {{- end }} - {{- if .Values.nginx.vts.enabled }} - - ports: - - port: {{ .Values.nginx.vts.internalPort }} - {{- end }} - egress: {{- toYaml .Values.networkPolicy.egress | nindent 4 }} -{{- end }} diff --git a/wb/templates/pdb.yaml b/wb/templates/pdb.yaml deleted file mode 100644 index 806b6217..00000000 --- a/wb/templates/pdb.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.budget.minAvailable -}} -{{- if .Capabilities.APIVersions.Has "policy/v1" -}} -apiVersion: policy/v1 -{{- else}} -apiVersion: policy/v1beta1 -{{- end }} -kind: PodDisruptionBudget -metadata: - name: "{{ template "wb.fullname" . }}" - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - selector: - matchLabels: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} - minAvailable: {{ .Values.budget.minAvailable }} -{{- end -}} diff --git a/wb/templates/secret.yaml b/wb/templates/secret.yaml deleted file mode 100644 index 50a2a45e..00000000 --- a/wb/templates/secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -type: Opaque -data: -{{- range $key, $value := .Values.secretEnvs }} - {{ $key }}: {{ $value | b64enc | quote }} -{{- end }} -{{- range $key, $value := .Values.secretFiles }} - {{ $key }}: {{ $value | b64enc | quote }} -{{- end }} diff --git a/wb/templates/service.yaml b/wb/templates/service.yaml deleted file mode 100644 index cd2e09c0..00000000 --- a/wb/templates/service.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "wb.fullname" . }} - labels: - app: {{ template "wb.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - type: {{ .Values.service.type }} - {{- if eq .Values.service.type "LoadBalancer" }} - {{- if .Values.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.service.loadBalancerIP | quote }} - {{- end }} - {{- if .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range .Values.service.loadBalancerSourceRanges }} - - {{ . | quote }} - {{- end }} - {{- end }} - {{- end }} - {{- if .Values.service.externalTrafficPolicy }} - externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} - {{- end }} - ports: - - port: {{ .Values.service.externalPort }} - targetPort: {{ .Values.service.internalPort }} - protocol: TCP - name: {{ .Values.service.name }} - selector: - app: {{ template "wb.name" . }} - release: {{ .Release.Name }} diff --git a/wb/values.yaml b/wb/values.yaml index 32a35e15..6a26c23d 100644 --- a/wb/values.yaml +++ b/wb/values.yaml @@ -1,40 +1,12 @@ -# Default values for wb. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. -replicaCount: 1 - +### ------- Global or reusable parts across values.yaml ------- image: repository: quay.io/centerforopenscience/waterbutler tag: develop pullPolicy: Always -antiAffinity: soft - -# strategy: -# rollingUpdate: -# maxSurge: 25% -# maxUnavailable: 25% -# type: RollingUpdate - -budget: - minAvailable: 0 - nginx: workerCount: 1 - image: - repository: quay.io/centerforopenscience/nginx - tag: latest - pullPolicy: Always - resources: {} - # limits: - # cpu: 1 - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi proxySourceRanges: [] - # - 130.211.0.0/22 - # - 35.191.0.0/16 realIpHeader: X-Real-IP realIpRecursive: "off" vts: @@ -42,311 +14,535 @@ nginx: internalPort: 18080 statusZoneSize: 10m defaultFilterKey: "$geoip_country_code country::*" - readTimeout: 60 # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout - -tornado: - resources: {} - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - volumeMounts: [] - env: {} - -worker: - concurrency: 2 - logLevel: INFO - maxTasksPerChild: 5 - resources: {} - # limits: - # cpu: 2 - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - volumeMounts: [] - env: {} - -horizontalPodAutoscaler: - enabled: false - maxReplicas: 3 - targetCPUUtilizationPercentage: 90 - -service: - name: http - type: ClusterIP - # If using type: LoadBalancer - #loadBalancerIP: 0.0.0.0 - #loadBalancerSourceRanges: - # - 0.0.0.0/0 - externalPort: 7777 - internalPort: 80 - -ingress: - enabled: false - annotations: - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - # ingress.kubernetes.io/proxy-body-size: 9999m - # nginx.org/client-max-body-size: 9999m - paths: - - / - hosts: - # - staging-files.osf.io - tls: - # - secretName: osf-io-tls - # hosts: - # - staging-files.osf.io - -certificate: - enabled: false - createCert: false - name: cert - # WORKAROUND: Ingress deploy blocked to GLBC due to race condition w/ missing TLS certificate - # - Issue: https://github.com/jetstack/cert-manager/issues/606 - # - PR: https://github.com/kubernetes/ingress-gce/pull/388 - tls: true - # issuerRef: - # name: letsencrypt-prod - # kind: ClusterIssuer - # commonName: example.org - # dnsNames: - # - example.org - # - subdomain.example.org - # acmeConfig: - # http01: {} - # # ingress: '' - # domains: - # - example.org - # - subdomain.example.org - -networkPolicy: - enabled: false - # Allows external access to the pod, otherwise access is restricted to - # clients with the explicit label. - allowExternal: true - egress: {} - # - to: - # - namespaceSelector: {} - # ports: - # - port: 53 # dns - # protocol: TCP - # - port: 53 # dns - # protocol: UDP - # - to: - # - ipBlock: - # cidr: 0.0.0.0/0 - # except: - # - 10.0.0.0/8 - # - 172.16.0.0/12 - # - 192.168.0.0/16 - # ports: - # - port: 80 # http - # protocol: TCP - # - port: 443 # https - # protocol: TCP - -configEnvs: {} - -configFiles: {} - -secretEnvs: {} - -secretFiles: - settings.json: |- - { - "ANALYTICS": { - "MFR_DOMAIN": "https://staging-mfr.osf.io", - "KEEN": { - "PRIVATE": { - "PROJECT_ID": "", - "WRITE_KEY": "" - }, - "PUBLIC": { - "PROJECT_ID": "", - "WRITE_KEY": "" - } - } - }, - "GITHUB_PROVIDER_CONFIG": { - "MOVE_MESSAGE": "Moved via the Open Science Framework", - "COPY_MESSAGE": "Copied via the Open Science Framework", - "UPLOAD_FILE_MESSAGE": "Added via the Open Science Framework", - "UPDATE_FILE_MESSAGE": "Updated via the Open Science Framework", - "DELETE_FILE_MESSAGE": "Deleted via the Open Science Framework", - "DELETE_FOLDER_MESSAGE": "Deleted via the Open Science Framework" - }, - "OSFSTORAGE_PROVIDER_CONFIG": { - "FILE_PATH_PENDING": "/data/pending", - "FILE_PATH_COMPLETE": "/data/complete", - "HMAC_SECRET": "", - "RUN_TASKS": true - }, - "SERVER_CONFIG": { - "DOMAIN": "https://staging-files.osf.io", - "ADDRESS": "0.0.0.0", - "PORT": 7777, - "DEBUG": false, - "XHEADERS": true, - "CORS_ALLOW_ORIGIN": [ - "https://staging.osf.io", - "https://staging-mfr.osf.io" - ], - "HMAC_SECRET": "", - "MAX_BUFFER_SIZE": 157286400, - "AUTH_HANDLERS": [ - "osf" - ] - }, - "OSF_AUTH_CONFIG": { - "API_URL": "https://staging.osf.io/api/v1/files/auth/", - "JWE_SALT": "", - "JWE_SECRET": "", - "JWT_SECRET": "" - }, - "TASKS_CONFIG": { - "BROKER_URL": "amqp://guest:guest@127.0.0.1:5672//", - "ADHOC_BACKEND_PATH": "/pickles" - }, - "SENTRY_DSN": "", - "LOGGING": { - "version": 1, - "disable_existing_loggers": false, - "formatters": { - "defaultFormatter": { - "()": "waterbutler.core.logging.MaskFormatter", - "format": "[%(asctime)s][%(levelname)s][%(name)s]: %(message)s", - "pattern": "(?<=cookie=)(.*?)(?=&|$)", - "mask": "***" - } - }, - "handlers": { - "consoleHandler": { - "class": "logging.StreamHandler", - "level": "INFO", - "formatter": "defaultFormatter" - } - }, - "loggers": { - "": { - "handlers": [ - "consoleHandler" - ], - "level": "INFO", - "propagate": false - } - }, - "root": { - "level": "INFO", - "handlers": [ - "consoleHandler" - ] - } - } - } - -maintenance: - enabled: false + readTimeout: 60 rabbitmq: - image: - repository: rabbitmq - tag: 3-management - pullPolicy: Always - rabbitmqUsername: guest rabbitmqPassword: guest rabbitmqNodePort: 5672 rabbitmqNodeType: stats rabbitmqNodeName: rabbit@localhost - # rabbitmqClusternodename: + rabbitmqClusterNodeName: "" rabbitmqVhost: / rabbitmqManagerPort: 15672 - resources: - requests: - memory: 256Mi - cpu: 100m - -rateLimiting: - enabled: false - redis: - enabled: true - + enabled: false image: repository: redis tag: alpine pullPolicy: IfNotPresent - secretEnvs: {} - # REDIS_PASSWORD: '' - - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - ## args: - ## - --maxmemory 200mb - ## - --maxmemory-policy volatile-ttl - args: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## + args: [] persistence: enabled: false - - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" accessMode: ReadWriteOnce size: 8Gi - - ## Configure resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## resources: {} - #limits: - # cpu: 100m - # memory: 256Mi - #requests: - # cpu: 100m - # memory: 256Mi - service: type: ClusterIP - loadBalancerIP: - #annotations: {} - # If using type: LoadBalancer - #loadBalancerIP: 0.0.0.0 - #loadBalancerSourceRanges: - # - 0.0.0.0/0 port: 6379 externalIPs: [] + networkPolicy: + enabled: false + allowExternal: true + +maintenance: + enabled: false + service: + name: -maintenance # default service name would be Release.name-Chart.name-maintenance + + +## Remember that full name for all objects is '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' +## or in other form current naming is Release.Name-Chart.Name + +## =============== MAIN Component =============== +main: + enabled: true + + replicas: 1 + + http: + containers: + nginx: + internalPort: 80 + externalPort: 7777 + serviceType: ClusterIP + + +# ------- Configuration follows for containerName: nginx ------- + image: + repository: quay.io/centerforopenscience/nginx + tag: latest + pullPolicy: Always + + containerName: nginx + + command: + - nginx + - -c + - /etc/nginx/nginx.conf + - -g + - daemon off; + + env: [] + + envFrom: [] + + probes: + readiness: + httpGet: + path: /healthz + port: "{{ .Values.main.http.containers.nginx.internalPort }}" + + ports: + - name: http + containerPort: "{{ .Values.main.http.containers.nginx.internalPort }}" + protocol: TCP + + volumeMounts: + - name: config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + readOnly: true + - name: config + mountPath: /usr/share/nginx/html/robots.txt + subPath: robots.txt + readOnly: true + + resources: {} + + +# ------- Init containers ------- + initContainers: + - name: chown + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + command: + - /bin/sh + - -c + - chown -R www-data:www-data /pickles + volumeMounts: + - name: pickles + mountPath: /pickles + + +# ------- Additional containers ------- + tornado: + volumeMounts: + - name: secret + subPath: settings.json + mountPath: /home/.cos/waterbutler-kube.json + readOnly: true + - name: data + mountPath: /data + - name: pickles + mountPath: /pickles + resources: {} + + worker: + volumeMounts: + - name: secret + subPath: settings.json + mountPath: /home/.cos/waterbutler-kube.json + readOnly: true + - name: data + mountPath: /data + - name: pickles + mountPath: /pickles + resources: {} + concurrency: 2 + logLevel: INFO + maxTasksPerChild: 5 + + rabbitmq: + image: + repository: rabbitmq + tag: 3-management + pullPolicy: Always + volumeMounts: + - name: rabbitmq-data + mountPath: /bitnami/rabbitmq + resources: + requests: + memory: 256Mi + cpu: 100m + + additionalContainers: + - name: tornado + inheritVolumeMountsFrom: tornado + inheritResourcesFrom: tornado + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + command: + - /bin/sh + - -c + - |- + set -e + PREFIX='' + if [ -f /code/newrelic.ini ]; then + PREFIX='newrelic-admin run-program' + fi + $PREFIX gosu www-data invoke server + envFrom: + - configMapRef: + name: '{{ include "cos-common.fullname" (dict "root" . "name" "common-env") | trim }}' + - secretRef: + name: '{{ include "cos-common.fullname" (dict "root" . "name" "common-env") | trim }}' + ports: + - name: http + containerPort: "{{ .Values.main.http.containers.nginx.externalPort }}" + readinessProbe: + httpGet: + path: /status + port: "{{ .Values.main.http.containers.nginx.externalPort }}" + + - name: worker + inheritVolumeMountsFrom: worker + inheritResourcesFrom: worker + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + command: + - /bin/sh + - -c + - |- + set -e + PREFIX='' + if [ -f /code/newrelic.ini ]; then + PREFIX='newrelic-admin run-program' + fi + $PREFIX gosu www-data celery -A waterbutler.tasks.app worker \ + -c "{{ .Values.main.worker.concurrency }}" -l "{{ .Values.main.worker.logLevel }}" \ + -n worker.%h --without-gossip + {{- if .Values.main.worker.maxTasksPerChild }} --maxtasksperchild "{{ .Values.main.worker.maxTasksPerChild }}" {{- end }} + envFrom: + - configMapRef: + name: '{{ include "cos-common.fullname" (dict "root" . "name" "common-env") | trim }}' + - secretRef: + name: '{{ include "cos-common.fullname" (dict "root" . "name" "common-env") | trim }}' + + - name: rabbitmq + inheritVolumeMountsFrom: rabbitmq + inheritResourcesFrom: rabbitmq + image: "{{ .Values.main.rabbitmq.image.repository }}:{{ .Values.main.rabbitmq.image.tag }}" + imagePullPolicy: "{{ .Values.main.rabbitmq.image.pullPolicy }}" + env: + - name: RABBITMQ_USERNAME + value: "{{ .Values.rabbitmq.rabbitmqUsername }}" + - name: RABBITMQ_PASSWORD + value: "{{ .Values.rabbitmq.rabbitmqPassword }}" + - name: RABBITMQ_NODE_PORT_NUMBER + value: "{{ .Values.rabbitmq.rabbitmqNodePort }}" + - name: RABBITMQ_NODE_TYPE + value: "{{ .Values.rabbitmq.rabbitmqNodeType }}" + - name: RABBITMQ_NODE_NAME + value: "{{ printf \"%s@%s\" .Values.rabbitmq.rabbitmqNodeName \"localhost\" }}" + - name: RABBITMQ_CLUSTER_NODE_NAME + value: "{{ .Values.rabbitmq.rabbitmqClusterNodeName }}" + - name: RABBITMQ_VHOST + value: "{{ .Values.rabbitmq.rabbitmqVhost }}" + - name: RABBITMQ_MANAGER_PORT_NUMBER + value: "{{ .Values.rabbitmq.rabbitmqManagerPort }}" + ports: + - name: amqp + containerPort: "{{ .Values.rabbitmq.rabbitmqNodePort }}" + - name: stats + containerPort: "{{ .Values.rabbitmq.rabbitmqManagerPort }}" + livenessProbe: + exec: + command: + - rabbitmqctl + - status + initialDelaySeconds: 120 + timeoutSeconds: 5 + failureThreshold: 6 + readinessProbe: + exec: + command: + - rabbitmqctl + - status + initialDelaySeconds: 10 + timeoutSeconds: 3 + periodSeconds: 5 + + sidecars: [] + + +# ------- Volumes configuration for the pod ------- + volumes: + - name: rabbitmq-data + emptyDir: {} + - name: data + emptyDir: {} + - name: pickles + emptyDir: {} + - name: config + configMap: + name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + - name: secret + secret: + secretName: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + + additionalVolumes: [] + + + # ------- Affinity configuration ------- + affinity: {} + + additionalAffinities: + - podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: "{{ .Chart.Name }}" + app.kubernetes.io/instance: "{{ .Release.Name }}" + app.kubernetes.io/component: "{{ .Chart.Name }}" # in this case component name = chart name, because we leave component name in main.yaml empty. + + +# ------- Pod Annotations ------- + podAnnotations: + checksum/main-config: '{{ include "cos-common.componentChecksum" (dict "root" . "name" "" "values" .Values.main "resource" "configmap") }}' + checksum/main-config-common-env: '{{ include "cos-common.componentChecksum" (dict "root" . "name" "common-env" "values" .Values.main "resource" "configmap") }}' + checksum/main-secret: '{{ include "cos-common.componentChecksum" (dict "root" . "name" "" "values" .Values.main "resource" "secret") }}' + checksum/main-secret-common-env: '{{ include "cos-common.componentChecksum" (dict "root" . "name" "common-env" "values" .Values.main "resource" "secret") }}' + + +# ------- Service configuration ------- +# service name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + service: + enabled: true + type: "{{ .Values.main.http.containers.nginx.serviceType }}" + ports: + - name: http + port: "{{ .Values.main.http.containers.nginx.externalPort }}" + targetPort: "{{ .Values.main.http.containers.nginx.internalPort }}" + + +# ------- Ingress configuration ------- +# ingress name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + ingress: + enabled: true + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + primary: + - chart-example.local + rules: + - name: main + includeForPrimaryHost: true + includeForAdditionalHost: false + pathType: ImplementationSpecific + service: + name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + port: "{{ .Values.main.http.containers.nginx.externalPort }}" + paths: + - / + tls: [] + # - secretName: secret_name + # hosts: + # - chart-example.local + + +# ------- Certificate configuration ------- (if we want to create Certificate object) +# certificate name: '{{ include "cos-common.fullname" (dict "root" . "name" "cert") | trim }}' + certificate: + enabled: false + # secretName: secret-with-cert # default secret name is certificate name + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + commonName: example.org + dnsNames: + - example.org + acmeConfig: + http01: {} + # ingress: '' + domains: + - example.org + + +# ---------- HPA configuration ---------- + hpa: + enabled: false + minReplicas: "{{ .Values.main.replicas }}" + maxReplicas: 3 + metrics: [] + behavior: {} + +# ---------- PDB configuration ---------- + pdb: + enabled: false + minAvailable: 0 + + +# ------- Network Policy configuration ------- +# Network Policy name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' networkPolicy: - ## Enable creation of NetworkPolicy resources. - ## enabled: false + ingressRules: + - ports: + - port: "{{ .Values.main.http.containers.nginx.internalPort }}" + from: + - podSelector: + matchLabels: + '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}-client': "true" + - ports: + - port: "{{ .Values.nginx.vts.internalPort }}" + egressRules: [] + + +# Additional network Policy name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + name + additionalNetworkPolicies: + - name: cert-solver + enabled: false + podSelector: + matchExpressions: + - key: acme.cert-manager.io/http01-solver + operator: Exists + ingressRules: + - from: [] + + +# ------- ConfigMap configuration ------- +# ConfigMap name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + configMap: + enabled: true + tpl: true + data: + nginx.conf: | + {{ tpl (.Files.Get "files/nginx.conf") (dict "Values" .Values "root" .) }} + robots.txt: |- + {{ .Files.Get "files/robots.txt" }} + + +# configmap name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + name + additionalConfigMaps: + - name: common-env + enabled: true + tpl: true + data: + ## Uncomment when rateLimiting enabled <---- + # SERVER_CONFIG_ENABLE_RATE_LIMITING: "1" + ENV: kube + TASKS_CONFIG_BROKER_URL: "amqp://{{ .Values.rabbitmq.rabbitmqUsername }}:{{ .Values.rabbitmq.rabbitmqPassword }}@127.0.0.1:{{ .Values.rabbitmq.rabbitmqNodePort }}/{{ .Values.rabbitmq.rabbitmqVhost }}" + ## If Redis enabled <---- + # SERVER_CONFIG_REDIS_HOST: "{{ .Release.Name }}-redis.{{ .Release.Namespace }}.svc.cluster.local }}" + # SERVER_CONFIG_REDIS_PORT: "{{ .Values.redis.service.port }}" + + +# ------- Secrets configuration ------- +# Secret name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + secret: + enabled: true + data: + settings.json: |- + { + "ANALYTICS": { + "MFR_DOMAIN": "https://staging-mfr.osf.io", + "KEEN": { + "PRIVATE": { + "PROJECT_ID": "", + "WRITE_KEY": "" + }, + "PUBLIC": { + "PROJECT_ID": "", + "WRITE_KEY": "" + } + } + }, + "GITHUB_PROVIDER_CONFIG": { + "MOVE_MESSAGE": "Moved via the Open Science Framework", + "COPY_MESSAGE": "Copied via the Open Science Framework", + "UPLOAD_FILE_MESSAGE": "Added via the Open Science Framework", + "UPDATE_FILE_MESSAGE": "Updated via the Open Science Framework", + "DELETE_FILE_MESSAGE": "Deleted via the Open Science Framework", + "DELETE_FOLDER_MESSAGE": "Deleted via the Open Science Framework" + }, + "OSFSTORAGE_PROVIDER_CONFIG": { + "FILE_PATH_PENDING": "/data/pending", + "FILE_PATH_COMPLETE": "/data/complete", + "HMAC_SECRET": "", + "RUN_TASKS": true + }, + "SERVER_CONFIG": { + "DOMAIN": "https://staging-files.osf.io", + "ADDRESS": "0.0.0.0", + "PORT": 7777, + "DEBUG": false, + "XHEADERS": true, + "CORS_ALLOW_ORIGIN": [ + "https://staging.osf.io", + "https://staging-mfr.osf.io" + ], + "HMAC_SECRET": "", + "MAX_BUFFER_SIZE": 157286400, + "AUTH_HANDLERS": [ + "osf" + ] + }, + "OSF_AUTH_CONFIG": { + "API_URL": "https://staging.osf.io/api/v1/files/auth/", + "JWE_SALT": "", + "JWE_SECRET": "", + "JWT_SECRET": "" + }, + "TASKS_CONFIG": { + "BROKER_URL": "amqp://guest:guest@127.0.0.1:5672//", + "ADHOC_BACKEND_PATH": "/pickles" + }, + "SENTRY_DSN": "", + "LOGGING": { + "version": 1, + "disable_existing_loggers": false, + "formatters": { + "defaultFormatter": { + "()": "waterbutler.core.logging.MaskFormatter", + "format": "[%(asctime)s][%(levelname)s][%(name)s]: %(message)s", + "pattern": "(?<=cookie=)(.*?)(?=&|$)", + "mask": "***" + } + }, + "handlers": { + "consoleHandler": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "defaultFormatter" + } + }, + "loggers": { + "": { + "handlers": [ + "consoleHandler" + ], + "level": "INFO", + "propagate": false + } + }, + "root": { + "level": "INFO", + "handlers": [ + "consoleHandler" + ] + } + } + } - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - allowExternal: true - +# secret name: '{{ include "cos-common.fullname" (dict "root" . "name" "") | trim }}' + name + additionalSecrets: + - name: common-env + enabled: true + includeTls: false + data: {} + # If Redis enabled <---- + # SERVER_CONFIG_REDIS_PASSWORD: superpass + + +# ------- Selectors and etc. ------- + nodeSelector: {} + tolerations: []