From 6e28fd7f26ae4d53800ac133e3bda591e65200f8 Mon Sep 17 00:00:00 2001 From: Danny August Ramaputra Date: Sun, 14 Feb 2021 13:26:10 +1000 Subject: [PATCH 1/6] ci: initialized helm chart --- .daystram/helm-chart/.helmignore | 23 ++++++ .daystram/helm-chart/Chart.yaml | 24 ++++++ .daystram/helm-chart/templates/NOTES.txt | 22 ++++++ .daystram/helm-chart/templates/_helpers.tpl | 62 +++++++++++++++ .../helm-chart/templates/deployment.yaml | 61 ++++++++++++++ .daystram/helm-chart/templates/hpa.yaml | 28 +++++++ .daystram/helm-chart/templates/ingress.yaml | 41 ++++++++++ .daystram/helm-chart/templates/service.yaml | 15 ++++ .../helm-chart/templates/serviceaccount.yaml | 12 +++ .../templates/tests/test-connection.yaml | 15 ++++ .daystram/helm-chart/values.yaml | 79 +++++++++++++++++++ 11 files changed, 382 insertions(+) create mode 100644 .daystram/helm-chart/.helmignore create mode 100644 .daystram/helm-chart/Chart.yaml create mode 100644 .daystram/helm-chart/templates/NOTES.txt create mode 100644 .daystram/helm-chart/templates/_helpers.tpl create mode 100644 .daystram/helm-chart/templates/deployment.yaml create mode 100644 .daystram/helm-chart/templates/hpa.yaml create mode 100644 .daystram/helm-chart/templates/ingress.yaml create mode 100644 .daystram/helm-chart/templates/service.yaml create mode 100644 .daystram/helm-chart/templates/serviceaccount.yaml create mode 100644 .daystram/helm-chart/templates/tests/test-connection.yaml create mode 100644 .daystram/helm-chart/values.yaml diff --git a/.daystram/helm-chart/.helmignore b/.daystram/helm-chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/.daystram/helm-chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/.daystram/helm-chart/Chart.yaml b/.daystram/helm-chart/Chart.yaml new file mode 100644 index 0000000..d905a87 --- /dev/null +++ b/.daystram/helm-chart/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: ratify +description: Central Authentication Service implementing OAuth 2.0 and OpenID Connect protocols + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +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: APPLICATION_VERSION + +# 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 +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: APPLICATION_VERSION diff --git a/.daystram/helm-chart/templates/NOTES.txt b/.daystram/helm-chart/templates/NOTES.txt new file mode 100644 index 0000000..f7fc5b0 --- /dev/null +++ b/.daystram/helm-chart/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "ratify.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "ratify.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "ratify.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "ratify.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/.daystram/helm-chart/templates/_helpers.tpl b/.daystram/helm-chart/templates/_helpers.tpl new file mode 100644 index 0000000..3c7a509 --- /dev/null +++ b/.daystram/helm-chart/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ratify.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ratify.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ratify.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ratify.labels" -}} +helm.sh/chart: {{ include "ratify.chart" . }} +{{ include "ratify.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ratify.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ratify.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ratify.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ratify.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/.daystram/helm-chart/templates/deployment.yaml b/.daystram/helm-chart/templates/deployment.yaml new file mode 100644 index 0000000..cdde4ab --- /dev/null +++ b/.daystram/helm-chart/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ratify.fullname" . }} + labels: + {{- include "ratify.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "ratify.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "ratify.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "ratify.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/.daystram/helm-chart/templates/hpa.yaml b/.daystram/helm-chart/templates/hpa.yaml new file mode 100644 index 0000000..3f8564e --- /dev/null +++ b/.daystram/helm-chart/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "ratify.fullname" . }} + labels: + {{- include "ratify.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "ratify.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/.daystram/helm-chart/templates/ingress.yaml b/.daystram/helm-chart/templates/ingress.yaml new file mode 100644 index 0000000..7284492 --- /dev/null +++ b/.daystram/helm-chart/templates/ingress.yaml @@ -0,0 +1,41 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "ratify.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "ratify.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/.daystram/helm-chart/templates/service.yaml b/.daystram/helm-chart/templates/service.yaml new file mode 100644 index 0000000..1523de5 --- /dev/null +++ b/.daystram/helm-chart/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ratify.fullname" . }} + labels: + {{- include "ratify.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "ratify.selectorLabels" . | nindent 4 }} diff --git a/.daystram/helm-chart/templates/serviceaccount.yaml b/.daystram/helm-chart/templates/serviceaccount.yaml new file mode 100644 index 0000000..14cd6ad --- /dev/null +++ b/.daystram/helm-chart/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ratify.serviceAccountName" . }} + labels: + {{- include "ratify.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/.daystram/helm-chart/templates/tests/test-connection.yaml b/.daystram/helm-chart/templates/tests/test-connection.yaml new file mode 100644 index 0000000..f490aba --- /dev/null +++ b/.daystram/helm-chart/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "ratify.fullname" . }}-test-connection" + labels: + {{- include "ratify.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "ratify.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/.daystram/helm-chart/values.yaml b/.daystram/helm-chart/values.yaml new file mode 100644 index 0000000..df40b33 --- /dev/null +++ b/.daystram/helm-chart/values.yaml @@ -0,0 +1,79 @@ +# Default values for ratify. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} From aca91a9956a1c8842bbbc6846650dcc24dcfebf3 Mon Sep 17 00:00:00 2001 From: Danny August Ramaputra Date: Sun, 14 Feb 2021 13:29:05 +1000 Subject: [PATCH 2/6] ci: added helm packaging step --- .gitlab-ci.yml | 74 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 31fd9ce..6c6a4a7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,8 @@ stages: - build - test - - deploy + - image + - chart # ------------------------ ratify-be build ratify-be: @@ -26,8 +27,8 @@ test ratify-be: - cd ratify-be - go test ./tests/... -deploy dev ratify-be: - stage: deploy +image dev ratify-be: + stage: image image: docker:19.03.12 needs: ["test ratify-be"] environment: @@ -48,8 +49,8 @@ deploy dev ratify-be: except: - master -deploy prod ratify-be: - stage: deploy +image prod ratify-be: + stage: image image: docker:19.03.12 needs: ["test ratify-be"] environment: @@ -81,8 +82,8 @@ build ratify-fe: paths: - ratify-fe/dist/ -deploy dev ratify-fe: - stage: deploy +image dev ratify-fe: + stage: image image: docker:19.03.12 needs: ["build ratify-fe"] environment: @@ -104,8 +105,8 @@ deploy dev ratify-fe: except: - master -deploy prod ratify-fe: - stage: deploy +image prod ratify-fe: + stage: image image: docker:19.03.12 needs: ["build ratify-fe"] environment: @@ -125,3 +126,58 @@ deploy prod ratify-fe: when: on_success only: - tags + +# ------------------------ chart +chart dev ratify: + stage: chart + image: daystram/k8s-tools:latest + needs: ["image dev ratify-be", "image dev ratify-fe"] + variables: + APPLICATION_NAME: "ratify" + APPLICATION_VERSION: "v0.0.0-development" + before_script: + - git config --global user.name "$BOTDAYSTRAM_NAME" + - git config --global user.email "$BOTDAYSTRAM_EMAIL" + - mkdir -p ~/.ssh && eval `ssh-agent -s` && ssh-keyscan github.com >> ~/.ssh/known_hosts + - cat $BOTDAYSTRAM_KEY_FILE | ssh-add - + - cat $KUBECONFIG_FILE > $KUBECONFIG && chmod 700 $KUBECONFIG + script: + - git clone git@github.com:daystram/helm-charts.git + - cp -r .daystram helm-charts/docs/ + - cd helm-charts/docs/ + - curl -sfL https://charts.daystram.com/build.sh | sh -s - $APPLICATION_NAME $APPLICATION_VERSION + - rm -rf .daystram/ + - git add . + - 'git commit -m "feat: added chart for ${APPLICATION_NAME}@${APPLICATION_VERSION}"' + - git push + when: on_success + only: + - branches + except: + - main + +chart prod ratify: + stage: chart + image: daystram/k8s-tools:latest + needs: ["image prod ratify-be", "image prod ratify-fe"] + variables: + APPLICATION_NAME: "ratify" + APPLICATION_VERSION: "$CI_COMMIT_TAG" + before_script: + - git config --global user.name "$BOTDAYSTRAM_NAME" + - git config --global user.email "$BOTDAYSTRAM_EMAIL" + - mkdir -p ~/.ssh && eval `ssh-agent -s` && ssh-keyscan github.com >> ~/.ssh/known_hosts + - cat $BOTDAYSTRAM_KEY_FILE | ssh-add - + - cat $KUBECONFIG_FILE > $KUBECONFIG && chmod 700 $KUBECONFIG + script: + - git clone git@github.com:daystram/helm-charts.git + - cp -r .daystram helm-charts/docs/ + - cd helm-charts/docs/ + - curl -sfL https://charts.daystram.com/build.sh | sh -s - $APPLICATION_NAME $APPLICATION_VERSION + - rm -rf .daystram/ + - git add . + - 'git commit -m "feat: added chart for ${APPLICATION_NAME}@${APPLICATION_VERSION}"' + - git push + when: on_success + only: + - tags From bdd5ec35a5c026a5743292d34753c6dfb74e23af Mon Sep 17 00:00:00 2001 From: Danny August Ramaputra Date: Sun, 14 Feb 2021 14:11:18 +1000 Subject: [PATCH 3/6] ci: updated helm chart --- .daystram/helm-chart/templates/NOTES.txt | 22 ---- .../helm-chart/templates/deployment.yaml | 87 ++++++++++++--- .daystram/helm-chart/templates/ingress.yaml | 105 +++++++++++++----- .daystram/helm-chart/templates/service.yaml | 27 ++++- .daystram/helm-chart/values.yaml | 42 ++++--- 5 files changed, 195 insertions(+), 88 deletions(-) diff --git a/.daystram/helm-chart/templates/NOTES.txt b/.daystram/helm-chart/templates/NOTES.txt index f7fc5b0..e69de29 100644 --- a/.daystram/helm-chart/templates/NOTES.txt +++ b/.daystram/helm-chart/templates/NOTES.txt @@ -1,22 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "ratify.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "ratify.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "ratify.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "ratify.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} diff --git a/.daystram/helm-chart/templates/deployment.yaml b/.daystram/helm-chart/templates/deployment.yaml index cdde4ab..3f34a92 100644 --- a/.daystram/helm-chart/templates/deployment.yaml +++ b/.daystram/helm-chart/templates/deployment.yaml @@ -1,16 +1,19 @@ + apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "ratify.fullname" . }} + name: {{ include "folio.fullname" . }}-be labels: - {{- include "ratify.labels" . | nindent 4 }} + {{- include "folio.labels" . | nindent 4 }} + tier: be spec: {{- if not .Values.autoscaling.enabled }} - replicas: {{ .Values.replicaCount }} + replicas: {{ .Values.ratify.be.replicaCount }} {{- end }} selector: matchLabels: - {{- include "ratify.selectorLabels" . | nindent 6 }} + {{- include "folio.selectorLabels" . | nindent 6 }} + tier: be template: metadata: {{- with .Values.podAnnotations }} @@ -18,33 +21,87 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} labels: - {{- include "ratify.selectorLabels" . | nindent 8 }} + {{- include "folio.selectorLabels" . | nindent 8 }} + tier: be spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - serviceAccountName: {{ include "ratify.serviceAccountName" . }} + serviceAccountName: {{ include "folio.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: "{{ .Values.image.repository }}:be-{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + envFrom: + - secretRef: + name: {{ .Values.ratify.be.envFrom.secretRef }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "folio.fullname" . }}-fe + labels: + {{- include "folio.labels" . | nindent 4 }} + tier: fe +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.ratify.fe.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "folio.selectorLabels" . | nindent 6 }} + tier: fe + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "folio.selectorLabels" . | nindent 8 }} + tier: fe + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "folio.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:fe-{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 80 protocol: TCP - livenessProbe: - httpGet: - path: / - port: http - readinessProbe: - httpGet: - path: / - port: http resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} diff --git a/.daystram/helm-chart/templates/ingress.yaml b/.daystram/helm-chart/templates/ingress.yaml index 7284492..3d0885d 100644 --- a/.daystram/helm-chart/templates/ingress.yaml +++ b/.daystram/helm-chart/templates/ingress.yaml @@ -1,41 +1,86 @@ {{- if .Values.ingress.enabled -}} -{{- $fullName := include "ratify.fullname" . -}} -{{- $svcPort := .Values.service.port -}} -{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} -kind: Ingress +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute metadata: - name: {{ $fullName }} + name: {{ include "folio.fullname" . }} labels: - {{- include "ratify.labels" . | nindent 4 }} + {{- include "folio.labels" . | nindent 4 }} {{- with .Values.ingress.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} spec: + entryPoints: + - websecure + routes: + - kind: Rule + match: "Host(`{{ .Values.ingress.host }}`)" + services: + - name: {{ include "folio.fullname" . }}-fe + passHostHeader: true + port: {{ .Values.service.port }} + middlewares: + - name: gzip + - kind: Rule + match: "Host(`{{ .Values.ingress.host }}`) && PathPrefix(`/api`)" + services: + - name: {{ include "folio.fullname" . }}-be + passHostHeader: true + port: {{ .Values.service.port }} + - kind: Rule + match: "Host(`{{ .Values.ingress.host }}`) && PathPrefix(`/oauth`)" + services: + - name: {{ include "folio.fullname" . }}-be + passHostHeader: true + port: {{ .Values.service.port }} + middlewares: + - name: cors {{- if .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} - http: - paths: - {{- range .paths }} - - path: {{ .path }} - backend: - serviceName: {{ $fullName }} - servicePort: {{ $svcPort }} - {{- end }} - {{- end }} + secretName: cert-{{ include "folio.fullname" . }} {{- end }} + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: gzip +spec: + compress: {} + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: cors +spec: + headers: + accessControlAllowOriginList: + - "*" + accessControlAllowMethods: + - "GET" + - "POST" + accessControlAllowHeaders: + - "Content-Type" + - "Content-Length" + - "Authorization" + - "Origin" + accessControlExposeHeaders: + - "Content-Type" + - "Content-Length" + accessControlAllowCredentials: false + accessControlMaxAge: 120 + +--- +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: cert-{{ include "folio.fullname" . }} +spec: + secretName: cert-{{ include "folio.fullname" . }} + dnsNames: + - {{ .Values.ingress.host }} + issuerRef: + kind: {{ .Values.ingress.certificate.issuerRef.kind }} + name: {{ .Values.ingress.certificate.issuerRef.name }} +{{- end }} diff --git a/.daystram/helm-chart/templates/service.yaml b/.daystram/helm-chart/templates/service.yaml index 1523de5..e2bc654 100644 --- a/.daystram/helm-chart/templates/service.yaml +++ b/.daystram/helm-chart/templates/service.yaml @@ -1,9 +1,10 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "ratify.fullname" . }} + name: {{ include "folio.fullname" . }}-fe labels: - {{- include "ratify.labels" . | nindent 4 }} + {{- include "folio.labels" . | nindent 4 }} + tier: fe spec: type: {{ .Values.service.type }} ports: @@ -12,4 +13,24 @@ spec: protocol: TCP name: http selector: - {{- include "ratify.selectorLabels" . | nindent 4 }} + {{- include "folio.selectorLabels" . | nindent 4 }} + tier: fe + +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "folio.fullname" . }}-be + labels: + {{- include "folio.labels" . | nindent 4 }} + tier: be +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "folio.selectorLabels" . | nindent 4 }} + tier: be diff --git a/.daystram/helm-chart/values.yaml b/.daystram/helm-chart/values.yaml index df40b33..2c519f8 100644 --- a/.daystram/helm-chart/values.yaml +++ b/.daystram/helm-chart/values.yaml @@ -2,21 +2,27 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. -replicaCount: 1 - image: - repository: nginx - pullPolicy: IfNotPresent + repository: daystram/ratify + pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. tag: "" +ratify: + be: + replicaCount: 1 + fe: + replicaCount: 1 + envFrom: + secretRef: secret-ratify-be + imagePullSecrets: [] nameOverride: "" fullnameOverride: "" serviceAccount: # Specifies whether a service account should be created - create: true + create: false # Annotations to add to the service account annotations: {} # The name of the service account to use. @@ -25,10 +31,12 @@ serviceAccount: podAnnotations: {} -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -41,19 +49,17 @@ service: port: 80 ingress: - enabled: false + enabled: true annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: chart-example.local - paths: [] - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local + host: ratify.daystram.com + tls: true + certificate: + issuerRef: + kind: ClusterIssuer + name: letsencrypt-prod -resources: {} +resources: + {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following From ec139dfc960d60ae0eda51415e0d360c1f42511d Mon Sep 17 00:00:00 2001 From: Danny August Ramaputra Date: Sun, 14 Feb 2021 14:28:11 +1000 Subject: [PATCH 4/6] ci: added helm deployment guide --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 22b8ff8..a41e46f 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,13 @@ [![Docker Pulls](https://img.shields.io/docker/pulls/daystram/ratify)](https://hub.docker.com/r/daystram/ratify) [![MIT License](https://img.shields.io/github/license/daystram/ratify)](https://github.com/daystram/ratify/blob/master/LICENSE) -__Ratify__ is a Central Authentication Service (CAS) implementing OAuth 2.0 and OpenID Connect (OID) protocols, as defined in [RFC 6749](https://tools.ietf.org/html/rfc6749). +**Ratify** is a Central Authentication Service (CAS) implementing OAuth 2.0 and OpenID Connect (OID) protocols, as defined in [RFC 6749](https://tools.ietf.org/html/rfc6749). ## Features + - Implements various authorization flows - Implements OpenID Connect protocol layer -- Register new applications to use __Ratify__ +- Register new applications to use **Ratify** - Manage registered users (with email verification) - Multi-factor authentication using Time-based One-Time Password (TOTP) - Universal login @@ -17,29 +18,36 @@ __Ratify__ is a Central Authentication Service (CAS) implementing OAuth 2.0 and - Active session management ## Supported Authorizaton Flows + - Authorization Code - Authorization Code with PKCE - _WIP: Client Credentials_ ## Client Libraries -Use the following libraries to easily integrate your application with __Ratify__'s authentication service. + +Use the following libraries to easily integrate your application with **Ratify**'s authentication service. + - JavaScript/TypeScript: [ratify-client-js](https://github.com/daystram/ratify-client-js) ## Services + The application comes in two parts: -|Name|Code Name|Stack| -|----|:-------:|-----| -|Back-end|`ratify-be`|[Go](https://golang.org/), [Gin](https://github.com/gin-gonic/gin) + [Gorm](https://github.com/go-gorm/gorm), [PostgreSQL](https://www.postgresql.org/), [Redis](https://redis.io/)| -|Front-end|`ratify-fe`|[TypeScript](https://www.typescriptlang.org/), [Vue.js](https://vuejs.org/)| +| Name | Code Name | Stack | +| --------- | :---------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Back-end | `ratify-be` | [Go](https://golang.org/), [Gin](https://github.com/gin-gonic/gin) + [Gorm](https://github.com/go-gorm/gorm), [PostgreSQL](https://www.postgresql.org/), [Redis](https://redis.io/) | +| Front-end | `ratify-fe` | [TypeScript](https://www.typescriptlang.org/), [Vue.js](https://vuejs.org/) | ## Develop + `ratify-fe` itself acts as stand-alone application to `ratify-be`, thus it utilizes an access token it self-issued via the _Authorization Code with PKCE_ flow to authenticate users. ### ratify-be + `ratify-be` uses [Go Modules](https://blog.golang.org/using-go-modules) module/dependency manager, hence at least Go 1.11 is required. To ease development, [comstrek/air](https://github.com/cosmtrek/air) is used to live-reload the application. Install the tool as documented. To begin developing, simply enter the sub-directory and run the development server: + ```shell $ cd ratify-be $ go mod tidy @@ -47,9 +55,11 @@ $ air ``` ### ratify-fe + Populate `.env.development` with the required credentials. Use the Client ID that `ratify-be` provides. To begin developing, simply enter the sub-directory and run the development server: + ```shell $ cd ratify-fe $ yarn @@ -57,28 +67,60 @@ $ yarn serve ``` ## Deploy + Both `ratify-be` and `ratify-fe` are containerized and pushed to [Docker Hub](https://hub.docker.com/r/daystram/ratify). They are tagged based on their application name and version, e.g. `daystram/ratify:be` or `daystram/ratify:be-v1.1.0`. To run `ratify-be`, run the following: + ```shell $ docker run --name ratify-be --env-file ./.env -p 8080:8080 -d daystram/ratify:be ``` And `ratify-fe` as follows: + ```shell $ docker run --name ratify-fe -p 80:80 -d daystram/ratify:fe ``` ### Dependencies + The following are required for `ratify-be` to function properly: + - PostgreSQL - Redis - SMTP Server Their credentials must be provided in the configuration file. +### Helm Chart + +To deploy to a Kubernetes cluster, Helm charts could be used. Add the [repository](https://charts.daystram.com): + +```shell +$ helm repo add daystram https://charts.daystram.com +$ helm repo update +``` + +Ensure you have the secrets created for `ratify-be` by providing the secret name in `values.yaml`, or creating the secret from a populated `.env` file (make sure it is on the same namespace as `ratify` installation): + +```shell +$ kubectl create secret generic secret-ratify-be --from-env-file=.env +``` + +And install `ratify`: + +```shell +$ helm install ratify daystram/ratify +``` + +You can override the chart values by providing a `values.yaml` file via the `--values` flag. + +Pre-release and development charts are accessible using the `--devel` flag. To isntall the development chart, provide the `--set image.tag=dev` flag, as development images are deployed with the suffix `dev`. + ### Docker Compose + For ease of deployment, the following `docker-compose.yml` file can be used to orchestrate the stack deployment: + ```yaml version: "3" services: @@ -109,10 +151,13 @@ services: ``` ### PostgreSQL UUID Extension + UUID support is also required in PostgreSQL. For modern PostgreSQL versions (9.1 and newer), the contrib module `uuid-ossp` can be enabled as follows: + ```sql CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; ``` ## License + This project is licensed under the [MIT License](./LICENSE). From 93daf83f754091829d0138d25de9007627e71e1d Mon Sep 17 00:00:00 2001 From: Danny August Ramaputra Date: Sun, 14 Feb 2021 15:01:07 +1000 Subject: [PATCH 5/6] ci: fixed application names --- .../helm-chart/templates/deployment.yaml | 20 +++++++++---------- .daystram/helm-chart/templates/ingress.yaml | 16 +++++++-------- .daystram/helm-chart/templates/service.yaml | 12 +++++------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.daystram/helm-chart/templates/deployment.yaml b/.daystram/helm-chart/templates/deployment.yaml index 3f34a92..382cb89 100644 --- a/.daystram/helm-chart/templates/deployment.yaml +++ b/.daystram/helm-chart/templates/deployment.yaml @@ -2,9 +2,9 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "folio.fullname" . }}-be + name: {{ include "ratify.fullname" . }}-be labels: - {{- include "folio.labels" . | nindent 4 }} + {{- include "ratify.labels" . | nindent 4 }} tier: be spec: {{- if not .Values.autoscaling.enabled }} @@ -12,7 +12,7 @@ spec: {{- end }} selector: matchLabels: - {{- include "folio.selectorLabels" . | nindent 6 }} + {{- include "ratify.selectorLabels" . | nindent 6 }} tier: be template: metadata: @@ -21,14 +21,14 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} labels: - {{- include "folio.selectorLabels" . | nindent 8 }} + {{- include "ratify.selectorLabels" . | nindent 8 }} tier: be spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - serviceAccountName: {{ include "folio.serviceAccountName" . }} + serviceAccountName: {{ include "ratify.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: @@ -63,9 +63,9 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "folio.fullname" . }}-fe + name: {{ include "ratify.fullname" . }}-fe labels: - {{- include "folio.labels" . | nindent 4 }} + {{- include "ratify.labels" . | nindent 4 }} tier: fe spec: {{- if not .Values.autoscaling.enabled }} @@ -73,7 +73,7 @@ spec: {{- end }} selector: matchLabels: - {{- include "folio.selectorLabels" . | nindent 6 }} + {{- include "ratify.selectorLabels" . | nindent 6 }} tier: fe template: metadata: @@ -82,14 +82,14 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} labels: - {{- include "folio.selectorLabels" . | nindent 8 }} + {{- include "ratify.selectorLabels" . | nindent 8 }} tier: fe spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - serviceAccountName: {{ include "folio.serviceAccountName" . }} + serviceAccountName: {{ include "ratify.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: diff --git a/.daystram/helm-chart/templates/ingress.yaml b/.daystram/helm-chart/templates/ingress.yaml index 3d0885d..a0dcae0 100644 --- a/.daystram/helm-chart/templates/ingress.yaml +++ b/.daystram/helm-chart/templates/ingress.yaml @@ -2,9 +2,9 @@ apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: {{ include "folio.fullname" . }} + name: {{ include "ratify.fullname" . }} labels: - {{- include "folio.labels" . | nindent 4 }} + {{- include "ratify.labels" . | nindent 4 }} {{- with .Values.ingress.annotations }} annotations: {{- toYaml . | nindent 4 }} @@ -16,7 +16,7 @@ spec: - kind: Rule match: "Host(`{{ .Values.ingress.host }}`)" services: - - name: {{ include "folio.fullname" . }}-fe + - name: {{ include "ratify.fullname" . }}-fe passHostHeader: true port: {{ .Values.service.port }} middlewares: @@ -24,20 +24,20 @@ spec: - kind: Rule match: "Host(`{{ .Values.ingress.host }}`) && PathPrefix(`/api`)" services: - - name: {{ include "folio.fullname" . }}-be + - name: {{ include "ratify.fullname" . }}-be passHostHeader: true port: {{ .Values.service.port }} - kind: Rule match: "Host(`{{ .Values.ingress.host }}`) && PathPrefix(`/oauth`)" services: - - name: {{ include "folio.fullname" . }}-be + - name: {{ include "ratify.fullname" . }}-be passHostHeader: true port: {{ .Values.service.port }} middlewares: - name: cors {{- if .Values.ingress.tls }} tls: - secretName: cert-{{ include "folio.fullname" . }} + secretName: cert-{{ include "ratify.fullname" . }} {{- end }} --- @@ -75,9 +75,9 @@ spec: apiVersion: cert-manager.io/v1alpha2 kind: Certificate metadata: - name: cert-{{ include "folio.fullname" . }} + name: cert-{{ include "ratify.fullname" . }} spec: - secretName: cert-{{ include "folio.fullname" . }} + secretName: cert-{{ include "ratify.fullname" . }} dnsNames: - {{ .Values.ingress.host }} issuerRef: diff --git a/.daystram/helm-chart/templates/service.yaml b/.daystram/helm-chart/templates/service.yaml index e2bc654..657ba4c 100644 --- a/.daystram/helm-chart/templates/service.yaml +++ b/.daystram/helm-chart/templates/service.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "folio.fullname" . }}-fe + name: {{ include "ratify.fullname" . }}-fe labels: - {{- include "folio.labels" . | nindent 4 }} + {{- include "ratify.labels" . | nindent 4 }} tier: fe spec: type: {{ .Values.service.type }} @@ -13,16 +13,16 @@ spec: protocol: TCP name: http selector: - {{- include "folio.selectorLabels" . | nindent 4 }} + {{- include "ratify.selectorLabels" . | nindent 4 }} tier: fe --- apiVersion: v1 kind: Service metadata: - name: {{ include "folio.fullname" . }}-be + name: {{ include "ratify.fullname" . }}-be labels: - {{- include "folio.labels" . | nindent 4 }} + {{- include "ratify.labels" . | nindent 4 }} tier: be spec: type: {{ .Values.service.type }} @@ -32,5 +32,5 @@ spec: protocol: TCP name: http selector: - {{- include "folio.selectorLabels" . | nindent 4 }} + {{- include "ratify.selectorLabels" . | nindent 4 }} tier: be From 151b00b6327583adfdaea258fd6d73173eafc48e Mon Sep 17 00:00:00 2001 From: Danny August Ramaputra Date: Sun, 14 Feb 2021 21:15:57 +1000 Subject: [PATCH 6/6] ci: fixed values envFrom --- .daystram/helm-chart/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.daystram/helm-chart/values.yaml b/.daystram/helm-chart/values.yaml index 2c519f8..534b3b1 100644 --- a/.daystram/helm-chart/values.yaml +++ b/.daystram/helm-chart/values.yaml @@ -11,10 +11,10 @@ image: ratify: be: replicaCount: 1 - fe: - replicaCount: 1 envFrom: secretRef: secret-ratify-be + fe: + replicaCount: 1 imagePullSecrets: [] nameOverride: ""