diff --git a/.secrets.baseline b/.secrets.baseline index dad0a32c..d9e1aac2 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2024-07-02T16:36:02Z", + "generated_at": "2024-07-12T19:26:58Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -170,7 +170,7 @@ "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", "is_secret": false, "is_verified": false, - "line_number": 85, + "line_number": 90, "type": "Secret Keyword" } ], @@ -254,7 +254,7 @@ "type": "Secret Keyword" }, { - "hashed_secret": "9d8fada0e01336e865c461bb3549084d206fe6da", + "hashed_secret": "680318f193e2ef208430b002ad07ff98a79ac457", "is_secret": false, "is_verified": false, "line_number": 200, @@ -321,7 +321,7 @@ "hashed_secret": "5d07e1b80e448a213b392049888111e1779a52db", "is_secret": false, "is_verified": false, - "line_number": 1963, + "line_number": 1992, "type": "Secret Keyword" } ], @@ -353,7 +353,7 @@ "hashed_secret": "1740c48fa3141d4851b14f97e3bc0f46f7670672", "is_secret": false, "is_verified": false, - "line_number": 122, + "line_number": 126, "type": "Secret Keyword" } ], @@ -362,7 +362,7 @@ "hashed_secret": "9b5925ea817163740dfb287a9894e8ab3aba2c18", "is_secret": false, "is_verified": false, - "line_number": 200, + "line_number": 208, "type": "Secret Keyword" } ], @@ -423,10 +423,10 @@ "type": "Secret Keyword" }, { - "hashed_secret": "1cc98556e7b1353c7bd08344f9190808b0d3d6d4", - "is_secret": true, + "hashed_secret": "44cb746036385723dde2ac36e53da8932a69bfe2", + "is_secret": false, "is_verified": false, - "line_number": 108, + "line_number": 112, "type": "Secret Keyword" } ], @@ -469,21 +469,21 @@ "hashed_secret": "cbdb7939a61698c9c866ea614399ef7eb7770c68", "is_secret": false, "is_verified": false, - "line_number": 49, + "line_number": 48, "type": "Secret Keyword" }, { "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", "is_secret": false, "is_verified": false, - "line_number": 74, + "line_number": 73, "type": "Secret Keyword" }, { "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", "is_secret": false, "is_verified": false, - "line_number": 93, + "line_number": 96, "type": "Secret Keyword" } ], @@ -499,14 +499,14 @@ "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", "is_secret": false, "is_verified": false, - "line_number": 71, + "line_number": 75, "type": "Secret Keyword" }, { - "hashed_secret": "7d4e263f1ae83868444f5327219830493a7d1486", + "hashed_secret": "489e396b7c68f95c6018f7b98ef7b1b94587ef29", "is_secret": false, "is_verified": false, - "line_number": 103, + "line_number": 114, "type": "Secret Keyword" } ], @@ -586,14 +586,14 @@ "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", "is_secret": false, "is_verified": false, - "line_number": 64, + "line_number": 63, "type": "Secret Keyword" }, { "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", "is_secret": false, "is_verified": false, - "line_number": 87, + "line_number": 90, "type": "Secret Keyword" } ], @@ -634,7 +634,7 @@ "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", "is_secret": false, "is_verified": false, - "line_number": 79, + "line_number": 83, "type": "Secret Keyword" } ], @@ -727,7 +727,7 @@ "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", "is_secret": false, "is_verified": false, - "line_number": 74, + "line_number": 78, "type": "Secret Keyword" } ], diff --git a/dev-bootstrap.sh b/dev-bootstrap.sh new file mode 100755 index 00000000..19262bf7 --- /dev/null +++ b/dev-bootstrap.sh @@ -0,0 +1,450 @@ +# install helm cli +# https://helm.sh/docs/intro/install/ +# https://helm.sh/docs/intro/quickstart/ + + +# install kubectl +function install_kubectl() { + # check if kubectl is installed + if ! command -v kubectl &> /dev/null + then + echo "kubectl could not be found" + echo "installing kubectl" + # install kubectl + # Check if uname == Darwin + if [ $(uname) = Darwin ] + then + # For AMD64 / x86_64 + [ $(uname -m) = x86_64 ] && curl -Lo ./kubectl https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/darwin/amd64/kubectl + # For ARM64 + [ $(uname -m) = aarch64 ] && curl -Lo ./kubectl https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/darwin/arm64/kubectl + chmod +x ./kubectl + sudo mv ./kubectl /usr/local/bin/kubectl + fi + + # Check if uname == Linux + if [ $(uname) = Linux ] + then + # For AMD64 / x86_64 + [ $(uname -m) = x86_64 ] && curl -Lo ./kubectl https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubectl + # For ARM64 + [ $(uname -m) = aarch64 ] && curl -Lo ./kubectl https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/arm64/kubectl + chmod +x ./kubectl + sudo mv ./kubectl /usr/local/bin/kubectl + fi + fi +} + + +# install helm cli +function install_helm() { + # check if helm is installed + if ! command -v helm &> /dev/null + then + echo "helm could not be found" + echo "installing helm" + # install helm + curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 + chmod 700 get_helm.sh + ./get_helm.sh --version v3.12.3 + fi + + # cleanup + rm -rf get_helm.sh +} + +# checkout gen3-helm repository +function checkout_gen3_helm() { + # checkout gen3-helm repository + if [ ! -d ~/.gen3/gen3-helm ]; then + echo "gen3-helm repository not found" + echo "cloning gen3-helm repository" + mkdir -p ~/.gen3 + git clone https://github.com/uc-cdis/gen3-helm.git ~/.gen3/gen3-helm + + # checkout branch called feat/GPE-979 without cd + git checkout -C ~/.gen3/gen3-helm feat/GPE-979 + git -C ~/.gen3/gen3-helm pull + fi +} + +function gen3_helm_repo() { + # add gen3-helm repo + helm repo add gen3 https://helm.gen3.org + helm repo update +} + +# install docker +function install_docker() { + # check if docker is installed + if ! command -v docker &> /dev/null + then + echo "docker could not be found" + echo "installing docker" + # install docker + curl -fsSL https://get.docker.com -o get-docker.sh + sh get-docker.sh + fi + + # cleanup + rm -rf get-docker.sh +} + +# install kind +function install_kind() { + # check if kind is installed + if ! command -v kind &> /dev/null + then + echo "kind could not be found" + echo "installing kind" + # check if mac + if [[ "$OSTYPE" == "darwin"* ]]; then + # For Intel Macs + [ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-darwin-amd64 + # For M1 / ARM Macs + [ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-darwin-arm64 + chmod +x ./kind + mv ./kind /some-dir-in-your-PATH/kind + else + # install kind + # For AMD64 / x86_64 + [ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 + # For ARM64 + [ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-arm64 + chmod +x ./kind + sudo mv ./kind /usr/local/bin/kind + fi + fi +} + +# Create kind cluster +function create_kind_cluster() { + # Check if cluster already exists + if ! kind get clusters | grep -q "kind"; then + echo "kind cluster not found" + echo "creating Kubernetes in Docker (KIND) cluster for gen3 deployment" + # create kind cluster with port 80 and 443 exposed + cat < ~/.gen3/gen3-k8s-alias +# if (( $+commands[kubectl] )); then +# __KUBECTL_COMPLETION_FILE="${ZSH_CACHE_DIR}/kubectl_completion" + +# if [[ ! -f $__KUBECTL_COMPLETION_FILE ]]; then +# kubectl completion zsh >! $__KUBECTL_COMPLETION_FILE +# fi + +# [[ -f $__KUBECTL_COMPLETION_FILE ]] && source $__KUBECTL_COMPLETION_FILE + +# unset __KUBECTL_COMPLETION_FILE +# fi + +# This command is used a LOT both below and in daily life +alias k=kubectl + +# Execute a kubectl command against all namespaces +alias kca='f(){ kubectl "$@" --all-namespaces; unset -f f; }; f' + +# Apply a YML file +alias kaf='kubectl apply -f' + +# Drop into an interactive terminal on a container +alias keti='kubectl exec -ti' + +# Manage configuration quickly to switch contexts between local, dev ad staging. +alias kcuc='kubectl config use-context' +alias kcsc='kubectl config set-context' +alias kcdc='kubectl config delete-context' +alias kccc='kubectl config current-context' + +# List all contexts +alias kcgc='kubectl config get-contexts' + +# General aliases +alias kdel='kubectl delete' +alias kdelf='kubectl delete -f' + +# Pod management. +alias kgp='kubectl get pods' +alias kgpw='kgp --watch' +alias kgpwide='kgp -o wide' +alias kep='kubectl edit pods' +alias kdp='kubectl describe pods' +alias kdelp='kubectl delete pods' + +# get pod by label: kgpl "app=myapp" -n myns +alias kgpl='kgp -l' + +# Service management. +alias kgs='kubectl get svc' +alias kgsw='kgs --watch' +alias kgswide='kgs -o wide' +alias kes='kubectl edit svc' +alias kds='kubectl describe svc' +alias kdels='kubectl delete svc' + +# Ingress management +alias kgi='kubectl get ingress' +alias kei='kubectl edit ingress' +alias kdi='kubectl describe ingress' +alias kdeli='kubectl delete ingress' + +# Namespace management +alias kgns='kubectl get namespaces' +alias kens='kubectl edit namespace' +alias kdns='kubectl describe namespace' +alias kdelns='kubectl delete namespace' +alias kcn='kubectl config set-context $(kubectl config current-context) --namespace' + +# ConfigMap management +alias kgcm='kubectl get configmaps' +alias kecm='kubectl edit configmap' +alias kdcm='kubectl describe configmap' +alias kdelcm='kubectl delete configmap' + +# Secret management +alias kgsec='kubectl get secret' +alias kdsec='kubectl describe secret' +alias kdelsec='kubectl delete secret' + +# Deployment management. +alias kgd='kubectl get deployment' +alias kgdw='kgd --watch' +alias kgdwide='kgd -o wide' +alias ked='kubectl edit deployment' +alias kdd='kubectl describe deployment' +alias kdeld='kubectl delete deployment' +alias ksd='kubectl scale deployment' +alias krsd='kubectl rollout status deployment' +kres(){ + kubectl set env $@ REFRESHED_AT=$(date +%Y%m%d%H%M%S) +} + +# Rollout management. +alias kgrs='kubectl get rs' +alias krh='kubectl rollout history' +alias kru='kubectl rollout undo' + +# Port forwarding +alias kpf="kubectl port-forward" + +# Tools for accessing all information +alias kga='kubectl get all' +alias kgaa='kubectl get all --all-namespaces' + +# Logs +alias kl='kubectl logs' +alias klf='kubectl logs -f' + +# File copy +alias kcp='kubectl cp' + +# Node Management +alias kgno='kubectl get nodes' +alias keno='kubectl edit node' +alias kdno='kubectl describe node' +alias kdelno='kubectl delete node' +EOF + source ~/.gen3/gen3-k8s-alias + + # adding to .zshrc or .bashrc whatever exists + if [ -f ~/.zshrc ]; then + # check if gen3-k8s-alias is already in .zshrc + # if not, add it + if ! grep -q "gen3-k8s-alias" ~/.zshrc; then + echo "adding gen3-k8s-alias to .zshrc" + echo "source ~/.gen3/gen3-k8s-alias" >> ~/.zshrc + fi + elif [ -f ~/.bashrc ]; then + # check if gen3-k8s-alias is already in .bashrc + # if not, add it + if ! grep -q "gen3-k8s-alias" ~/.bashrc; then + echo "adding gen3-k8s-alias to .bashrc" + echo "source ~/.gen3/gen3-k8s-alias" >> ~/.bashrc + fi + fi + +} + + +function install_k9s() { + # check if k9s is installed + if ! command -v k9s &> /dev/null + then + # install k9s + # check if brew is installed and use it to install k9s + if command -v brew &> /dev/null + then + echo "k9s could not be found" + echo "installing k9s" + brew install k9s + fi + fi +} + + +function install_ingress() { + # chekc if ingress-nginx is installed + if kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=90s > /dev/null 2>&1; then + return + fi + echo "installing ingress-nginx" + + kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml > /dev/null 2>&1 + sleep 15 + kubectl wait --namespace ingress-nginx \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/component=controller \ + --timeout=90s + echo "ingress-nginx installed" + sleep 30 +} + + + +function nuke() { + if command -v kind &> /dev/null 2>&1; + then + if kind get clusters | grep -q "kind"; then + echo "deleting kind cluster" + kind delete cluster + fi + fi + + sudo rm -rf ~/.gen3/values.yaml || true + sudo rm -rf ~/.gen3/gen3-k8s-alias || true + sudo rm -rf ~/.gen3/gen3-helm || true +} + +function install_gen3() { + # check if values file exists in ~/.gen3/values.yaml + if [ ! -f ~/.gen3/values.yaml ]; then + echo "values.yaml file not found" + echo "creating dummy values.yaml file" + echo "You should still edit this file in ~/.gen3/values.yaml to make your own changes!" + # create values.yaml file + cat < ~/.gen3/values.yaml +# values.yaml +global: + hostname: changeme.dev.planx-pla.net + dev: true + +fence: + image: + tag: master + FENCE_CONFIG: + MOCK_AUTH: "true" +EOF + fi + + # helm dependency update + echo "helm dependency update" + helm dependency update ~/.gen3/gen3-helm/helm/gen3 > /dev/null 2>&1 + kubectl delete jobs --all + helm upgrade --install gen3 ~/.gen3/gen3-helm/helm/gen3 -f ~/.gen3/values.yaml +} + +function update_hosts_file() { + hostname=$(cat ~/.gen3/values.yaml | yq -r .global.hostname) + echo $hostname + + # check if hosts file already has the hostname added + if grep -q "$hostname" /etc/hosts; then + echo "hostname already added to /etc/hosts" + return + fi + + # add hostname to /etc/hosts file and make it route to localhost + echo "adding hostname $hostname to /etc/hosts for local routing" + echo "127.0.0.1 $hostname" | sudo tee -a /etc/hosts +} + +# main function +function main() { + if [ "$1" == "-h" ]; then + echo "Usage: ./dev-bootstrap.sh [-n] [-h]" + echo "Options:" + echo " -h: help" + echo " -n: nuke everything" + echo " --hosts: Just update /etc/hosts file for your commons hostname" + return + fi + + # nuke if -n flag is passed + if [ "$1" == "-n" ]; then + nuke + return + fi + + # update hosts file only if --host flag is passed + if [ "$1" == "--hosts" ]; then + update_hosts_file + return + fi + + # accept a -y to skip the confirmation prompt + if [ "$1" == "-y" ]; then + echo "Skipping confirmation prompt" + else + # prompt user to continue + echo "This script will install (if not already installed) kubectl, helm, docker, kind, k9s, ingress-nginx, and gen3. " + echo "" + echo "It will also update your hosts file to route your commons hostname to your computer (localhost)" + echo "" + read -p "Continue? (y/n) " -n 1 -r + if [[ ! $REPLY =~ ^[Yy]$ ]] + then + echo "Exiting" + return + fi + fi + + install_kubectl + apply_k8_alias + install_helm + install_docker + install_kind + create_kind_cluster + install_k9s + checkout_gen3_helm + install_ingress + install_gen3 + update_hosts_file +} + +# run main function +main $@ + diff --git a/helm/audit/Chart.yaml b/helm/audit/Chart.yaml index 2295c602..31739d3b 100644 --- a/helm/audit/Chart.yaml +++ b/helm/audit/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.12 +version: 0.1.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -24,7 +24,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/audit/README.md b/helm/audit/README.md index 8d4ffa2c..ecae6ff6 100644 --- a/helm/audit/README.md +++ b/helm/audit/README.md @@ -1,6 +1,6 @@ # audit -![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for Kubernetes @@ -8,7 +8,7 @@ A Helm chart for Kubernetes | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -69,7 +69,12 @@ A Helm chart for Kubernetes | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | +| global.tierAccessLimit | int | `"1000"` | Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. | | image | map | `{"pullPolicy":"Always","repository":"quay.io/cdis/audit-service","tag":"master"}` | Docker image information. | | image.pullPolicy | string | `"Always"` | When to pull the image. This value should be "Always" to ensure the latest image is used. | | image.repository | string | `"quay.io/cdis/audit-service"` | The Docker image repository for the audit service | @@ -104,6 +109,13 @@ A Helm chart for Kubernetes | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Secret information for External Secrets. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | securityContext | map | `{}` | Security context for the containers in the pod | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | | server.AWS_CREDENTIALS | map | `{}` | AWS credentials to access SQS queue. | @@ -112,8 +124,8 @@ A Helm chart for Kubernetes | server.sqs | map | `{"region":"us-east-1","url":"http://sqs.com"}` | AWS SQS queue information. | | server.sqs.region | string | `"us-east-1"` | SQS queue AWS region. | | server.sqs.url | string | `"http://sqs.com"` | The URL for the SQS queue. | -| service | map | `{"port":80,"type":"ClusterIP"}` | Configuration for the service | -| service.port | int | `80` | Port on which the service is exposed | +| service | map | `{"port":[],"type":"ClusterIP"}` | Configuration for the service | +| service.port | list | `[]` | Port on which the service is exposed | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAccount | map | `{"annotations":{"eks.amazonaws.com/role-arn":null},"create":true,"name":"audit-service-sa"}` | Service account to use or create. | | serviceAccount.annotations."eks.amazonaws.com/role-arn" | string | `nil` | The Amazon Resource Name (ARN) of the role to associate with the service account | diff --git a/helm/audit/templates/deployment.yaml b/helm/audit/templates/deployment.yaml index 6d4db6f6..c7078e5f 100644 --- a/helm/audit/templates/deployment.yaml +++ b/helm/audit/templates/deployment.yaml @@ -26,33 +26,63 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} serviceAccountName: {{ include "audit.serviceAccountName" . }} volumes: - name: config-volume secret: secretName: "audit-g3auto" + - name: wsgi-config + configMap: + name: audit-wsgi + - name: nginx-config + configMap: + name: audit-nginx-configmap {{- with .Values.volumes }} {{- toYaml . | nindent 8 }} {{- end }} containers: - name: audit + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/audit-service:feat_GPE-1113" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - - containerPort: 80 - name: http - protocol: TCP + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} + - name: http + containerPort: 80 + protocol: TCP + {{- end }} livenessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} env: @@ -95,12 +125,37 @@ spec: readOnly: true mountPath: "/src/audit-service-config.yaml" subPath: "audit-service-config.yaml" + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/audit-service/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} {{- with .Values.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} initContainers: - name: audit-init + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/audit-service:feat_GPE-1113" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: DB_HOST @@ -136,10 +191,17 @@ spec: resources: {{- toYaml .Values.resources | nindent 12 }} command: ["/bin/bash"] + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + args: + - "-c" + - | + alembic upgrade head + {{- else }} args: - "-c" - | /env/bin/alembic upgrade head + {{- end }} volumeMounts: - name: "config-volume" readOnly: true diff --git a/helm/audit/templates/nginx_config.yaml b/helm/audit/templates/nginx_config.yaml new file mode 100644 index 00000000..54feeb2f --- /dev/null +++ b/helm/audit/templates/nginx_config.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: audit-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/audit/templates/service.yaml b/helm/audit/templates/service.yaml index aeb8e725..279214c2 100644 --- a/helm/audit/templates/service.yaml +++ b/helm/audit/templates/service.yaml @@ -7,9 +7,16 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} + protocol: TCP selector: {{- include "audit.selectorLabels" . | nindent 4 }} diff --git a/helm/audit/templates/wsgi.yaml b/helm/audit/templates/wsgi.yaml new file mode 100644 index 00000000..f3859045 --- /dev/null +++ b/helm/audit/templates/wsgi.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: audit-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 + worker_class = "uvicorn.workers.UvicornWorker" +{{- end }} \ No newline at end of file diff --git a/helm/audit/values.yaml b/helm/audit/values.yaml index 0112fb8a..ec21bf12 100644 --- a/helm/audit/values.yaml +++ b/helm/audit/values.yaml @@ -48,6 +48,8 @@ global: publicDataSets: true # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre + # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. + tierAccessLimit: "1000" # -- (bool) Whether network policies are enabled. netPolicy: true # -- (int) Number of dispatcher jobs. @@ -64,6 +66,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -117,6 +127,21 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "master" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # -- (list) Docker image pull secrets. imagePullSecrets: [] @@ -160,8 +185,8 @@ securityContext: {} service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) Port on which the service is exposed - port: 80 + # -- (list) Port on which the service is exposed + port: [] # -- (map) Resource requests and limits for the containers in the pod resources: diff --git a/helm/common/Chart.yaml b/helm/common/Chart.yaml index 11151e9d..768bff1f 100644 --- a/helm/common/Chart.yaml +++ b/helm/common/Chart.yaml @@ -15,7 +15,7 @@ type: library # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.11 +version: 0.1.12 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/common/README.md b/helm/common/README.md index 1fe4bdf7..64833c45 100644 --- a/helm/common/README.md +++ b/helm/common/README.md @@ -1,6 +1,6 @@ # common -![Version: 0.1.11](https://img.shields.io/badge/Version-0.1.11-informational?style=flat-square) ![Type: library](https://img.shields.io/badge/Type-library-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: library](https://img.shields.io/badge/Type-library-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for provisioning databases in gen3 diff --git a/helm/common/templates/_db_setup_job.tpl b/helm/common/templates/_db_setup_job.tpl index 9ea67dbe..49f12421 100644 --- a/helm/common/templates/_db_setup_job.tpl +++ b/helm/common/templates/_db_setup_job.tpl @@ -37,6 +37,7 @@ kind: Job metadata: name: {{ .Chart.Name }}-dbcreate spec: + ttlSecondsAfterFinished: 10 template: metadata: labels: diff --git a/helm/fence/Chart.yaml b/helm/fence/Chart.yaml index b4bd4825..e145f4a4 100644 --- a/helm/fence/Chart.yaml +++ b/helm/fence/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.19 +version: 0.1.20 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -24,7 +24,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.11 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/fence/README.md b/helm/fence/README.md index cd1c7821..1eee3756 100644 --- a/helm/fence/README.md +++ b/helm/fence/README.md @@ -1,6 +1,6 @@ # fence -![Version: 0.1.19](https://img.shields.io/badge/Version-0.1.19-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.20](https://img.shields.io/badge/Version-0.1.20-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Fence @@ -8,7 +8,7 @@ A Helm chart for gen3 Fence | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.11 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -132,10 +132,14 @@ A Helm chart for gen3 Fence | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.syncFromDbgap | bool | `false` | Whether to sync data from dbGaP. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | global.tierAccessLimit | int | `"1000"` | Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. | -| image.pullPolicy | string | `"Always"` | When to pull the image. This value should be "Always" to ensure the latest image is used. | +| image.pullPolicy | string | `"IfNotPresent"` | When to pull the image. This value should be "Always" to ensure the latest image is used. | | image.repository | string | `"quay.io/cdis/fence"` | The Docker image repository for the fence service | | image.tag | string | `"master"` | Overrides the image tag whose default is the chart appVersion. | | imagePullSecrets | list | `[]` | Docker image pull secrets. | @@ -176,10 +180,17 @@ A Helm chart for gen3 Fence | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Secret information for Usersync and External Secrets. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | securityContext | map | `{}` | Security context for the containers in the pod | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":80,"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `80` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAccount | map | `{"annotations":{"eks.amazonaws.com/role-arn":null},"create":true,"name":"fence-sa"}` | Service account to use or create. | | serviceAccount.annotations | map | `{"eks.amazonaws.com/role-arn":null}` | Annotations to add to the service account. | @@ -197,6 +208,6 @@ A Helm chart for gen3 Fence | usersync.syncFromDbgap | bool | `false` | Whether to sync data from dbGaP. | | usersync.userYamlS3Path | string | `"s3://cdis-gen3-users/helm-test/user.yaml"` | Path to the user.yaml file in S3. | | usersync.usersync | bool | `true` | Whether to run Fence usersync or not. | -| volumeMounts | list | `[{"mountPath":"/var/www/fence/local_settings.py","name":"old-config-volume","readOnly":true,"subPath":"local_settings.py"},{"mountPath":"/var/www/fence/fence_credentials.json","name":"json-secret-volume","readOnly":true,"subPath":"fence_credentials.json"},{"mountPath":"/var/www/fence/creds.json","name":"creds-volume","readOnly":true,"subPath":"creds.json"},{"mountPath":"/var/www/fence/config_helper.py","name":"config-helper","readOnly":true,"subPath":"config_helper.py"},{"mountPath":"/fence/fence/static/img/logo.svg","name":"logo-volume","readOnly":true,"subPath":"logo.svg"},{"mountPath":"/fence/fence/static/privacy_policy.md","name":"privacy-policy","readOnly":true,"subPath":"privacy_policy.md"},{"mountPath":"/var/www/fence/fence-config-secret.yaml","name":"config-volume","readOnly":true,"subPath":"fence-config.yaml"},{"mountPath":"/var/www/fence/yaml_merge.py","name":"yaml-merge","readOnly":true,"subPath":"yaml_merge.py"},{"mountPath":"/var/www/fence/fence_google_app_creds_secret.json","name":"fence-google-app-creds-secret-volume","readOnly":true,"subPath":"fence_google_app_creds_secret.json"},{"mountPath":"/var/www/fence/fence_google_storage_creds_secret.json","name":"fence-google-storage-creds-secret-volume","readOnly":true,"subPath":"fence_google_storage_creds_secret.json"},{"mountPath":"/fence/keys/key/jwt_private_key.pem","name":"fence-jwt-keys","readOnly":true,"subPath":"jwt_private_key.pem"},{"mountPath":"/var/www/fence/fence-config-public.yaml","name":"config-volume-public","readOnly":true,"subPath":"fence-config-public.yaml"}]` | Volumes to mount to the container. | -| volumes | list | `[{"name":"old-config-volume","secret":{"secretName":"fence-secret"}},{"name":"json-secret-volume","secret":{"optional":true,"secretName":"fence-json-secret"}},{"name":"creds-volume","secret":{"secretName":"fence-creds"}},{"configMap":{"name":"config-helper","optional":true},"name":"config-helper"},{"configMap":{"name":"logo-config"},"name":"logo-volume"},{"name":"config-volume","secret":{"secretName":"fence-config"}},{"name":"fence-google-app-creds-secret-volume","secret":{"secretName":"fence-google-app-creds-secret"}},{"name":"fence-google-storage-creds-secret-volume","secret":{"secretName":"fence-google-storage-creds-secret"}},{"name":"fence-jwt-keys","secret":{"secretName":"fence-jwt-keys"}},{"configMap":{"name":"privacy-policy"},"name":"privacy-policy"},{"configMap":{"name":"fence-yaml-merge","optional":false},"name":"yaml-merge"},{"configMap":{"name":"manifest-fence","optional":true},"name":"config-volume-public"}]` | Volumes to attach to the container. | +| volumeMounts | list | `[{"mountPath":"/var/www/fence/local_settings.py","name":"old-config-volume","readOnly":true,"subPath":"local_settings.py"},{"mountPath":"/var/www/fence/fence_credentials.json","name":"json-secret-volume","readOnly":true,"subPath":"fence_credentials.json"},{"mountPath":"/var/www/fence/creds.json","name":"creds-volume","readOnly":true,"subPath":"creds.json"},{"mountPath":"/var/www/fence/config_helper.py","name":"config-helper","readOnly":true,"subPath":"config_helper.py"},{"mountPath":"/fence/fence/static/img/logo.svg","name":"logo-volume","readOnly":true,"subPath":"logo.svg"},{"mountPath":"/fence/fence/static/privacy_policy.md","name":"privacy-policy","readOnly":true,"subPath":"privacy_policy.md"},{"mountPath":"/var/www/fence/fence-config-secret.yaml","name":"config-volume","readOnly":true,"subPath":"fence-config.yaml"},{"mountPath":"/var/www/fence/yaml_merge.py","name":"yaml-merge","readOnly":true,"subPath":"yaml_merge.py"},{"mountPath":"/var/www/fence/fence_google_app_creds_secret.json","name":"fence-google-app-creds-secret-volume","readOnly":true,"subPath":"fence_google_app_creds_secret.json"},{"mountPath":"/var/www/fence/fence_google_storage_creds_secret.json","name":"fence-google-storage-creds-secret-volume","readOnly":true,"subPath":"fence_google_storage_creds_secret.json"},{"mountPath":"/fence/keys/key/jwt_private_key.pem","name":"fence-jwt-keys","readOnly":false,"subPath":"jwt_private_key.pem"},{"mountPath":"/var/www/fence/fence-config-public.yaml","name":"config-volume-public","readOnly":true,"subPath":"fence-config-public.yaml"}]` | Volumes to mount to the container. | +| volumes | list | `[{"name":"old-config-volume","secret":{"secretName":"fence-secret"}},{"name":"json-secret-volume","secret":{"optional":true,"secretName":"fence-json-secret"}},{"name":"creds-volume","secret":{"secretName":"fence-creds"}},{"configMap":{"name":"config-helper","optional":true},"name":"config-helper"},{"configMap":{"name":"logo-config"},"name":"logo-volume"},{"name":"config-volume","secret":{"secretName":"fence-config"}},{"name":"fence-google-app-creds-secret-volume","secret":{"secretName":"fence-google-app-creds-secret"}},{"name":"fence-google-storage-creds-secret-volume","secret":{"secretName":"fence-google-storage-creds-secret"}},{"name":"fence-jwt-keys","secret":{"secretName":"fence-jwt-keys"}},{"configMap":{"name":"privacy-policy"},"name":"privacy-policy"},{"configMap":{"name":"fence-yaml-merge","optional":false},"name":"yaml-merge"},{"configMap":{"name":"manifest-fence","optional":true},"name":"config-volume-public"},{"configMap":{"name":"fence-wsgi"},"name":"wsgi-config"},{"configMap":{"name":"fence-nginx-configmap"},"name":"nginx-config"}]` | Volumes to attach to the container. | diff --git a/helm/fence/templates/fence-deployment.yaml b/helm/fence/templates/fence-deployment.yaml index 3139a243..2cfb6fba 100644 --- a/helm/fence/templates/fence-deployment.yaml +++ b/helm/fence/templates/fence-deployment.yaml @@ -28,33 +28,54 @@ spec: spec: enableServiceLinks: false serviceAccountName: {{ include "fence.serviceAccountName" . }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} volumes: {{- toYaml .Values.volumes | nindent 8 }} containers: - name: fence + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/fence:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} ports: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} - name: http containerPort: 80 protocol: TCP - - name: https - containerPort: 443 - protocol: TCP + {{- end }} - name: container containerPort: 6567 protocol: TCP livenessProbe: httpGet: path: /_status + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} initialDelaySeconds: 60 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /_status + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} command: ["/bin/bash"] @@ -72,21 +93,48 @@ spec: {{- end }} {{- toYaml .Values.env | nindent 12 }} volumeMounts: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: wsgi-config + mountPath: "/fence/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} initContainers: - name: fence-init + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/fence:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} ports: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} - name: http containerPort: 80 protocol: TCP - - name: https - containerPort: 443 - protocol: TCP + {{- end }} - name: container containerPort: 6567 - protocol: TCP resources: {{- toYaml .Values.resources | nindent 12 }} command: ["/bin/bash"] diff --git a/helm/fence/templates/nginx-config.yaml b/helm/fence/templates/nginx-config.yaml new file mode 100644 index 00000000..3987d818 --- /dev/null +++ b/helm/fence/templates/nginx-config.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: fence-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/fence/templates/presigned-url-fence.yaml b/helm/fence/templates/presigned-url-fence.yaml index 166106a8..99bdf27f 100644 --- a/helm/fence/templates/presigned-url-fence.yaml +++ b/helm/fence/templates/presigned-url-fence.yaml @@ -21,16 +21,32 @@ spec: app: presigned-url-fence spec: serviceAccountName: {{ include "fence.serviceAccountName" . }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} volumes: {{- toYaml .Values.volumes | nindent 8 }} containers: - name: presigned-url-fence + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/fence:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: Always + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} ports: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} - name: http containerPort: 80 protocol: TCP + {{- end }} - name: https containerPort: 443 protocol: TCP @@ -40,14 +56,22 @@ spec: livenessProbe: httpGet: path: /_status + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /_status + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} command: ["/bin/bash"] @@ -62,7 +86,25 @@ spec: env: {{- toYaml .Values.env | nindent 12 }} volumeMounts: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: wsgi-config + mountPath: "/fence/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + protocol: TCP + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/fence/templates/service.yaml b/helm/fence/templates/service.yaml index e5887708..ec40c93e 100644 --- a/helm/fence/templates/service.yaml +++ b/helm/fence/templates/service.yaml @@ -7,10 +7,16 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} selector: {{- include "fence.selectorLabels" . | nindent 4 }} --- @@ -21,10 +27,16 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} selector: app: presigned-url-fence diff --git a/helm/fence/templates/useryaml-job.yaml b/helm/fence/templates/useryaml-job.yaml index 6adb96c4..83c520ba 100644 --- a/helm/fence/templates/useryaml-job.yaml +++ b/helm/fence/templates/useryaml-job.yaml @@ -27,7 +27,7 @@ spec: containers: - name: fence image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: Always + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} env: {{- toYaml .Values.env | nindent 10 }} volumeMounts: diff --git a/helm/fence/templates/wsgi.yaml b/helm/fence/templates/wsgi.yaml new file mode 100644 index 00000000..b267502c --- /dev/null +++ b/helm/fence/templates/wsgi.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: fence-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' +{{- end }} \ No newline at end of file diff --git a/helm/fence/values.yaml b/helm/fence/values.yaml index 3f8a0c69..8b99b339 100644 --- a/helm/fence/values.yaml +++ b/helm/fence/values.yaml @@ -77,6 +77,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -159,10 +167,25 @@ image: # -- (string) The Docker image repository for the fence service repository: quay.io/cdis/fence # -- (string) When to pull the image. This value should be "Always" to ensure the latest image is used. - pullPolicy: Always + pullPolicy: IfNotPresent # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "master" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # -- (list) Docker image pull secrets. imagePullSecrets: [] @@ -204,8 +227,8 @@ securityContext: {} service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: 80 + # -- (list) The port number that the service exposes. + port: [] # -- (map) Resource requests and limits for the containers in the pod resources: @@ -376,6 +399,12 @@ volumes: configMap: name: "manifest-fence" optional: true + - name: wsgi-config + configMap: + name: fence-wsgi + - name: nginx-config + configMap: + name: fence-nginx-configmap # -- (list) Volumes to mount to the container. volumeMounts: @@ -420,7 +449,7 @@ volumeMounts: mountPath: "/var/www/fence/fence_google_storage_creds_secret.json" subPath: fence_google_storage_creds_secret.json - name: "fence-jwt-keys" - readOnly: true + readOnly: false mountPath: "/fence/keys/key/jwt_private_key.pem" subPath: "jwt_private_key.pem" - name: "config-volume-public" diff --git a/helm/gen3/Chart.yaml b/helm/gen3/Chart.yaml index ccedae64..e47684c1 100644 --- a/helm/gen3/Chart.yaml +++ b/helm/gen3/Chart.yaml @@ -17,7 +17,7 @@ dependencies: repository: "file://../argo-wrapper" condition: argo-wrapper.enabled - name: audit - version: 0.1.12 + version: 0.1.13 repository: "file://../audit" condition: audit.enabled - name: aws-es-proxy @@ -25,7 +25,7 @@ dependencies: repository: "file://../aws-es-proxy" condition: aws-es-proxy.enabled - name: common - version: 0.1.11 + version: 0.1.12 repository: file://../common - name: etl version: 0.1.1 @@ -36,7 +36,7 @@ dependencies: repository: "file://../frontend-framework" condition: frontend-framework.enabled - name: fence - version: 0.1.19 + version: 0.1.20 repository: "file://../fence" condition: fence.enabled - name: guppy @@ -48,19 +48,19 @@ dependencies: repository: "file://../hatchery" condition: hatchery.enabled - name: indexd - version: 0.1.14 + version: 0.1.15 repository: "file://../indexd" condition: indexd.enabled - name: manifestservice - version: 0.1.14 + version: 0.1.15 repository: "file://../manifestservice" condition: manifestservice.enabled - name: metadata - version: 0.1.12 + version: 0.1.13 repository: "file://../metadata" condition: metadata.enabled - name: peregrine - version: 0.1.13 + version: 0.1.14 repository: "file://../peregrine" condition: peregrine.enabled - name: pidgin @@ -72,7 +72,7 @@ dependencies: repository: "file://../portal" condition: portal.enabled - name: requestor - version: 0.1.11 + version: 0.1.12 repository: "file://../requestor" condition: requestor.enabled - name: revproxy @@ -80,7 +80,7 @@ dependencies: repository: "file://../revproxy" condition: revproxy.enabled - name: sheepdog - version: 0.1.14 + version: 0.1.15 repository: "file://../sheepdog" condition: sheepdog.enabled - name: ssjdispatcher @@ -92,7 +92,7 @@ dependencies: condition: sower.enabled repository: "file://../sower" - name: wts - version: 0.1.13 + version: 0.1.14 repository: "file://../wts" condition: wts.enabled @@ -128,7 +128,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.38 +version: 0.1.39 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/gen3/README.md b/helm/gen3/README.md index fa6ed288..0e258a34 100644 --- a/helm/gen3/README.md +++ b/helm/gen3/README.md @@ -1,6 +1,6 @@ # gen3 -![Version: 0.1.38](https://img.shields.io/badge/Version-0.1.38-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.39](https://img.shields.io/badge/Version-0.1.39-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) Helm chart to deploy Gen3 Data Commons @@ -21,27 +21,27 @@ Helm chart to deploy Gen3 Data Commons | file://../ambassador | ambassador | 0.1.11 | | file://../arborist | arborist | 0.1.11 | | file://../argo-wrapper | argo-wrapper | 0.1.7 | -| file://../audit | audit | 0.1.12 | +| file://../audit | audit | 0.1.13 | | file://../aws-es-proxy | aws-es-proxy | 0.1.9 | -| file://../common | common | 0.1.11 | +| file://../common | common | 0.1.12 | | file://../etl | etl | 0.1.1 | -| file://../fence | fence | 0.1.19 | +| file://../fence | fence | 0.1.20 | | file://../frontend-framework | frontend-framework | 0.1.1 | | file://../guppy | guppy | 0.1.12 | | file://../hatchery | hatchery | 0.1.9 | -| file://../indexd | indexd | 0.1.14 | -| file://../manifestservice | manifestservice | 0.1.14 | -| file://../metadata | metadata | 0.1.12 | +| file://../indexd | indexd | 0.1.15 | +| file://../manifestservice | manifestservice | 0.1.15 | +| file://../metadata | metadata | 0.1.13 | | file://../neuvector | neuvector | 0.1.0 | -| file://../peregrine | peregrine | 0.1.13 | +| file://../peregrine | peregrine | 0.1.14 | | file://../pidgin | pidgin | 0.1.10 | | file://../portal | portal | 0.1.15 | -| file://../requestor | requestor | 0.1.11 | +| file://../requestor | requestor | 0.1.12 | | file://../revproxy | revproxy | 0.1.16 | -| file://../sheepdog | sheepdog | 0.1.14 | +| file://../sheepdog | sheepdog | 0.1.15 | | file://../sower | sower | 0.1.11 | | file://../ssjdispatcher | ssjdispatcher | 0.1.9 | -| file://../wts | wts | 0.1.13 | +| file://../wts | wts | 0.1.14 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | | https://helm.elastic.co | elasticsearch | 7.10.2 | @@ -112,6 +112,10 @@ Helm chart to deploy Gen3 Data Commons | global.postgres.master.username | string | `"postgres"` | global postgres master username | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | global.tierAccessLimit | int | `"1000"` | Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. | | guppy | map | `{"enabled":false}` | Configurations for guppy chart. | diff --git a/helm/gen3/values.yaml b/helm/gen3/values.yaml index e5f528b2..b6837952 100644 --- a/helm/gen3/values.yaml +++ b/helm/gen3/values.yaml @@ -76,6 +76,14 @@ global: deploy: false # -- (bool) Will create the databases and store the creds in Kubernetes Secrets even if externalSecrets is deployed. Useful if you want to use ExternalSecrets for other secrets besides db secrets. dbCreate: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # Dependancy Charts diff --git a/helm/indexd/Chart.yaml b/helm/indexd/Chart.yaml index 19e78126..99d51416 100644 --- a/helm/indexd/Chart.yaml +++ b/helm/indexd/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.14 +version: 0.1.15 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -26,7 +26,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/indexd/README.md b/helm/indexd/README.md index 8d7057cb..d605b015 100644 --- a/helm/indexd/README.md +++ b/helm/indexd/README.md @@ -1,6 +1,6 @@ # indexd -![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 indexd @@ -8,7 +8,7 @@ A Helm chart for gen3 indexd | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -59,6 +59,10 @@ A Helm chart for gen3 indexd | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | global.tierAccessLimit | int | `"1000"` | Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. | | image | map | `{"pullPolicy":"IfNotPresent","repository":"quay.io/cdis/indexd","tag":""}` | Docker image information. | @@ -93,10 +97,17 @@ A Helm chart for gen3 indexd | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null,"userdb":{"fence":null,"sheepdog":null}}` | Values for indexd secret. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID to access the db restore job S3 bucket. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID to access the db restore job S3 bucket. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | securityContext | map | `{}` | Security context for the containers in the pod | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":80,"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `80` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAccount | map | `{"annotations":{},"create":false,"name":""}` | Service account to use or create. | | serviceAccount.annotations | map | `{}` | Annotations to add to the service account. | @@ -105,5 +116,5 @@ A Helm chart for gen3 indexd | tolerations | list | `[]` | Tolerations for the pods | | uwsgi | map | `{"listen":1024}` | Values for overriding uwsgi settings | | volumeMounts | list | `[{"mountPath":"/var/www/indexd/local_settings.py","name":"config-volume","readOnly":true,"subPath":"local_settings.py"}]` | Volumes to mount to the container. | -| volumes | list | `[{"configMap":{"name":"indexd-uwsgi"},"name":"uwsgi-config"},{"name":"config-volume","secret":{"secretName":"indexd-settings"}}]` | Volumes to attach to the pod | +| volumes | list | `[{"configMap":{"name":"indexd-wsgi"},"name":"wsgi-config"},{"configMap":{"name":"indexd-uwsgi"},"name":"uwsgi-config"},{"configMap":{"name":"indexd-nginx-configmap"},"name":"nginx-config"},{"name":"config-volume","secret":{"secretName":"indexd-settings"}}]` | Volumes to attach to the pod | diff --git a/helm/indexd/templates/deployment.yaml b/helm/indexd/templates/deployment.yaml index 497d4f45..ec906800 100644 --- a/helm/indexd/templates/deployment.yaml +++ b/helm/indexd/templates/deployment.yaml @@ -26,6 +26,12 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} {{- with .Values.volumes }} volumes: {{- toYaml . | nindent 8 }} @@ -41,7 +47,11 @@ spec: - name: indexd securityContext: {{- toYaml .Values.securityContext | nindent 12 }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/indexd:feat_GPE-788" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- if .Values.global.ddEnabled }} @@ -81,29 +91,65 @@ spec: value: {{ .Values.defaultPrefix }} {{- toYaml .Values.env | nindent 12 }} volumeMounts: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/indexd/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- else }} - name: "uwsgi-config" mountPath: "/etc/uwsgi/uwsgi.ini" subPath: uwsgi.ini + {{- end }} - name: "config-volume" readOnly: true mountPath: "/var/www/indexd/local_settings.py" subPath: "local_settings.py" ports: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} - name: http containerPort: 80 protocol: TCP + {{- end }} livenessProbe: httpGet: path: /_status + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /_status + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/indexd/templates/nginx_config.yaml b/helm/indexd/templates/nginx_config.yaml new file mode 100644 index 00000000..57b03a13 --- /dev/null +++ b/helm/indexd/templates/nginx_config.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: indexd-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/indexd/templates/pre-install.yaml b/helm/indexd/templates/pre-install.yaml index a6f6cd9f..888d8367 100644 --- a/helm/indexd/templates/pre-install.yaml +++ b/helm/indexd/templates/pre-install.yaml @@ -9,6 +9,7 @@ metadata: name: indexd-userdb spec: backoffLimit: 0 + ttlSecondsAfterFinished: 100 template: metadata: labels: @@ -81,9 +82,18 @@ spec: - "-c" # Script always succeeds if it runs (echo exits with 0) # indexd image does not include jq, so use python + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - | + source .venv/bin/activate + echo 'python3 /indexd/bin/index_admin.py create --username "fence" --password "${FENCE_PASS}' + python3 /indexd/bin/index_admin.py create --username "fence" --password "${FENCE_PASS}" + echo 'python3 /indexd/bin/index_admin.py create --username "sheepdog" --password "${SHEEPDOG_PASS}' + python3 /indexd/bin/index_admin.py create --username "sheepdog" --password "${SHEEPDOG_PASS}" + {{- else }} - | echo 'python /indexd/bin/index_admin.py create --username "fence" --password "${FENCE_PASS}' python /indexd/bin/index_admin.py create --username "fence" --password "${FENCE_PASS}" echo 'python /indexd/bin/index_admin.py create --username "sheepdog" --password "${SHEEPDOG_PASS}' python /indexd/bin/index_admin.py create --username "sheepdog" --password "${SHEEPDOG_PASS}" + {{- end }} restartPolicy: Never \ No newline at end of file diff --git a/helm/indexd/templates/service.yaml b/helm/indexd/templates/service.yaml index 6fb671d1..98319453 100644 --- a/helm/indexd/templates/service.yaml +++ b/helm/indexd/templates/service.yaml @@ -7,9 +7,15 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} selector: {{- include "indexd.selectorLabels" . | nindent 4 }} diff --git a/helm/indexd/templates/uwsgi.yaml b/helm/indexd/templates/uwsgi.yaml index a6eef58c..17bbb55c 100644 --- a/helm/indexd/templates/uwsgi.yaml +++ b/helm/indexd/templates/uwsgi.yaml @@ -1,3 +1,4 @@ +{{- if not (or (.Values.secureImage.enabled | default .Values.global.secureImage.enabled)) }} apiVersion: v1 kind: ConfigMap metadata: @@ -40,3 +41,4 @@ data: lazy = true lazy-apps = true listen = {{ .Values.uwsgi.listen }} +{{- end }} \ No newline at end of file diff --git a/helm/indexd/templates/wsgi.yaml b/helm/indexd/templates/wsgi.yaml new file mode 100644 index 00000000..c590ec39 --- /dev/null +++ b/helm/indexd/templates/wsgi.yaml @@ -0,0 +1,14 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: indexd-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 +{{- end }} \ No newline at end of file diff --git a/helm/indexd/values.yaml b/helm/indexd/values.yaml index 8c64335d..f9e32ff8 100644 --- a/helm/indexd/values.yaml +++ b/helm/indexd/values.yaml @@ -67,6 +67,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -126,6 +134,21 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # -- (list) Docker image pull secrets. imagePullSecrets: [] @@ -165,8 +188,8 @@ securityContext: {} service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: 80 + # -- (list) The port number that the service exposes. + port: [] # -- (map) Resource requests and limits for the containers in the pod resources: @@ -205,9 +228,15 @@ affinity: {} # -- (list) Volumes to attach to the pod volumes: +- name: wsgi-config + configMap: + name: indexd-wsgi - name: uwsgi-config configMap: name: indexd-uwsgi +- name: nginx-config + configMap: + name: indexd-nginx-configmap - name: config-volume secret: secretName: "indexd-settings" diff --git a/helm/manifestservice/Chart.yaml b/helm/manifestservice/Chart.yaml index 382e0165..87860f02 100644 --- a/helm/manifestservice/Chart.yaml +++ b/helm/manifestservice/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.14 +version: 0.1.15 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -25,5 +25,5 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common diff --git a/helm/manifestservice/README.md b/helm/manifestservice/README.md index 11fc1f39..e4e87559 100644 --- a/helm/manifestservice/README.md +++ b/helm/manifestservice/README.md @@ -1,6 +1,6 @@ # manifestservice -![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for Kubernetes @@ -8,7 +8,7 @@ A Helm chart for Kubernetes | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | ## Values @@ -47,6 +47,10 @@ A Helm chart for Kubernetes | global.externalSecrets.separateSecretStore | string | `false` | Will deploy a separate External Secret Store for this service. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | image | map | `{"pullPolicy":"Always","repository":"quay.io/cdis/manifestservice","tag":""}` | Docker image information. | | image.pullPolicy | string | `"Always"` | Docker pull policy. | | image.repository | string | `"quay.io/cdis/manifestservice"` | Docker repository. | @@ -70,9 +74,16 @@ A Helm chart for Kubernetes | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Secret information for External Secrets. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":80,"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `80` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAccount | map | `{"annotations":{},"create":true,"name":""}` | Service account to use or create. | | serviceAccount.annotations | map | `{}` | Annotations to add to the service account. | @@ -83,5 +94,5 @@ A Helm chart for Kubernetes | strategy.rollingUpdate.maxUnavailable | int | `0` | Maximum amount of pods that can be unavailable during the update. | | terminationGracePeriodSeconds | int | `50` | Grace period that applies to the total time it takes for both the PreStop hook to execute and for the Container to stop normally. | | volumeMounts | list | `[{"mountPath":"/var/gen3/config/","name":"config-volume","readOnly":true}]` | Volumes to mount to the container. | -| volumes | list | `[{"name":"config-volume","secret":{"secretName":"manifestservice-g3auto"}}]` | Volumes to attach to the container. | +| volumes | list | `[{"configMap":{"name":"manifestservice-wsgi"},"name":"wsgi-config"},{"name":"config-volume","secret":{"secretName":"manifestservice-g3auto"}},{"configMap":{"name":"manifestservice-nginx-configmap"},"name":"nginx-config"}]` | Volumes to attach to the container. | diff --git a/helm/manifestservice/templates/deployment.yaml b/helm/manifestservice/templates/deployment.yaml index 6923a5c0..9b902dcd 100644 --- a/helm/manifestservice/templates/deployment.yaml +++ b/helm/manifestservice/templates/deployment.yaml @@ -28,6 +28,12 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} @@ -38,7 +44,11 @@ spec: terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds}} containers: - name: manifestservice + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/manifestservice:feat_GPE-1108" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- if .Values.global.ddEnabled }} @@ -46,19 +56,56 @@ spec: {{- end }} {{- toYaml .Values.env | nindent 12 }} volumeMounts: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/manifestservice/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} {{- toYaml .Values.volumeMounts | nindent 12 }} resources: {{- toYaml .Values.resources | nindent 12 }} ports: - - containerPort: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} + - name: http + containerPort: 80 + protocol: TCP + {{- end }} livenessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} initialDelaySeconds: 10 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} diff --git a/helm/manifestservice/templates/nginx_config.yaml b/helm/manifestservice/templates/nginx_config.yaml new file mode 100644 index 00000000..c2b114c1 --- /dev/null +++ b/helm/manifestservice/templates/nginx_config.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: manifestservice-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/manifestservice/templates/service.yaml b/helm/manifestservice/templates/service.yaml index 173ba48c..452a1803 100644 --- a/helm/manifestservice/templates/service.yaml +++ b/helm/manifestservice/templates/service.yaml @@ -7,9 +7,15 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: 80 - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} selector: {{- include "manifestservice.selectorLabels" . | nindent 4 }} diff --git a/helm/manifestservice/templates/wsgi.yaml b/helm/manifestservice/templates/wsgi.yaml new file mode 100644 index 00000000..f0c867d1 --- /dev/null +++ b/helm/manifestservice/templates/wsgi.yaml @@ -0,0 +1,14 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: manifestservice-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 +{{- end }} \ No newline at end of file diff --git a/helm/manifestservice/values.yaml b/helm/manifestservice/values.yaml index 09cd04f3..b048bbee 100644 --- a/helm/manifestservice/values.yaml +++ b/helm/manifestservice/values.yaml @@ -27,6 +27,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -56,12 +64,27 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # -- (map) Kubernetes service information. service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: 80 + # -- (list) The port number that the service exposes. + port: [] # -- (map) Service account to use or create. serviceAccount: @@ -118,9 +141,15 @@ automountServiceAccountToken: false # -- (list) Volumes to attach to the container. volumes: + - name: wsgi-config + configMap: + name: manifestservice-wsgi - name: config-volume secret: secretName: "manifestservice-g3auto" + - name: nginx-config + configMap: + name: manifestservice-nginx-configmap # -- (int) Grace period that applies to the total time it takes for both the PreStop hook to execute and for the Container to stop normally. terminationGracePeriodSeconds: 50 diff --git a/helm/metadata/Chart.yaml b/helm/metadata/Chart.yaml index d38d06e5..c2cd2d9b 100644 --- a/helm/metadata/Chart.yaml +++ b/helm/metadata/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.12 +version: 0.1.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -25,7 +25,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/metadata/README.md b/helm/metadata/README.md index c9553ba9..48999d46 100644 --- a/helm/metadata/README.md +++ b/helm/metadata/README.md @@ -1,6 +1,6 @@ # metadata -![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Metadata Service @@ -8,7 +8,7 @@ A Helm chart for gen3 Metadata Service | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | | https://helm.elastic.co | elasticsearch | 7.17.1 | @@ -25,7 +25,6 @@ A Helm chart for gen3 Metadata Service | affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.topologyKey | string | `"kubernetes.io/hostname"` | Value for topology key label. | | aggMdsConfig | string | `"{\n \"configuration\": {\n \"schema\": {\n \"_subjects_count\": {\n \"type\": \"integer\"\n },\n \"__manifest\": {\n \"description\": \"an array of filename (usually DRS ids and its size\",\n \"type\": \"array\",\n \"properties\": {\n \"file_name\": {\n \"type\": \"string\"\n },\n \"file_size\": {\n \"type\": \"integer\"\n }\n }\n },\n \"tags\": {\n \"type\": \"array\"\n },\n \"_unique_id\": {},\n \"study_description\": {},\n \"study_id\": {},\n \"study_url\": {},\n \"project_id\": {},\n \"short_name\": {\n \"default\": \"not_set\"\n },\n \"year\": {\n \"default\": \"not_set\"\n },\n \"full_name\": {},\n \"commons_url\": {},\n \"commons\": {}\n },\n \"settings\": {\n \"cache_drs\": true\n }\n },\n \"adapter_commons\": {\n \"Gen3\": {\n \"mds_url\": \"https://gen3.datacommons.io/\",\n \"commons_url\": \"gen3.datacommons.io/\",\n \"adapter\": \"gen3\",\n \"config\": {\n \"guid_type\": \"discovery_metadata\",\n \"study_field\": \"gen3_discovery\"\n },\n \"keep_original_fields\": false,\n \"field_mappings\": {\n \"tags\": \"path:tags\",\n \"_unique_id\": \"path:_unique_id\",\n \"study_description\": \"path:summary\",\n \"full_name\": \"path:study_title\",\n \"short_name\": \"path:short_name\",\n \"year\": \"path:year\",\n \"accession_number\": \"path:accession_number\",\n \"commons\": \"Gen3 Data Commons\",\n \"study_url\": {\n \"path\": \"link\",\n \"default\": \"unknown\"\n }\n }\n }\n }\n}\n"` | | | aggMdsNamespace | string | `"default"` | Namespae to use if AggMds is enabled. | -| args | list | `["-c","/env/bin/alembic upgrade head\n"]` | Arguments to pass to the init container. | | automountServiceAccountToken | bool | `false` | Automount the default service account token | | autoscaling | map | `{"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":80}` | Configuration for autoscaling the number of replicas | | autoscaling.enabled | bool | `false` | Whether autoscaling is enabled | @@ -78,6 +77,10 @@ A Helm chart for gen3 Metadata Service | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | image | map | `{"pullPolicy":"Always","repository":"quay.io/cdis/metadata-service","tag":"feat_es-7"}` | Docker image information. | | image.pullPolicy | string | `"Always"` | Docker pull policy. | @@ -113,9 +116,16 @@ A Helm chart for gen3 Metadata Service | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Secret information to access the db restore job S3 bucket. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":[{"name":"http","port":80,"protocol":"TCP","targetPort":80}],"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `[{"name":"http","port":80,"protocol":"TCP","targetPort":80}]` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAnnotations."getambassador.io/config" | string | `"---\napiVersion: ambassador/v1\nambassador_id: \"gen3\"\nkind: Mapping\nname: metadata_mapping\nprefix: /index/\nservice: http://metadata-service:80\n"` | | | strategy | map | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0},"type":"RollingUpdate"}` | Rolling update deployment strategy | diff --git a/helm/metadata/templates/deployment.yaml b/helm/metadata/templates/deployment.yaml index d0723397..f149c743 100644 --- a/helm/metadata/templates/deployment.yaml +++ b/helm/metadata/templates/deployment.yaml @@ -31,6 +31,12 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} @@ -48,9 +54,19 @@ spec: configMap: name: manifest-metadata optional: true + - name: wsgi-config + configMap: + name: metadata-wsgi + - name: nginx-config + configMap: + name: metadata-nginx-configmap containers: - name: {{ .Chart.Name }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/metadata-service:feat_GPE-1115" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} env: {{- if .Values.global.ddEnabled }} {{- include "common.datadogEnvVar" . | nindent 12 }} @@ -101,27 +117,68 @@ spec: livenessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} ports: - - containerPort: 80 - {{- with .Values.volumeMounts }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} + - name: http + containerPort: 80 + protocol: TCP + {{- end }} volumeMounts: + {{- with .Values.volumeMounts }} {{- toYaml . | nindent 10 }} {{- end }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/metadata-service/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} {{- with .Values.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} initContainers: - name: {{ .Values.initContainerName }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/metadata-service:feat_GPE-1115" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.initVolumeMounts }} env: @@ -163,7 +220,13 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} command: {{ .Values.command }} - {{- with .Values.args }} - args: - {{- toYaml . | nindent 12}} + args: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - "-c" + - | + alembic upgrade head + {{- else }} + - "-c" + - | + /env/bin/alembic upgrade head {{- end }} \ No newline at end of file diff --git a/helm/metadata/templates/nginx_config.yaml b/helm/metadata/templates/nginx_config.yaml new file mode 100644 index 00000000..524b8782 --- /dev/null +++ b/helm/metadata/templates/nginx_config.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: metadata-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/metadata/templates/service.yaml b/helm/metadata/templates/service.yaml index 0cc0cb06..ad798473 100644 --- a/helm/metadata/templates/service.yaml +++ b/helm/metadata/templates/service.yaml @@ -11,8 +11,15 @@ metadata: spec: selector: {{- include "metadata.selectorLabels" . | nindent 4 }} - {{- with .Values.service.port }} ports: + {{- with .Values.service.port }} {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} type: {{ .Values.service.type }} \ No newline at end of file diff --git a/helm/metadata/templates/wsgi.yaml b/helm/metadata/templates/wsgi.yaml new file mode 100644 index 00000000..be57e7dc --- /dev/null +++ b/helm/metadata/templates/wsgi.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: metadata-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 + worker_class = "uvicorn.workers.UvicornWorker" +{{- end }} \ No newline at end of file diff --git a/helm/metadata/values.yaml b/helm/metadata/values.yaml index d3953808..7364cb3a 100644 --- a/helm/metadata/values.yaml +++ b/helm/metadata/values.yaml @@ -65,6 +65,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -168,6 +176,21 @@ image: debug: false +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # Environment Variables # -- (string) Elasticsearch endpoint. esEndpoint: http://gen3-elasticsearch-master:9200 @@ -295,11 +318,6 @@ initResources: memory: 512Mi # -- (list) Command to run for the init container. command: ["/bin/sh"] -# -- (list) Arguments to pass to the init container. -args: - - "-c" - - | - /env/bin/alembic upgrade head # Service and Pod serviceAnnotations: @@ -316,12 +334,8 @@ serviceAnnotations: service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: - - protocol: TCP - port: 80 - targetPort: 80 - name: http + # -- (list) The port number that the service exposes. + port: [] # Values to determine the labels that are used for the deployment, pod, etc. # -- (string) Valid options are "production" or "dev". If invalid option is set- the value will default to "dev". diff --git a/helm/peregrine/Chart.yaml b/helm/peregrine/Chart.yaml index 10f79b5d..dc0c7c16 100644 --- a/helm/peregrine/Chart.yaml +++ b/helm/peregrine/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.13 +version: 0.1.14 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -26,7 +26,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/peregrine/README.md b/helm/peregrine/README.md index 8d9884c5..97f59798 100644 --- a/helm/peregrine/README.md +++ b/helm/peregrine/README.md @@ -1,6 +1,6 @@ # peregrine -![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Peregrine service @@ -8,7 +8,7 @@ A Helm chart for gen3 Peregrine service | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -58,6 +58,10 @@ A Helm chart for gen3 Peregrine service | global.postgres.master.port | string | `"5432"` | Port for Postgres. | | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | image.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | | image.repository | string | `"quay.io/cdis/peregrine"` | The Docker image repository for the fence service | @@ -89,16 +93,23 @@ A Helm chart for gen3 Peregrine service | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Secret information for External Secrets. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | securityContext | map | `{}` | Security context for the containers in the pod | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":80,"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `80` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAccount | map | `{"annotations":{},"create":true,"name":""}` | Service account to use or create. | | serviceAccount.annotations | map | `{}` | Annotations to add to the service account. | | serviceAccount.create | bool | `true` | Specifies whether a service account should be created. | | serviceAccount.name | string | `""` | The name of the service account | | tolerations | list | `[]` | Tolerations for the pods | -| volumeMounts | list | `[{"mountPath":"/var/www/peregrine/settings.py","name":"config-volume","readOnly":true,"subPath":"settings.py"}]` | Volumes to mount to the container. | -| volumes | list | `[{"emptyDir":{},"name":"shared-data"},{"name":"config-volume","secret":{"secretName":"peregrine-secret"}}]` | Volumes to attach to the container. | +| volumeMounts | list | `[]` | Volumes to mount to the container. | +| volumes | list | `[{"emptyDir":{},"name":"shared-data"},{"name":"config-volume","secret":{"secretName":"peregrine-secret"}},{"configMap":{"name":"peregrine-wsgi"},"name":"wsgi-config"},{"configMap":{"name":"peregrine-nginx-configmap"},"name":"nginx-config"}]` | Volumes to attach to the container. | diff --git a/helm/peregrine/templates/deployment.yaml b/helm/peregrine/templates/deployment.yaml index e554be55..3424c739 100644 --- a/helm/peregrine/templates/deployment.yaml +++ b/helm/peregrine/templates/deployment.yaml @@ -26,6 +26,14 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + securityContext: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- else }} + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- end }} {{- with .Values.volumes }} volumes: {{- toYaml . | nindent 8 }} @@ -35,13 +43,15 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "peregrine.serviceAccountName" . }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/peregrine:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- if .Values.global.ddEnabled }} @@ -147,18 +157,42 @@ spec: value: "False" - name: CONF_HOSTNAME value: {{ .Values.global.hostname }} - {{- with .Values.volumeMounts }} volumeMounts: + {{- with .Values.volumeMounts }} {{- toYaml . | nindent 10 }} {{- end }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/peregrine/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + - name: "config-volume" + readOnly: true + mountPath: "/peregrine/deployment/wsgi/wsgi.py" + subPath: "settings.py" + {{- else }} + - name: "config-volume" + readOnly: true + mountPath: "/var/www/peregrine/settings.py" + subPath: "settings.py" + {{- end }} ports: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} - name: http containerPort: 80 protocol: TCP + {{- end }} livenessProbe: httpGet: path: /_status?timeout=20 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} # peregrine can take forever to initialize initialDelaySeconds: 60 periodSeconds: 60 @@ -166,9 +200,29 @@ spec: readinessProbe: httpGet: path: /_status?timeout=2 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} port: http + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/peregrine/templates/nginx_config.yaml b/helm/peregrine/templates/nginx_config.yaml new file mode 100644 index 00000000..90735c92 --- /dev/null +++ b/helm/peregrine/templates/nginx_config.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: peregrine-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/peregrine/templates/service.yaml b/helm/peregrine/templates/service.yaml index afff1c22..2c2106d7 100644 --- a/helm/peregrine/templates/service.yaml +++ b/helm/peregrine/templates/service.yaml @@ -7,9 +7,15 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} selector: {{- include "peregrine.selectorLabels" . | nindent 4 }} diff --git a/helm/peregrine/templates/wsgi.yaml b/helm/peregrine/templates/wsgi.yaml new file mode 100644 index 00000000..3bf02e8a --- /dev/null +++ b/helm/peregrine/templates/wsgi.yaml @@ -0,0 +1,14 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: peregrine-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 +{{- end }} \ No newline at end of file diff --git a/helm/peregrine/values.yaml b/helm/peregrine/values.yaml index 46086658..5abadc74 100644 --- a/helm/peregrine/values.yaml +++ b/helm/peregrine/values.yaml @@ -62,6 +62,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -115,6 +123,21 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "feat_jq-audience" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # -- (list) Docker image pull secrets. imagePullSecrets: [] @@ -154,8 +177,8 @@ securityContext: {} service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: 80 + # -- (list) The port number that the service exposes. + port: [] # -- (map) Resource requests and limits for the containers in the pod resources: @@ -203,13 +226,15 @@ volumes: - name: config-volume secret: secretName: "peregrine-secret" +- name: wsgi-config + configMap: + name: peregrine-wsgi +- name: nginx-config + configMap: + name: peregrine-nginx-configmap # -- (list) Volumes to mount to the container. -volumeMounts: - - name: "config-volume" - readOnly: true - mountPath: "/var/www/peregrine/settings.py" - subPath: "settings.py" +volumeMounts: [] # Values to determine the labels that are used for the deployment, pod, etc. # -- (string) Valid options are "production" or "dev". If invalid option is set- the value will default to "dev". diff --git a/helm/requestor/Chart.yaml b/helm/requestor/Chart.yaml index e0c06a88..ab00815c 100644 --- a/helm/requestor/Chart.yaml +++ b/helm/requestor/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.11 +version: 0.1.12 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -26,7 +26,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/requestor/README.md b/helm/requestor/README.md index 85792b12..7ef35853 100644 --- a/helm/requestor/README.md +++ b/helm/requestor/README.md @@ -1,6 +1,6 @@ # requestor -![Version: 0.1.11](https://img.shields.io/badge/Version-0.1.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Requestor Service @@ -8,7 +8,7 @@ A Helm chart for gen3 Requestor Service | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -23,7 +23,6 @@ A Helm chart for gen3 Requestor Service | affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.labelSelector.matchExpressions[0].values | list | `["requestor"]` | Value for the match expression key. | | affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.topologyKey | string | `"kubernetes.io/hostname"` | Value for topology key label. | | arboristUrl | string | `"http://arborist-service"` | Arborist service URL. | -| args | list | `["-c","/env/bin/alembic upgrade head\n"]` | Arguments to pass to the init container. | | automountServiceAccountToken | bool | `false` | Automount the default service account token | | autoscaling | map | `{"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":80}` | Configuration for autoscaling the number of replicas | | autoscaling.enabled | bool | `false` | Whether autoscaling is enabled | @@ -68,6 +67,10 @@ A Helm chart for gen3 Requestor Service | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.slack_send_dbgap | bool | `false` | Will echo what files we are seeing on dbgap ftp to Slack. | | global.slack_webhook | string | `"None"` | Slack webhook endpoint used with certain jobs. | | global.syncFromDbgap | bool | `false` | Whether to sync data from dbGaP. | @@ -108,12 +111,19 @@ A Helm chart for gen3 Requestor Service | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Secret information for External Secrets. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":[{"name":"http","port":80,"protocol":"TCP","targetPort":80}],"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `[{"name":"http","port":80,"protocol":"TCP","targetPort":80}]` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | strategy | map | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0},"type":"RollingUpdate"}` | Rolling update deployment strategy | | strategy.rollingUpdate.maxSurge | int | `1` | Number of additional replicas to add during rollout. | | strategy.rollingUpdate.maxUnavailable | int | `0` | Maximum amount of pods that can be unavailable during the update. | -| volumeMounts | list | `nil` | Volumes to mount to the container. | +| volumeMounts | list | `[]` | Volumes to mount to the container. | diff --git a/helm/requestor/templates/deployment.yaml b/helm/requestor/templates/deployment.yaml index 24876c59..09569a75 100644 --- a/helm/requestor/templates/deployment.yaml +++ b/helm/requestor/templates/deployment.yaml @@ -31,6 +31,12 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} @@ -40,9 +46,19 @@ spec: - name: config-volume secret: secretName: "requestor-g3auto" + - name: wsgi-config + configMap: + name: requestor-wsgi + - name: nginx-config + configMap: + name: requestor-nginx-configmap containers: - name: requestor + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/requestor:feat_al2" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} env: - name: DB_PORT value: "5432" @@ -86,27 +102,68 @@ spec: livenessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} ports: - - containerPort: 80 - {{- with .Values.volumeMounts }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} + - name: http + containerPort: 80 + protocol: TCP + {{- end }} volumeMounts: + {{- with .Values.volumeMounts }} {{- toYaml . | nindent 10 }} {{- end }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/requestor/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} {{- with .Values.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} initContainers: - name: requestor-db-migrate + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/requestor:feat_al2" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- if .Values.global.ddEnabled }} @@ -154,6 +211,12 @@ spec: {{- end }} command: ["/bin/sh"] args: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - "-c" + - | + alembic upgrade head + {{- else }} - "-c" - | - /env/bin/alembic upgrade head \ No newline at end of file + /env/bin/alembic upgrade head + {{- end }} \ No newline at end of file diff --git a/helm/requestor/templates/nginx_config.yaml b/helm/requestor/templates/nginx_config.yaml new file mode 100644 index 00000000..f21d0bef --- /dev/null +++ b/helm/requestor/templates/nginx_config.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: requestor-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/requestor/templates/service.yaml b/helm/requestor/templates/service.yaml index e71b0650..d912d810 100644 --- a/helm/requestor/templates/service.yaml +++ b/helm/requestor/templates/service.yaml @@ -7,8 +7,15 @@ metadata: spec: selector: {{- include "requestor.selectorLabels" . | nindent 4 }} - {{- with .Values.service.port }} ports: + {{- with .Values.service.port }} {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} type: {{ .Values.service.type }} \ No newline at end of file diff --git a/helm/requestor/templates/wsgi.yaml b/helm/requestor/templates/wsgi.yaml new file mode 100644 index 00000000..ad212448 --- /dev/null +++ b/helm/requestor/templates/wsgi.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: requestor-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 + worker_class = "uvicorn.workers.UvicornWorker" +{{- end }} \ No newline at end of file diff --git a/helm/requestor/values.yaml b/helm/requestor/values.yaml index 1a060975..606a5793 100644 --- a/helm/requestor/values.yaml +++ b/helm/requestor/values.yaml @@ -79,6 +79,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -179,16 +187,27 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "master" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # Environment Variables # -- (string) Arborist service URL. arboristUrl: http://arborist-service # -- (list) Volumes to mount to the container. -volumeMounts: - # - name: "config-volume" - # readOnly: true - # mountPath: "/src/requestor-config.yaml" - # subPath: "requestor-config.yaml" +volumeMounts: [] # -- (map) Resource requests and limits for the containers in the pod resources: @@ -218,23 +237,14 @@ initResources: memory: 512Mi # -- (list) Command to run for the init container. command: ["/bin/sh"] -# -- (list) Arguments to pass to the init container. -args: - - "-c" - - | - /env/bin/alembic upgrade head # Service and Pod # -- (map) Kubernetes service information. service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: - - protocol: TCP - port: 80 - targetPort: 80 - name: http + # -- (list) The port number that the service exposes. + port: [] # Values to determine the labels that are used for the deployment, pod, etc. # -- (string) Valid options are "production" or "dev". If invalid option is set- the value will default to "dev". diff --git a/helm/sheepdog/Chart.yaml b/helm/sheepdog/Chart.yaml index ea4bcc32..3e93d550 100644 --- a/helm/sheepdog/Chart.yaml +++ b/helm/sheepdog/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.14 +version: 0.1.15 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -25,7 +25,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/sheepdog/README.md b/helm/sheepdog/README.md index afbdd189..f8f6be27 100644 --- a/helm/sheepdog/README.md +++ b/helm/sheepdog/README.md @@ -1,6 +1,6 @@ # sheepdog -![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Sheepdog Service @@ -8,7 +8,7 @@ A Helm chart for gen3 Sheepdog Service | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -68,6 +68,10 @@ A Helm chart for gen3 Sheepdog Service | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | image | map | `{"pullPolicy":"Always","repository":"quay.io/cdis/sheepdog","tag":"bug_auth-audience"}` | Docker image information. | | image.pullPolicy | string | `"Always"` | Docker pull policy. | @@ -100,13 +104,20 @@ A Helm chart for gen3 Sheepdog Service | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null}` | Values for sheepdog secret. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID to access the db restore job S3 bucket. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID to access the db restore job S3 bucket. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"port":80,"type":"ClusterIP"}` | Kubernetes service information. | -| service.port | int | `80` | The port number that the service exposes. | +| service | map | `{"port":[],"type":"ClusterIP"}` | Kubernetes service information. | +| service.port | list | `[]` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | strategy | map | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0},"type":"RollingUpdate"}` | Rolling update deployment strategy | | strategy.rollingUpdate.maxSurge | int | `1` | Number of additional replicas to add during rollout. | | strategy.rollingUpdate.maxUnavailable | int | `0` | Maximum amount of pods that can be unavailable during the update. | | terminationGracePeriodSeconds | int | `50` | sheepdog transactions take forever - try to let the complete before termination | -| volumeMounts | list | `[{"mountPath":"/var/www/sheepdog/settings.py","name":"config-volume","readOnly":true,"subPath":"settings.py"}]` | Volumes to mount to the container. | +| volumeMounts | list | `[]` | Volumes to mount to the container. | diff --git a/helm/sheepdog/templates/deployment.yaml b/helm/sheepdog/templates/deployment.yaml index d56beb93..5e902174 100644 --- a/helm/sheepdog/templates/deployment.yaml +++ b/helm/sheepdog/templates/deployment.yaml @@ -35,6 +35,12 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} @@ -47,9 +53,20 @@ spec: - name: config-helper configMap: name: config-helper + - name: wsgi-config + configMap: + name: sheepdog-wsgi + - name: nginx-config + configMap: + name: sheepdog-nginx-configmap initContainers: - name: sheepdog-init + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/sheepdog:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- if .Values.global.ddEnabled }} {{- include "common.datadogEnvVar" . | nindent 12 }} @@ -104,15 +121,30 @@ spec: python /sheepdog/bin/setup_transactionlogs.py --user "${PGUSER}" --password "${PGPASSWORD}" --host "${PGHOST}" --database "${PGDB}" containers: - name: sheepdog + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/audit-service:feat_GPE-1113" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - - containerPort: 80 - - containerPort: 443 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} + - name: http + containerPort: 80 + protocol: TCP + {{- end }} livenessProbe: httpGet: path: /_status?timeout=20 - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 30 @@ -120,7 +152,11 @@ spec: initialDelaySeconds: 30 httpGet: path: /_status?timeout=2 - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} # command: ["/bin/bash" ] # args: # - "-c" @@ -231,9 +267,39 @@ spec: # value: /etc/ssl/certs/ca-certificates.crt - name: GEN3_DEBUG value: "True" - {{- with .Values.volumeMounts }} volumeMounts: + {{- with .Values.volumeMounts }} {{- toYaml . | nindent 10 }} {{- end }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "config-volume" + readOnly: true + mountPath: "/sheepdog/deployment/wsgi/wsgi.py" + subPath: "wsgi.py" + - name: "wsgi-config" + mountPath: "/sheepdog/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- else }} + - name: "config-volume" + readOnly: true + mountPath: "/var/www/sheepdog/settings.py" + subPath: "settings.py" + {{- end }} resources: - {{- toYaml .Values.resources | nindent 12 }} \ No newline at end of file + {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} \ No newline at end of file diff --git a/helm/sheepdog/templates/nginx_config.yaml b/helm/sheepdog/templates/nginx_config.yaml new file mode 100644 index 00000000..4839cb06 --- /dev/null +++ b/helm/sheepdog/templates/nginx_config.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: sheepdog-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/sheepdog/templates/service.yaml b/helm/sheepdog/templates/service.yaml index eff84f42..a43de377 100644 --- a/helm/sheepdog/templates/service.yaml +++ b/helm/sheepdog/templates/service.yaml @@ -7,9 +7,15 @@ metadata: spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.port }} - targetPort: {{ .Values.service.port }} - protocol: TCP - name: http + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} selector: {{- include "sheepdog.selectorLabels" . | nindent 4 }} diff --git a/helm/sheepdog/templates/wsgi.yaml b/helm/sheepdog/templates/wsgi.yaml new file mode 100644 index 00000000..3c12cd15 --- /dev/null +++ b/helm/sheepdog/templates/wsgi.yaml @@ -0,0 +1,14 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: sheepdog-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 +{{- end }} \ No newline at end of file diff --git a/helm/sheepdog/values.yaml b/helm/sheepdog/values.yaml index 59b0841f..6a17850c 100644 --- a/helm/sheepdog/values.yaml +++ b/helm/sheepdog/values.yaml @@ -65,6 +65,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -170,6 +178,21 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "bug_auth-audience" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # Environment Variables # -- (string) URL of the data dictionary. dictionaryUrl: https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json @@ -182,11 +205,7 @@ arboristUrl: http://arborist-service authNamespace: default # -- (list) Volumes to mount to the container. -volumeMounts: - - name: "config-volume" - readOnly: true - mountPath: "/var/www/sheepdog/settings.py" - subPath: "settings.py" +volumeMounts: [] # -- (map) Resource requests and limits for the containers in the pod resources: @@ -208,8 +227,8 @@ resources: service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) The port number that the service exposes. - port: 80 + # -- (list) The port number that the service exposes. + port: [] # Secrets # -- (map) Values for sheepdog secret. diff --git a/helm/wts/Chart.yaml b/helm/wts/Chart.yaml index 6d9533e4..8c6abbb8 100644 --- a/helm/wts/Chart.yaml +++ b/helm/wts/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.13 +version: 0.1.14 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -25,7 +25,7 @@ appVersion: "master" dependencies: - name: common - version: 0.1.10 + version: 0.1.12 repository: file://../common - name: postgresql version: 11.9.13 diff --git a/helm/wts/README.md b/helm/wts/README.md index f755b799..d163467e 100644 --- a/helm/wts/README.md +++ b/helm/wts/README.md @@ -1,6 +1,6 @@ # wts -![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 workspace token service @@ -8,7 +8,7 @@ A Helm chart for gen3 workspace token service | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.10 | +| file://../common | common | 0.1.12 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values @@ -57,6 +57,10 @@ A Helm chart for gen3 workspace token service | global.postgres.master.username | string | `"postgres"` | username of superuser in postgres. This is used to create or restore databases | | global.publicDataSets | bool | `true` | Whether public datasets are enabled. | | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | +| global.secureImage | map | `{"enabled":false,"sidecar":{"enabled":false}}` | Configuration settings for the secure AL2 based image. | +| global.secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| global.secureImage.sidecar | map | `{"enabled":false}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| global.secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | hostname | string | `nil` | Hostname for the deployment. | | image | map | `{"pullPolicy":"Always","repository":"quay.io/cdis/workspace-token-service","tag":"feat_wts_internalfence"}` | Docker image information. | @@ -93,15 +97,22 @@ A Helm chart for gen3 workspace token service | secrets | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null,"external_oidc":null}` | Values for wts secret and keys for External Secrets. | | secrets.awsAccessKeyId | str | `nil` | AWS access key ID. Overrides global key. | | secrets.awsSecretAccessKey | str | `nil` | AWS secret access key ID. Overrides global key. | +| secureImage | map | `{"enabled":false,"sidecar":{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}}` | Configuration settings for the secure AL2 based image. | +| secureImage.enabled | bool | `false` | Enable the use of the secure AL2 based image. | +| secureImage.sidecar | map | `{"enabled":false,"image":"quay.io/cdis/nginx-sidecar","pullPolicy":"IfNotPresent","tag":"nginx-sidecar-feat_nginx-sidecar"}` | Configuration for Nginx sidecar container to be deployed with gunicorn. | +| secureImage.sidecar.enabled | bool | `false` | Enable the Nginx sidecar container. | +| secureImage.sidecar.image | string | `"quay.io/cdis/nginx-sidecar"` | The Docker image repository for nginx | +| secureImage.sidecar.pullPolicy | string | `"IfNotPresent"` | When to pull the image. | +| secureImage.sidecar.tag | string | `"nginx-sidecar-feat_nginx-sidecar"` | Image tag. | | securityContext | map | `{}` | Security context for the containers in the pod | | selectorLabels | map | `nil` | Will completely override the selectorLabels defined in the common chart's _label_setup.tpl | -| service | map | `{"httpPort":80,"httpsPort":443,"type":"ClusterIP"}` | Configuration for the service | -| service.httpPort | int | `80` | Port on which the service is exposed | -| service.httpsPort | int | `443` | Secure port on which the service is exposed | +| service | map | `{"port":[],"type":"ClusterIP"}` | Configuration for the service | +| service.port | list | `[]` | Port on which the service is exposed | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | | serviceAccount | map | `{"annotations":{},"create":true,"name":""}` | Service account to use or create. | | serviceAccount.annotations | map | `{}` | Annotations to add to the service account. | | serviceAccount.create | bool | `true` | Specifies whether a service account should be created. | | serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | | tolerations | list | `[]` | Tolerations for the pods | +| volumeMounts | list | `[{"mountPath":"/var/www/wts/appcreds.json","name":"wts-secret","readOnly":true,"subPath":"appcreds.json"}]` | Volumes to mount to the container. | diff --git a/helm/wts/templates/deployment.yaml b/helm/wts/templates/deployment.yaml index e3f20dec..57cbe3e7 100644 --- a/helm/wts/templates/deployment.yaml +++ b/helm/wts/templates/deployment.yaml @@ -38,6 +38,12 @@ spec: {{- include "common.datadogLabels" . | nindent 8 }} {{- end }} spec: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + {{- end }} affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -55,6 +61,12 @@ spec: - name: wts-secret secret: secretName: "wts-g3auto" + - name: wsgi-config + configMap: + name: wts-wsgi + - name: nginx-config + configMap: + name: wts-nginx-configmap {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} @@ -62,27 +74,49 @@ spec: serviceAccountName: workspace-token-service containers: - name: {{ .Chart.Name }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/workspace-token-service:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.volumeMounts }} volumeMounts: - - name: "wts-secret" - readOnly: true - mountPath: "/var/www/wts/appcreds.json" - subPath: appcreds.json + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: "wsgi-config" + mountPath: "/wts/deployment/wsgi/gunicorn.conf.py" + subPath: gunicorn.conf.py + {{- end }} ports: + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + - name: app + containerPort: 8000 + protocol: TCP + {{- else }} - name: http containerPort: 80 protocol: TCP + {{- end }} livenessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} failureThreshold: 10 initialDelaySeconds: 5 readinessProbe: httpGet: path: /_status - port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + port: app + {{- else }} + port: http + {{- end }} env: {{- if .Values.global.ddEnabled }} {{- include "common.datadogEnvVar" . | nindent 11 }} @@ -137,15 +171,34 @@ spec: value: postgresql://$(PGUSER):$(PGPASSWORD)@$(PGHOST):5432/$(PGDB) resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} + - name: sidecar-nginx + image: "{{ .Values.secureImage.sidecar.image }}:{{ .Values.secureImage.sidecar.tag }}" + imagePullPolicy: {{ .Values.secureImage.sidecar.pullPolicy }} + ports: + - name: app + containerPort: 8080 + readinessProbe: + httpGet: + path: /_status + port: app + volumeMounts: + - name: "nginx-config" + mountPath: "/etc/nginx/conf.d/default.conf" + subPath: default.conf + {{- end }} initContainers: - name: wts-db-migrate + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + image: "quay.io/cdis/workspace-token-service:feat_gunicorn" + {{- else }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.volumeMounts }} volumeMounts: - - name: "wts-secret" - readOnly: true - mountPath: "/var/www/wts/appcreds.json" - subPath: appcreds.json + {{- toYaml . | nindent 10 }} + {{- end }} env: - name: PGHOST valueFrom: @@ -206,4 +259,3 @@ spec: tolerations: {{- toYaml . | nindent 8 }} {{- end }} - diff --git a/helm/wts/templates/nginx_config.yaml b/helm/wts/templates/nginx_config.yaml new file mode 100644 index 00000000..0e28060b --- /dev/null +++ b/helm/wts/templates/nginx_config.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secureImage.sidecar.enabled | default .Values.global.secureImage.sidecar.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: wts-nginx-configmap +data: + default.conf: | + server { + listen 8080; + server_name localhost; + location / { + proxy_pass http://127.0.0.1:8000; # Gunicorn binds to this address + } + } +{{- end }} \ No newline at end of file diff --git a/helm/wts/templates/service.yaml b/helm/wts/templates/service.yaml index 66efd2ce..4c4889c5 100644 --- a/helm/wts/templates/service.yaml +++ b/helm/wts/templates/service.yaml @@ -9,11 +9,13 @@ spec: app: wts type: {{ .Values.service.type }} ports: - - protocol: TCP - port: {{ .Values.service.httpPort }} - targetPort: {{ .Values.service.httpPort }} - name: http - - protocol: TCP - port: {{ .Values.service.httpsPort }} - targetPort: {{ .Values.service.httpsPort }} - name: https \ No newline at end of file + {{- with .Values.service.port }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: http + port: 80 + {{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} + targetPort: 8080 + {{- else }} + targetPort: 80 + {{- end }} \ No newline at end of file diff --git a/helm/wts/templates/wsgi.yaml b/helm/wts/templates/wsgi.yaml new file mode 100644 index 00000000..5fc2960f --- /dev/null +++ b/helm/wts/templates/wsgi.yaml @@ -0,0 +1,14 @@ +{{- if .Values.secureImage.enabled | default .Values.global.secureImage.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: wts-wsgi +data: + gunicorn.conf.py: | + wsgi_app = "deployment.wsgi.wsgi:application" + bind = "0.0.0.0:8000" + workers = 1 + user = 'gen3' + group = 'gen3' + timeout = 300 +{{- end }} \ No newline at end of file diff --git a/helm/wts/templates/wts-oidc.yaml b/helm/wts/templates/wts-oidc.yaml index 769a3c47..3b2b7d7d 100644 --- a/helm/wts/templates/wts-oidc.yaml +++ b/helm/wts/templates/wts-oidc.yaml @@ -3,6 +3,7 @@ kind: Job metadata: name: wts-oidc-job spec: + ttlSecondsAfterFinished: 100 template: metadata: labels: diff --git a/helm/wts/values.yaml b/helm/wts/values.yaml index d4e10223..0e2ce44f 100644 --- a/helm/wts/values.yaml +++ b/helm/wts/values.yaml @@ -65,6 +65,14 @@ global: deploy: false # -- (string) Will deploy a separate External Secret Store for this service. separateSecretStore: false + # -- (map) Configuration settings for the secure AL2 based image. + secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false # -- (map) External Secrets settings. externalSecrets: @@ -109,6 +117,21 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "feat_wts_internalfence" +# -- (map) Configuration settings for the secure AL2 based image. +secureImage: + # -- (bool) Enable the use of the secure AL2 based image. + enabled: false + # -- (map) Configuration for Nginx sidecar container to be deployed with gunicorn. + sidecar: + # -- (bool) Enable the Nginx sidecar container. + enabled: false + # -- (string) The Docker image repository for nginx + image: quay.io/cdis/nginx-sidecar + # -- (string) When to pull the image. + pullPolicy: IfNotPresent + # -- (string) Image tag. + tag: "nginx-sidecar-feat_nginx-sidecar" + # -- (list) Docker image pull secrets. imagePullSecrets: [] @@ -155,10 +178,15 @@ securityContext: {} service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". type: ClusterIP - # -- (int) Port on which the service is exposed - httpPort: 80 - # -- (int) Secure port on which the service is exposed - httpsPort: 443 + # -- (list) Port on which the service is exposed + port: [] + +# -- (list) Volumes to mount to the container. +volumeMounts: + - name: "wts-secret" + readOnly: true + mountPath: "/var/www/wts/appcreds.json" + subPath: appcreds.json # -- (map) Resource requests and limits for the containers in the pod resources: