diff --git a/.drone.yml b/.drone.yml index be2f215..2a90fe9 100644 --- a/.drone.yml +++ b/.drone.yml @@ -4,7 +4,7 @@ kind: pipeline type: docker steps: -- name: publish +- name: Publish image: otwld/drone-chart-releaser-github-pages settings: cr_token: diff --git a/charts/clearport/.helmignore b/charts/clearport/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/clearport/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/clearport/Chart.yaml b/charts/clearport/Chart.yaml new file mode 100644 index 0000000..8dd5575 --- /dev/null +++ b/charts/clearport/Chart.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +appVersion: '1.0' +description: Yellow Clearport Chart +name: clearport +version: 1.1.0 diff --git a/charts/clearport/config/postgres-example.yaml b/charts/clearport/config/postgres-example.yaml new file mode 100644 index 0000000..5bd3459 --- /dev/null +++ b/charts/clearport/config/postgres-example.yaml @@ -0,0 +1,19 @@ +secrets: + DATABASE_DRIVER: postgres + DATABASE_HOST: + DATABASE_PORT: + DATABASE_USER: + DATABASE_PASS: + DATABASE_NAME: + DATABASE_SCHEMA: + +persistentVolume: + enabled: false + +hooks: + createDb: + enabled: true + createDbUser: + enabled: true + createDbSchema: + enabled: true diff --git a/charts/clearport/config/sqlite-example.yaml b/charts/clearport/config/sqlite-example.yaml new file mode 100644 index 0000000..c172a08 --- /dev/null +++ b/charts/clearport/config/sqlite-example.yaml @@ -0,0 +1,8 @@ +secrets: + DATABASE_DRIVER: sqlite + DATABASE_NAME: /data/sqlite.db + +persistentVolume: + enabled: true + mountPath: /data + size: 10Gi diff --git a/charts/clearport/config/testnet-kayen.yaml b/charts/clearport/config/testnet-kayen.yaml new file mode 100644 index 0000000..0f239ca --- /dev/null +++ b/charts/clearport/config/testnet-kayen.yaml @@ -0,0 +1,34 @@ +externalHostname: kayen-clearport.v4.uat.opendax.app +externalSecret: clearport-sec + +services: + peerGrpc: + nodePort: 31551 + +secrets: + TARGET_NETWORK: testnet + MARKET_PRICE_SOURCE: finex + DATABASE_DRIVER: postgres + DATABASE_HOST: postgresql.kayen-core + DATABASE_PORT: "5432" + DATABASE_USER: kayen_clearport + DATABASE_PASS: YzU1Yzc5MGNhMzcx + DATABASE_NAME: kayen_clearport + DATABASE_SCHEMA: public + +persistentVolume: + enabled: false + +hooks: + createDb: + enabled: true + createDbUser: + enabled: true + createDbSchema: + enabled: true + addOperator: + enabled: true + +responderMode: + enabled: true + name: Kayen diff --git a/charts/clearport/config/testnet-terminal.yaml b/charts/clearport/config/testnet-terminal.yaml new file mode 100644 index 0000000..d19c6d1 --- /dev/null +++ b/charts/clearport/config/testnet-terminal.yaml @@ -0,0 +1,28 @@ +externalHostname: terminal-clearport.v4.uat.opendax.app +externalSecret: clearport-sec + +services: + peerGrpc: + nodePort: 31561 + +secrets: + TARGET_NETWORK: testnet + MARKET_PRICE_SOURCE: finex + DATABASE_DRIVER: postgres + DATABASE_HOST: postgresql.kayen-core + DATABASE_PORT: "5432" + DATABASE_USER: terminal_clearport + DATABASE_PASS: YTU3ZDhmZjNjYzZk + DATABASE_NAME: terminal_clearport + DATABASE_SCHEMA: public + +persistentVolume: + enabled: false + +hooks: + createDb: + enabled: true + createDbUser: + enabled: true + createDbSchema: + enabled: true diff --git a/charts/clearport/templates/config-cm.yaml b/charts/clearport/templates/config-cm.yaml new file mode 100644 index 0000000..92e5e2b --- /dev/null +++ b/charts/clearport/templates/config-cm.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "component.fullname" . }}-config + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation + "helm.sh/hook-weight": "-1" +data: + config.yaml: |- + {{- .Values.config | nindent 4 }} diff --git a/charts/clearport/templates/deployment.yaml b/charts/clearport/templates/deployment.yaml new file mode 100644 index 0000000..8eee3a3 --- /dev/null +++ b/charts/clearport/templates/deployment.yaml @@ -0,0 +1,78 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "component.fullname" . }} + labels: + {{- include "component.labels" . | nindent 4 }} +spec: + {{- include "component.replicaCount" . | nindent 2 }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "component.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "component.metricsAnnotations" .Values.metrics | nindent 8 }} + checksum/config: {{ include (print $.Template.BasePath "/config-cm.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + {{- if .Values.extraLabels }} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + spec: + containers: + - name: clearport + image: {{ include "component.image" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["clearport", "start", "app"] + env: + {{- with .Values.services.operatorWs }} + - name: OPERATOR_WS_ADDR + value: {{ default .port .internalPort | print | printf ":%s" }} + {{- end }} + {{- with .Values.services.operatorGrpc }} + - name: OPERATOR_GRPC_PORT + value: {{ default .port .internalPort | print | printf ":%s" }} + {{- end }} + {{- with .Values.services.peerGrpc }} + - name: PEER_URL + value: {{ default .port .internalPort | print | printf "http://%s:%s" $.Values.externalHostname }} + {{- end }} + - name: CHANNEL_SEND_TRANSACTIONS + value: {{ .Values.responderMode.enabled | quote }} + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + {{- if .Values.persistentVolume.enabled }} + - name: pv + mountPath: {{ .Values.persistentVolume.mountPath }} + {{- end }} + {{- include "component.resources" . | nindent 10 }} + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + {{- with .Values.persistentVolume.enabled }} + - name: pv + persistentVolumeClaim: + claimName: {{ include "component.fullname" $ }} + {{- end }} + {{- include "component.imagePullSecrets" . | nindent 6 }} + {{- include "component.nodeSelectorLabels" . | nindent 6 }} + {{- include "component.affinity" . | nindent 6 }} + {{- include "component.tolerations" . | nindent 6 }} diff --git a/charts/clearport/templates/helpers/component.tpl b/charts/clearport/templates/helpers/component.tpl new file mode 100644 index 0000000..c8e13aa --- /dev/null +++ b/charts/clearport/templates/helpers/component.tpl @@ -0,0 +1,169 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "component.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 "component.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 }} + +{{/* +Selector labels +*/}} +{{- define "component.selectorLabels" -}} +app: {{ include "component.name" . }} +app.kubernetes.io/name: {{ include "component.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "component.labels" -}} +helm.sh/chart: {{ include "component.chart" . }} +{{ include "component.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "component.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Returns Prometheus metrics' annotations depending on input Values +*/}} +{{- define "component.metricsAnnotations" -}} +prometheus.io/scrape: {{ default false .enabled | print | quote }} +prometheus.io/port: {{ default 4242 .port | print | quote }} +prometheus.io/path: {{ default "/metrics" .endpoint | print | quote }} +{{- end }} + +{{/* +Returns replica count depending on global Values and HPA settings +*/}} +{{- define "component.replicaCount" -}} +{{- if not (and .Values.autoscaling .Values.autoscaling.enabled) }} +{{- if and .Values.profile.enabled }} +replicas: {{ get .Values.profile.replicas .Chart.Name }} +{{- else }} +replicas: {{ .Values.replicaCount }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Returns full docker image name +*/}} +{{- define "component.image" -}} +{{ printf "%s:%s" (print .repository) (print .tag) }} +{{- end }} + +{{/* +Returns container ports configuration depending on input service +*/}} +{{- define "component.port" -}} +- name: {{ .name }} + containerPort: {{ default .port .internalPort }} + protocol: TCP +{{- end }} + +{{/* +Returns component's resource consumption +*/}} +{{- define "component.resources" -}} +{{- if .Values.profile.enabled }} +{{- with .Values.profile }} +resources: + {{- with .requests }} + requests: + cpu: {{ .cpu }} + memory: {{ .memory }} + {{- end }} + {{- with .limits }} + limits: + cpu: {{ .cpu }} + memory: {{ .memory }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Returns component's probes +*/}} +{{- define "component.probes" -}} +{{- $svc := get .Values.services .subservice }} +{{- $port := default $svc.port $svc.internalPort }} +{{- range $name, $probe := .Values.probes }} +{{ printf "%sProbe" $name }}: + httpGet: + path: {{ default "/health" $probe.path }} + port: {{ default $port $probe.port }} + initialDelaySeconds: {{ default 5 $probe.initialDelaySeconds }} + timeoutSeconds: {{ default 10 $probe.timeoutSeconds }} + periodSeconds: {{ default 10 $probe.periodSeconds }} +{{- end }} +{{- end }} + +{{/* +Returns personal and global component's image pull secrets +*/}} +{{- define "component.imagePullSecrets" -}} +imagePullSecrets: +{{- if .Values.image.pullSecret }} +- name: {{ .Values.image.pullSecret }} +{{- end }} +{{- end }} + +{{/* +Returns personal and global component's node selector labels +*/}} +{{- define "component.nodeSelectorLabels" -}} +nodeSelector: + {{- if .Values.nodeSelector }} + {{ toYaml .Values.nodeSelector | nindent 2 }} + {{- end }} +{{- end }} + +{{/* +Returns personal and global component's tolerations +*/}} +{{- define "component.tolerations" -}} +tolerations: +{{- if .Values.tolerations }} +{{ toYaml .Values.tolerations }} +{{- end }} +{{- end }} + +{{/* +Returns component pod's affinity +*/}} +{{- define "component.affinity" -}} +affinity: + {{- if .Values.affinity }} + {{ toYaml .Values.affinity | nindent 2 }} + {{- end }} +{{- end }} diff --git a/charts/clearport/templates/helpers/ingress.tpl b/charts/clearport/templates/helpers/ingress.tpl new file mode 100644 index 0000000..6392f04 --- /dev/null +++ b/charts/clearport/templates/helpers/ingress.tpl @@ -0,0 +1,60 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns Ingress API version depending on K8s cluster version +*/}} +{{- define "ingress.apiVersion" -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version -}} +networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.Version -}} +networking.k8s.io/v1beta1 +{{- else -}} +extensions/v1beta1 +{{- end }} +{{- end }} + +{{/* +Returns default Ingress annotations +*/}} +{{- define "ingress.defaultAnnotations" -}} +kubernetes.io/ingress.class: nginx +kubernetes.io/tls-acme: "true" +cert-manager.io/cluster-issuer: "{{ .Values.tlsClusterIssuer }}" +{{- end }} + +{{/* +Returns Ingress TLS configuration +*/}} +{{- define "ingress.tls" -}} +{{- if .Values.ingress.tls.enabled }} +{{- if not .hosts }} +{{- $_ := set . "hosts" (list .Values.externalHostname) }} +{{- end }} +tls: + {{- range $host := .hosts }} + - secretName: "{{ $host | replace "." "-" }}-tls" + hosts: + - "{{ $host }}" + {{- end }} +{{- end }} +{{- end }} + +{{/* +Returns Ingress host path configuration +*/}} +{{- define "ingress.path" -}} +- path: {{ default .Values.ingress.path .path }} + {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.Version }} + pathType: Prefix + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- $svc := .service }} + service: + name: {{ $svc.name }} + port: + number: {{ default $svc.port $svc.internalPort }} + {{- else }} + serviceName: {{ $svc.name }} + servicePort: {{ default $svc.port $svc.internalPort }} + {{- end }} +{{- end }} diff --git a/charts/clearport/templates/helpers/job.tpl b/charts/clearport/templates/helpers/job.tpl new file mode 100644 index 0000000..a1dd7d3 --- /dev/null +++ b/charts/clearport/templates/helpers/job.tpl @@ -0,0 +1,31 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns Cron Job API version depending on K8s cluster version +*/}} +{{- define "cronjob.apiVersion" -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version -}} +batch/v1 +{{- else -}} +batch/v1beta1 +{{- end }} +{{- end }} + +{{/* +Returns env mapping from Secret +*/}} +{{- define "hook.secretEnvs" -}} +{{- $hook := get .Values.hooks .hookName }} +{{- range $secret := $hook.secrets }} +{{- range $env, $rename := $secret.envs }} +- name: {{ default $env $rename }} + valueFrom: + secretKeyRef: + {{- if $secret.this_release }} + name: {{ printf "%s-%s" (include "component.fullname" $) $secret.name }} + {{- else }} + name: {{ $secret.name }} + {{- end }} + key: {{ $env }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/clearport/templates/helpers/service.tpl b/charts/clearport/templates/helpers/service.tpl new file mode 100644 index 0000000..1bcd6b8 --- /dev/null +++ b/charts/clearport/templates/helpers/service.tpl @@ -0,0 +1,17 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns service ports configuration depending on input service +*/}} +{{- define "service.port" -}} +- name: {{ kebabcase .name }} + {{- if eq .type "NodePort" }} + port: {{ default .port .internalPort }} + {{- if .nodePort }} + nodePort: {{ .nodePort }} + {{- end }} + {{- else }} + port: {{ default .port .externalPort }} + {{- end }} + targetPort: {{ default .port .internalPort }} + protocol: TCP +{{- end }} diff --git a/charts/clearport/templates/hooks/add-operator.yaml b/charts/clearport/templates/hooks/add-operator.yaml new file mode 100644 index 0000000..51d306b --- /dev/null +++ b/charts/clearport/templates/hooks/add-operator.yaml @@ -0,0 +1,57 @@ +{{- $_ := set . "hookName" "addOperator"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "4" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + {{- if .Values.extraLabels }} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" .Values.image }} + command: ["clearport", "operator", "add", "-n", "{{ .Values.responderMode.name }}"] + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + {{- if .Values.persistentVolume.enabled }} + - name: pv + mountPath: {{ .Values.persistentVolume.mountPath }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + {{- with .Values.persistentVolume.enabled }} + - name: pv + persistentVolumeClaim: + claimName: {{ include "component.fullname" $ }} + {{- end }} + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/clearport/templates/hooks/create-db-schema.yaml b/charts/clearport/templates/hooks/create-db-schema.yaml new file mode 100644 index 0000000..9df2fdf --- /dev/null +++ b/charts/clearport/templates/hooks/create-db-schema.yaml @@ -0,0 +1,45 @@ +{{- $_ := set . "hookName" "createDbSchema"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "2" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" .Values.image }} + command: ["clearport", "db", "create"] + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/clearport/templates/hooks/create-db-user.yaml b/charts/clearport/templates/hooks/create-db-user.yaml new file mode 100644 index 0000000..c86914f --- /dev/null +++ b/charts/clearport/templates/hooks/create-db-user.yaml @@ -0,0 +1,41 @@ +{{- $_ := set . "hookName" "createDbUser"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "1" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + args: + - /bin/sh + - -exc + - | + echo " + CREATE USER ${DB_USER} WITH LOGIN ENCRYPTED PASSWORD '${DB_PASS}'; + GRANT CREATE ON DATABASE ${DB_NAME} TO ${DB_USER}; + + CREATE EXTENSION IF NOT EXISTS pg_cron; + SELECT cron.schedule_in_database(job_name:='cleanup_closed_orders', schedule:='0 2 * * *', command:='SELECT ${DB_SCHEMA}.cleanup_closed_orders(1000)',database:='${DB_NAME}',username:='${DB_USER}'); + SELECT cron.schedule_in_database(job_name:='compact_orders', schedule:='0 2 * * *', command:='SELECT ${DB_SCHEMA}.compact_orders((current_date - interval ''14 days'')::date, (current_date - interval ''7 days'')::date)',database:='${DB_NAME}',username:='${DB_USER}'); + UPDATE cron.job SET nodename = ''; + " | psql -v ON_ERROR_STOP=ON + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/clearport/templates/hooks/create-db.yaml b/charts/clearport/templates/hooks/create-db.yaml new file mode 100644 index 0000000..db3015c --- /dev/null +++ b/charts/clearport/templates/hooks/create-db.yaml @@ -0,0 +1,33 @@ +{{- $_ := set . "hookName" "createDb"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "0" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + args: + - /bin/sh + - -exc + - | + echo "CREATE DATABASE ${DB_NAME}" | psql -v ON_ERROR_STOP=ON + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/clearport/templates/hooks/migrate-db.yaml b/charts/clearport/templates/hooks/migrate-db.yaml new file mode 100644 index 0000000..44ea06c --- /dev/null +++ b/charts/clearport/templates/hooks/migrate-db.yaml @@ -0,0 +1,57 @@ +{{- $_ := set . "hookName" "migrateDb"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install, pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "3" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + {{- if .Values.extraLabels }} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" .Values.image }} + command: ["clearport", "db", "migrate"] + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + {{- if .Values.persistentVolume.enabled }} + - name: pv + mountPath: {{ .Values.persistentVolume.mountPath }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + {{- with .Values.persistentVolume.enabled }} + - name: pv + persistentVolumeClaim: + claimName: {{ include "component.fullname" $ }} + {{- end }} + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/clearport/templates/hooks/pvc.yaml b/charts/clearport/templates/hooks/pvc.yaml new file mode 100644 index 0000000..7fca366 --- /dev/null +++ b/charts/clearport/templates/hooks/pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.persistentVolume.enabled -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "component.fullname" . }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/resource-policy": keep + "helm.sh/hook-weight": "0" +spec: + accessModes: + - ReadWriteOnce + storageClassName: local-path + resources: + requests: + storage: {{ .Values.persistentVolume.size }} +{{- end }} diff --git a/charts/clearport/templates/secret.yaml b/charts/clearport/templates/secret.yaml new file mode 100644 index 0000000..89c2d04 --- /dev/null +++ b/charts/clearport/templates/secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "component.fullname" . }}-opt-env + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install, pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation + "helm.sh/hook-weight": "-1" +data: +{{- range $key, $value := .Values.secrets }} + {{- $key | nindent 2 }}: {{ $value | print | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/clearport/templates/services.yaml b/charts/clearport/templates/services.yaml new file mode 100644 index 0000000..0994374 --- /dev/null +++ b/charts/clearport/templates/services.yaml @@ -0,0 +1,16 @@ +{{- range $name, $svc := .Values.services }} +{{- $svc = set $svc "name" $name }} +--- +apiVersion: v1 +kind: Service +metadata: + name: "{{ include "component.fullname" $ }}-{{ kebabcase $svc.name }}" + labels: + {{- include "component.labels" $ | nindent 4 }} +spec: + type: {{ default "ClusterIP" $svc.type }} + ports: + {{- include "service.port" $svc | nindent 4 }} + selector: + {{- include "component.selectorLabels" $ | nindent 4 }} +{{- end }} diff --git a/charts/clearport/templates/ws-ingress.yaml b/charts/clearport/templates/ws-ingress.yaml new file mode 100644 index 0000000..8133467 --- /dev/null +++ b/charts/clearport/templates/ws-ingress.yaml @@ -0,0 +1,19 @@ +{{- if .Values.ingress.enabled }} +apiVersion: {{ include "ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "component.fullname" . }}-ws + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + {{- include "ingress.defaultAnnotations" . | nindent 4 }} +spec: + {{- $svc := set .Values.services.operatorWs "name" (printf "%s-operator-ws" (include "component.fullname" .)) }} + {{- $root := set . "service" $svc }} + rules: + - host: {{ .Values.externalHostname }} + http: + paths: + {{- include "ingress.path" $root | nindent 10 }} + {{- include "ingress.tls" $root | nindent 2 }} +{{- end }} diff --git a/charts/clearport/values.yaml b/charts/clearport/values.yaml new file mode 100644 index 0000000..f5f3dbc --- /dev/null +++ b/charts/clearport/values.yaml @@ -0,0 +1,122 @@ +replicaCount: 1 + +image: + repository: quay.io/openware/clearport + tag: 0.1.7 + pullPolicy: IfNotPresent + pullSecret: openware-quay + +metrics: + port: 8080 + enabled: false + endpoint: "/metrics" + +fullnameOverride: "" +nameOverride: "" + +secrets: + LOG_LEVEL: debug + MARKET_PRICE_SOURCE: binance +externalSecret: clearport-sec + +config: "" + +hooks: + createDb: + enabled: false + image: + repository: postgres + tag: 13.7-alpine + secrets: + - name: db-credentials + envs: + DATABASE_ROOT_USER: PGUSER + DATABASE_ROOT_PASSWORD: PGPASSWORD + - name: opt-env + this_release: true + envs: + DATABASE_NAME: DB_NAME + DATABASE_HOST: PGHOST + DATABASE_PORT: PGPORT + createDbUser: + enabled: false + image: + repository: postgres + tag: 13.7-alpine + secrets: + - name: db-credentials + envs: + DATABASE_ROOT_USER: PGUSER + DATABASE_ROOT_PASSWORD: PGPASSWORD + - name: opt-env + this_release: true + envs: + DATABASE_USER: DB_USER + DATABASE_PASS: DB_PASS + DATABASE_NAME: DB_NAME + DATABASE_SCHEMA: DB_SCHEMA + DATABASE_HOST: PGHOST + DATABASE_PORT: PGPORT + createDbSchema: + enabled: false + migrateDb: + enabled: true + addOperator: + enabled: false + +services: + operatorWs: + port: 8080 + operatorGrpc: + port: 50080 + # nodePort: 30050 + peerGrpc: + type: NodePort + port: 50081 + nodePort: 30051 + +externalHostname: clearport.v4.uat.opendax.app +tlsClusterIssuer: letsencrypt-prod + +ingress: + enabled: true + path: / + tls: + enabled: true + +persistentVolume: + enabled: false + mountPath: /data + size: 10Gi + +responderMode: + enabled: false + name: responder + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +profile: + enabled: false + # requests: + # cpu: 100m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + +probes: + readiness: {} + liveness: {} + +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +extraLabels: {} diff --git a/charts/neodax/.helmignore b/charts/neodax/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/neodax/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/neodax/Chart.yaml b/charts/neodax/Chart.yaml new file mode 100644 index 0000000..60611a7 --- /dev/null +++ b/charts/neodax/Chart.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +appVersion: '1.0' +description: NeoDax Helm Chart +name: neodax +version: 1.0.0 diff --git a/charts/neodax/templates/config-cm.yaml b/charts/neodax/templates/config-cm.yaml new file mode 100644 index 0000000..da9e62c --- /dev/null +++ b/charts/neodax/templates/config-cm.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "component.fullname" . }}-config + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation + "helm.sh/hook-weight": "-1" +data: + finex.yaml: |- + {{- .Values.config | nindent 4 }} diff --git a/charts/neodax/templates/deployment.yaml b/charts/neodax/templates/deployment.yaml new file mode 100644 index 0000000..ae38a44 --- /dev/null +++ b/charts/neodax/templates/deployment.yaml @@ -0,0 +1,59 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "component.fullname" . }} + labels: + {{- include "component.labels" . | nindent 4 }} +spec: + {{- include "component.replicaCount" . | nindent 2 }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "component.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "component.metricsAnnotations" .Values.metrics | nindent 8 }} + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + {{- if .Values.extraLabels }} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + spec: + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + containers: + - name: finex + image: {{ include "component.image" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["finex", "engine"] + env: + {{- with .Values.services.ws }} + - name: FINEX_WS_PORT + value: {{ default .port .internalPort | quote }} + {{- end }} + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + {{- include "component.resources" . | nindent 10 }} + {{- $root := set . "subservice" "ws"}} + {{- include "component.probes" $root | nindent 10 }} + {{- include "component.imagePullSecrets" . | nindent 6 }} + {{- include "component.nodeSelectorLabels" . | nindent 6 }} + {{- include "component.affinity" . | nindent 6 }} + {{- include "component.tolerations" . | nindent 6 }} diff --git a/charts/neodax/templates/helpers/component.tpl b/charts/neodax/templates/helpers/component.tpl new file mode 100644 index 0000000..c8e13aa --- /dev/null +++ b/charts/neodax/templates/helpers/component.tpl @@ -0,0 +1,169 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "component.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 "component.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 }} + +{{/* +Selector labels +*/}} +{{- define "component.selectorLabels" -}} +app: {{ include "component.name" . }} +app.kubernetes.io/name: {{ include "component.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "component.labels" -}} +helm.sh/chart: {{ include "component.chart" . }} +{{ include "component.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "component.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Returns Prometheus metrics' annotations depending on input Values +*/}} +{{- define "component.metricsAnnotations" -}} +prometheus.io/scrape: {{ default false .enabled | print | quote }} +prometheus.io/port: {{ default 4242 .port | print | quote }} +prometheus.io/path: {{ default "/metrics" .endpoint | print | quote }} +{{- end }} + +{{/* +Returns replica count depending on global Values and HPA settings +*/}} +{{- define "component.replicaCount" -}} +{{- if not (and .Values.autoscaling .Values.autoscaling.enabled) }} +{{- if and .Values.profile.enabled }} +replicas: {{ get .Values.profile.replicas .Chart.Name }} +{{- else }} +replicas: {{ .Values.replicaCount }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Returns full docker image name +*/}} +{{- define "component.image" -}} +{{ printf "%s:%s" (print .repository) (print .tag) }} +{{- end }} + +{{/* +Returns container ports configuration depending on input service +*/}} +{{- define "component.port" -}} +- name: {{ .name }} + containerPort: {{ default .port .internalPort }} + protocol: TCP +{{- end }} + +{{/* +Returns component's resource consumption +*/}} +{{- define "component.resources" -}} +{{- if .Values.profile.enabled }} +{{- with .Values.profile }} +resources: + {{- with .requests }} + requests: + cpu: {{ .cpu }} + memory: {{ .memory }} + {{- end }} + {{- with .limits }} + limits: + cpu: {{ .cpu }} + memory: {{ .memory }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Returns component's probes +*/}} +{{- define "component.probes" -}} +{{- $svc := get .Values.services .subservice }} +{{- $port := default $svc.port $svc.internalPort }} +{{- range $name, $probe := .Values.probes }} +{{ printf "%sProbe" $name }}: + httpGet: + path: {{ default "/health" $probe.path }} + port: {{ default $port $probe.port }} + initialDelaySeconds: {{ default 5 $probe.initialDelaySeconds }} + timeoutSeconds: {{ default 10 $probe.timeoutSeconds }} + periodSeconds: {{ default 10 $probe.periodSeconds }} +{{- end }} +{{- end }} + +{{/* +Returns personal and global component's image pull secrets +*/}} +{{- define "component.imagePullSecrets" -}} +imagePullSecrets: +{{- if .Values.image.pullSecret }} +- name: {{ .Values.image.pullSecret }} +{{- end }} +{{- end }} + +{{/* +Returns personal and global component's node selector labels +*/}} +{{- define "component.nodeSelectorLabels" -}} +nodeSelector: + {{- if .Values.nodeSelector }} + {{ toYaml .Values.nodeSelector | nindent 2 }} + {{- end }} +{{- end }} + +{{/* +Returns personal and global component's tolerations +*/}} +{{- define "component.tolerations" -}} +tolerations: +{{- if .Values.tolerations }} +{{ toYaml .Values.tolerations }} +{{- end }} +{{- end }} + +{{/* +Returns component pod's affinity +*/}} +{{- define "component.affinity" -}} +affinity: + {{- if .Values.affinity }} + {{ toYaml .Values.affinity | nindent 2 }} + {{- end }} +{{- end }} diff --git a/charts/neodax/templates/helpers/ingress.tpl b/charts/neodax/templates/helpers/ingress.tpl new file mode 100644 index 0000000..6392f04 --- /dev/null +++ b/charts/neodax/templates/helpers/ingress.tpl @@ -0,0 +1,60 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns Ingress API version depending on K8s cluster version +*/}} +{{- define "ingress.apiVersion" -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version -}} +networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.Version -}} +networking.k8s.io/v1beta1 +{{- else -}} +extensions/v1beta1 +{{- end }} +{{- end }} + +{{/* +Returns default Ingress annotations +*/}} +{{- define "ingress.defaultAnnotations" -}} +kubernetes.io/ingress.class: nginx +kubernetes.io/tls-acme: "true" +cert-manager.io/cluster-issuer: "{{ .Values.tlsClusterIssuer }}" +{{- end }} + +{{/* +Returns Ingress TLS configuration +*/}} +{{- define "ingress.tls" -}} +{{- if .Values.ingress.tls.enabled }} +{{- if not .hosts }} +{{- $_ := set . "hosts" (list .Values.externalHostname) }} +{{- end }} +tls: + {{- range $host := .hosts }} + - secretName: "{{ $host | replace "." "-" }}-tls" + hosts: + - "{{ $host }}" + {{- end }} +{{- end }} +{{- end }} + +{{/* +Returns Ingress host path configuration +*/}} +{{- define "ingress.path" -}} +- path: {{ default .Values.ingress.path .path }} + {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.Version }} + pathType: Prefix + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- $svc := .service }} + service: + name: {{ $svc.name }} + port: + number: {{ default $svc.port $svc.internalPort }} + {{- else }} + serviceName: {{ $svc.name }} + servicePort: {{ default $svc.port $svc.internalPort }} + {{- end }} +{{- end }} diff --git a/charts/neodax/templates/helpers/job.tpl b/charts/neodax/templates/helpers/job.tpl new file mode 100644 index 0000000..a1dd7d3 --- /dev/null +++ b/charts/neodax/templates/helpers/job.tpl @@ -0,0 +1,31 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns Cron Job API version depending on K8s cluster version +*/}} +{{- define "cronjob.apiVersion" -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version -}} +batch/v1 +{{- else -}} +batch/v1beta1 +{{- end }} +{{- end }} + +{{/* +Returns env mapping from Secret +*/}} +{{- define "hook.secretEnvs" -}} +{{- $hook := get .Values.hooks .hookName }} +{{- range $secret := $hook.secrets }} +{{- range $env, $rename := $secret.envs }} +- name: {{ default $env $rename }} + valueFrom: + secretKeyRef: + {{- if $secret.this_release }} + name: {{ printf "%s-%s" (include "component.fullname" $) $secret.name }} + {{- else }} + name: {{ $secret.name }} + {{- end }} + key: {{ $env }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/neodax/templates/helpers/main.tpl b/charts/neodax/templates/helpers/main.tpl new file mode 100644 index 0000000..7d265d9 --- /dev/null +++ b/charts/neodax/templates/helpers/main.tpl @@ -0,0 +1,36 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Kong Service Name +*/}} +{{- define "main.kongSvcName" -}} +{{- printf "%s-%s-%s" .Release.Name .Values.global.kong.nameOverride .Values.global.kong.svcType }} +{{- end }} + +{{/* +Secret environment variable template +with opendax-global Secret backwards compatibility +*/}} +{{- define "main.opendaxGlobalVarReplace" -}} +- name: {{ default .name .nameOverride }} + valueFrom: + secretKeyRef: + {{- if eq (default "vault" .Values.global.kaigara.storageDriver) "k8s" }} + name: {{ printf "kaigara-%s" .secretApp }} + key: {{ .name }} + {{- else }} + name: {{ .Values.global.secretPrefix }}-global + key: {{ .key }} + {{- end }} +{{- end }} + +{{/* +Returns pod annotations snippet depending on input Values +*/}} +{{- define "main.withGlobalAnnotations" -}} +{{- range $key, $value := .Values.global.podAnnotations }} +{{ printf "\"%s\": \"%s\"" $key (print $value) }} +{{- end }} +{{- range $key, $value := .Values.podAnnotations }} +{{ printf "\"%s\": \"%s\"" $key (print $value) }} +{{- end }} +{{- end }} diff --git a/charts/neodax/templates/helpers/service.tpl b/charts/neodax/templates/helpers/service.tpl new file mode 100644 index 0000000..e091fee --- /dev/null +++ b/charts/neodax/templates/helpers/service.tpl @@ -0,0 +1,17 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns service ports configuration depending on input service +*/}} +{{- define "service.port" -}} +- name: {{ .name }} + {{- if eq .type "NodePort" }} + port: {{ default .port .internalPort }} + {{- if .nodePort }} + nodePort: {{ .nodePort }} + {{- end }} + {{- else }} + port: {{ default .port .externalPort }} + {{- end }} + targetPort: {{ default .port .internalPort }} + protocol: TCP +{{- end }} diff --git a/charts/neodax/templates/hooks/create-db-schema.yaml b/charts/neodax/templates/hooks/create-db-schema.yaml new file mode 100644 index 0000000..818a547 --- /dev/null +++ b/charts/neodax/templates/hooks/create-db-schema.yaml @@ -0,0 +1,45 @@ +{{- $_ := set . "hookName" "createDbSchema"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "2" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" .Values.image }} + command: ["finex", "db", "create"] + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/neodax/templates/hooks/create-db-user.yaml b/charts/neodax/templates/hooks/create-db-user.yaml new file mode 100644 index 0000000..c86914f --- /dev/null +++ b/charts/neodax/templates/hooks/create-db-user.yaml @@ -0,0 +1,41 @@ +{{- $_ := set . "hookName" "createDbUser"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "1" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + args: + - /bin/sh + - -exc + - | + echo " + CREATE USER ${DB_USER} WITH LOGIN ENCRYPTED PASSWORD '${DB_PASS}'; + GRANT CREATE ON DATABASE ${DB_NAME} TO ${DB_USER}; + + CREATE EXTENSION IF NOT EXISTS pg_cron; + SELECT cron.schedule_in_database(job_name:='cleanup_closed_orders', schedule:='0 2 * * *', command:='SELECT ${DB_SCHEMA}.cleanup_closed_orders(1000)',database:='${DB_NAME}',username:='${DB_USER}'); + SELECT cron.schedule_in_database(job_name:='compact_orders', schedule:='0 2 * * *', command:='SELECT ${DB_SCHEMA}.compact_orders((current_date - interval ''14 days'')::date, (current_date - interval ''7 days'')::date)',database:='${DB_NAME}',username:='${DB_USER}'); + UPDATE cron.job SET nodename = ''; + " | psql -v ON_ERROR_STOP=ON + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/neodax/templates/hooks/create-db.yaml b/charts/neodax/templates/hooks/create-db.yaml new file mode 100644 index 0000000..db3015c --- /dev/null +++ b/charts/neodax/templates/hooks/create-db.yaml @@ -0,0 +1,33 @@ +{{- $_ := set . "hookName" "createDb"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "0" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + args: + - /bin/sh + - -exc + - | + echo "CREATE DATABASE ${DB_NAME}" | psql -v ON_ERROR_STOP=ON + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/neodax/templates/hooks/drop-db-user.yaml b/charts/neodax/templates/hooks/drop-db-user.yaml new file mode 100644 index 0000000..4a71390 --- /dev/null +++ b/charts/neodax/templates/hooks/drop-db-user.yaml @@ -0,0 +1,45 @@ +{{- $_ := set . "hookName" "dropDbUser"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if and $hook.enabled .Values.cleanupHooksEnabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "1" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + args: + - /bin/sh + - -exc + - | + echo " + DO \$\$ + DECLARE + id bigint; + BEGIN + select jobid into id from cron.job where database = '${DB_NAME}' and jobname = 'cleanup_closed_orders'; + PERFORM cron.unschedule(id); + select jobid into id from cron.job where database = '${DB_NAME}' and jobname = 'compact_orders'; + PERFORM cron.unschedule(id); + END \$\$; + + DROP USER ${DB_USER}; + " | psql -v ON_ERROR_STOP=ON + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/neodax/templates/hooks/drop-db.yaml b/charts/neodax/templates/hooks/drop-db.yaml new file mode 100644 index 0000000..5f871e2 --- /dev/null +++ b/charts/neodax/templates/hooks/drop-db.yaml @@ -0,0 +1,40 @@ +{{- $_ := set . "hookName" "dropDb"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if and $hook.enabled .Values.cleanupHooksEnabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "0" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + args: + - /bin/sh + - -exc + - | + echo " + SELECT pg_terminate_backend(pg_stat_activity.pid) + FROM pg_stat_activity + WHERE pg_stat_activity.datname = '${DB_NAME}' + AND pid <> pg_backend_pid(); + " | psql -v ON_ERROR_STOP=ON + + echo "DROP DATABASE ${DB_NAME}" | psql -v ON_ERROR_STOP=ON + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/neodax/templates/hooks/migrate-db-schema.yml b/charts/neodax/templates/hooks/migrate-db-schema.yml new file mode 100644 index 0000000..8b72e22 --- /dev/null +++ b/charts/neodax/templates/hooks/migrate-db-schema.yml @@ -0,0 +1,48 @@ +{{- $_ := set . "hookName" "migrateDbSchema"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install, pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-weight": "3" +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + {{- if .Values.extraLabels }} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" .Values.image }} + command: ["finex", "db", "migrate"] + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: {{ include "component.fullname" . }}-config + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/charts/neodax/templates/hooks/seed-influx-db.yaml b/charts/neodax/templates/hooks/seed-influx-db.yaml new file mode 100644 index 0000000..d9e7b30 --- /dev/null +++ b/charts/neodax/templates/hooks/seed-influx-db.yaml @@ -0,0 +1,45 @@ +{{- $_ := set . "hookName" "seedInfluxDb"}} +{{- $hook := get .Values.hooks .hookName }} +{{- if $hook.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{ include "component.fullname" . }}-{{ kebabcase .hookName }}" + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ kebabcase .hookName }} + image: {{ include "component.image" $hook.image }} + env: + {{- include "hook.secretEnvs" . | nindent 10 }} + command: + - sh + - -ec + - | + hosts=$(echo $INFLUXDB_HOSTS | tr "," "\n") + + echo "Seeding InfluxDB..."; + for host in $hosts + do + cat /opt/seed/schema.sql | influx -host $host; + done + volumeMounts: + - name: schema-seed + mountPath: /opt/seed + volumes: + - name: schema-seed + configMap: + name: {{ include "component.fullname" . }}-influxdb-seed-schema + {{- include "component.imagePullSecrets" . | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/charts/neodax/templates/influx-cm.yaml b/charts/neodax/templates/influx-cm.yaml new file mode 100644 index 0000000..12deb7e --- /dev/null +++ b/charts/neodax/templates/influx-cm.yaml @@ -0,0 +1,144 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "component.fullname" . }}-influxdb-seed-schema + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": before-hook-creation + "helm.sh/hook-weight": "-1" +data: + schema.sql: |- + {{- $database := .Values.secrets.FINEX_INFLUX_DATABASE }} + CREATE DATABASE {{ $database }}; + + CREATE CONTINUOUS QUERY "trade_to_cq_1m_per_source" ON {{ $database }} + RESAMPLE EVERY 1s FOR 3m + BEGIN + SELECT + FIRST(price) AS open, + MAX(price) AS high, + MIN(price) AS low, + LAST(price) AS close, + SUM(amount) AS volume, + SUM(total) AS quote_volume, + FIRST(price) * SUM(amount) AS weighted_open, + MAX(price) * SUM(amount) AS weighted_high, + MIN(price) * SUM(amount) AS weighted_low, + LAST(price) * SUM(amount) AS weighted_close + INTO "candles_1m_per_source" + FROM "trades" + GROUP BY time(1m), market, source + END; + + CREATE CONTINUOUS QUERY "aggregated_cq_1m" ON {{ $database }} + RESAMPLE EVERY 1s FOR 3m + BEGIN + SELECT + SUM(weighted_open) / SUM(volume) AS open, + SUM(weighted_high) / SUM(volume) AS high, + SUM(weighted_low) / SUM(volume) AS low, + SUM(weighted_close) / SUM(volume) AS close, + SUM(volume) AS volume, + SUM(quote_volume) AS quote_volume + INTO "candles_1m" + FROM "candles_1m_per_source" + GROUP BY time(1m), market + END; + + CREATE CONTINUOUS QUERY "cq_5m" ON {{ $database }} + RESAMPLE EVERY 5s FOR 6m + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_5m" FROM "candles_1m" GROUP BY time(5m), market + END; + + CREATE CONTINUOUS QUERY "cq_15m" ON {{ $database }} + RESAMPLE EVERY 5s FOR 20m + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_15m" FROM "candles_5m" GROUP BY time(15m), market + END; + + CREATE CONTINUOUS QUERY "cq_30m" ON {{ $database }} + RESAMPLE EVERY 5s FOR 45m + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_30m" FROM "candles_15m" GROUP BY time(30m), market + END; + + CREATE CONTINUOUS QUERY "cq_1h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 90m + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_1h" FROM "candles_30m" GROUP BY time(1h), market + END; + + CREATE CONTINUOUS QUERY "cq_2h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 3h + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_2h" FROM "candles_1h" GROUP BY time(2h), market + END; + + CREATE CONTINUOUS QUERY "cq_4h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 6h + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_4h" FROM "candles_2h" GROUP BY time(4h), market + END; + + CREATE CONTINUOUS QUERY "cq_6h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 8h + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_6h" FROM "candles_2h" GROUP BY time(6h), market + END; + + CREATE CONTINUOUS QUERY "cq_12h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 18h + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_12h" FROM "candles_6h" GROUP BY time(12h), market + END; + + CREATE CONTINUOUS QUERY "cq_1d" ON {{ $database }} + RESAMPLE EVERY 5s FOR 30h + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_1d" FROM "candles_6h" GROUP BY time(1d), market + END; + + CREATE CONTINUOUS QUERY "cq_3d" ON {{ $database }} + RESAMPLE EVERY 5s FOR 4d + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_3d" FROM "candles_1d" GROUP BY time(3d), market + END; + + CREATE CONTINUOUS QUERY "cq_1w" ON {{ $database }} + RESAMPLE EVERY 5s FOR 8d + BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume, SUM(quote_volume) as quote_volume INTO "candles_1w" FROM "candles_1d" GROUP BY time(1w), market + END; + + CREATE CONTINUOUS QUERY "candles_1m_to_cq_1m" ON {{ $database }} + RESAMPLE EVERY 1m FOR 2m + BEGIN + SELECT last(close) AS open, last(close) AS high, last(close) AS low, last(close) AS close, last(volume) * 0 as volume, last(quote_volume) * 0 as quote_volume INTO "candles_1m" FROM "candles_1m" GROUP BY time(1m), market fill(previous) + END; + + CREATE CONTINUOUS QUERY "charts_1h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 2h + BEGIN + SELECT mean(price) AS price, mean(market_cap) AS market_cap, mean(total_volume) AS total_volume INTO market_charts_1h FROM market_charts_5m GROUP BY time(1h), code + END; + + CREATE CONTINUOUS QUERY "charts_3h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 6h + BEGIN + SELECT mean(price) AS price, mean(market_cap) AS market_cap, mean(total_volume) AS total_volume INTO market_charts_3h FROM market_charts_1h GROUP BY time(3h), code + END; + + CREATE CONTINUOUS QUERY "charts_6h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 12h + BEGIN + SELECT mean(price) AS price, mean(market_cap) AS market_cap, mean(total_volume) AS total_volume INTO market_charts_6h FROM market_charts_3h GROUP BY time(6h), code + END; + + CREATE CONTINUOUS QUERY "charts_12h" ON {{ $database }} + RESAMPLE EVERY 5s FOR 24h + BEGIN + SELECT mean(price) AS price, mean(market_cap) AS market_cap, mean(total_volume) AS total_volume INTO market_charts_12h FROM market_charts_6h GROUP BY time(12h), code + END; diff --git a/charts/neodax/templates/secret.yaml b/charts/neodax/templates/secret.yaml new file mode 100644 index 0000000..322cff9 --- /dev/null +++ b/charts/neodax/templates/secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "component.fullname" . }}-opt-env + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-delete-policy": before-hook-creation + "helm.sh/hook-weight": "-1" +data: +{{- range $key, $value := .Values.secrets }} + {{- $key | nindent 2 }}: {{ $value | print | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/neodax/templates/services.yaml b/charts/neodax/templates/services.yaml new file mode 100644 index 0000000..67c8447 --- /dev/null +++ b/charts/neodax/templates/services.yaml @@ -0,0 +1,16 @@ +{{- range $name, $svc := .Values.services }} +{{- $svc = set $svc "name" $name }} +--- +apiVersion: v1 +kind: Service +metadata: + name: "{{ include "component.fullname" $ }}-{{ $svc.name }}" + labels: + {{- include "component.labels" $ | nindent 4 }} +spec: + type: {{ default "ClusterIP" $svc.type }} + ports: + {{- include "service.port" $svc | nindent 4 }} + selector: + {{- include "component.selectorLabels" $ | nindent 4 }} +{{- end }} diff --git a/charts/neodax/templates/ws-ingress.yaml b/charts/neodax/templates/ws-ingress.yaml new file mode 100644 index 0000000..fa6ebfc --- /dev/null +++ b/charts/neodax/templates/ws-ingress.yaml @@ -0,0 +1,17 @@ +apiVersion: {{ include "ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "component.fullname" . }}-ws + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + {{- include "ingress.defaultAnnotations" . | nindent 4 }} +spec: + {{- $svc := set .Values.services.ws "name" (printf "%s-ws" (include "component.fullname" .)) }} + {{- $root := set . "service" $svc }} + rules: + - host: {{ .Values.externalHostname }} + http: + paths: + {{- include "ingress.path" $root | nindent 10 }} + {{- include "ingress.tls" $root | nindent 2 }} diff --git a/charts/neodax/values.yaml b/charts/neodax/values.yaml new file mode 100644 index 0000000..071598e --- /dev/null +++ b/charts/neodax/values.yaml @@ -0,0 +1,149 @@ +replicaCount: 1 + +image: + repository: quay.io/openware/openfinex + tag: master + pullPolicy: IfNotPresent + +metrics: + port: 8080 + enabled: true + endpoint: "/metrics" + +fullnameOverride: "" +nameOverride: "" + +secrets: {} +externalSecret: "" + +config: | + mode: dev + +services: + ws: + port: 8080 + grpc: + type: NodePort + # nodePort: 30000 + port: 50051 + +externalHostname: example.kayen.io +tlsClusterIssuer: letsencrypt-prod + +ingress: + path: / + tls: + enabled: true + +cleanupHooksEnabled: false +hooks: + createDb: + enabled: true + image: + repository: supabase/postgres + tag: 13.3.0 + secrets: + - name: db-credentials + envs: + DATABASE_ROOT_USER: PGUSER + DATABASE_ROOT_PASSWORD: PGPASSWORD + - name: opt-env + this_release: true + envs: + FINEX_DATABASE_NAME: DB_NAME + FINEX_DATABASE_HOST: PGHOST + FINEX_DATABASE_PORT: PGPORT + createDbUser: + enabled: true + image: + repository: supabase/postgres + tag: 13.3.0 + secrets: + - name: db-credentials + envs: + DATABASE_ROOT_USER: PGUSER + DATABASE_ROOT_PASSWORD: PGPASSWORD + - name: opt-env + this_release: true + envs: + FINEX_DATABASE_USERNAME: DB_USER + FINEX_DATABASE_PASSWORD: DB_PASS + FINEX_DATABASE_NAME: DB_NAME + FINEX_DATABASE_SCHEMA: DB_SCHEMA + FINEX_DATABASE_HOST: PGHOST + FINEX_DATABASE_PORT: PGPORT + dropDbUser: + enabled: true + image: + repository: supabase/postgres + tag: 13.3.0 + secrets: + - name: db-credentials + envs: + DATABASE_ROOT_USER: PGUSER + DATABASE_ROOT_PASSWORD: PGPASSWORD + - name: opt-env + this_release: true + envs: + FINEX_DATABASE_USERNAME: DB_USER + FINEX_DATABASE_NAME: DB_NAME + FINEX_DATABASE_HOST: PGHOST + FINEX_DATABASE_PORT: PGPORT + dropDb: + enabled: true + image: + repository: supabase/postgres + tag: 13.3.0 + secrets: + - name: db-credentials + envs: + DATABASE_ROOT_USER: PGUSER + DATABASE_ROOT_PASSWORD: PGPASSWORD + - name: opt-env + this_release: true + envs: + FINEX_DATABASE_NAME: DB_NAME + FINEX_DATABASE_HOST: PGHOST + FINEX_DATABASE_PORT: PGPORT + createDbSchema: + enabled: true + migrateDbSchema: + enabled: true + seedInfluxDb: + enabled: true + image: + repository: "influxdb" + tag: "1.8.10-alpine" + secrets: + - name: opt-env + this_release: true + envs: + FINEX_INFLUX_HOST: INFLUXDB_HOSTS + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +profile: + enabled: false + # requests: + # cpu: 100m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + +probes: + readiness: {} + liveness: {} + +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +extraLabels: {} diff --git a/charts/terminal/.helmignore b/charts/terminal/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/terminal/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/terminal/Chart.yaml b/charts/terminal/Chart.yaml new file mode 100644 index 0000000..a6efea0 --- /dev/null +++ b/charts/terminal/Chart.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +appVersion: '1.0' +description: Yellow Terminal Chart +name: terminal +version: 1.0.0 diff --git a/charts/terminal/config/testnet.yaml b/charts/terminal/config/testnet.yaml new file mode 100644 index 0000000..804da93 --- /dev/null +++ b/charts/terminal/config/testnet.yaml @@ -0,0 +1,5 @@ +externalHostname: terminal.v4.uat.opendax.app +externalSecret: "" + +secrets: {} +# SOME_ENV: "some-value" diff --git a/charts/terminal/templates/deployment.yaml b/charts/terminal/templates/deployment.yaml new file mode 100644 index 0000000..961e153 --- /dev/null +++ b/charts/terminal/templates/deployment.yaml @@ -0,0 +1,46 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "component.fullname" . }} + labels: + {{- include "component.labels" . | nindent 4 }} +spec: + {{- include "component.replicaCount" . | nindent 2 }} + strategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "component.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "component.metricsAnnotations" .Values.metrics | nindent 8 }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + labels: + {{- include "component.selectorLabels" . | nindent 8 }} + {{- if .Values.extraLabels }} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + spec: + containers: + - name: clearport + image: {{ include "component.image" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["npm", "start"] + {{- if or .Values.secrets .Values.externalSecret }} + envFrom: + {{- if .Values.secrets }} + - secretRef: + name: {{ include "component.fullname" . }}-opt-env + {{- end }} + {{- if .Values.externalSecret }} + - secretRef: + name: {{ .Values.externalSecret }} + {{- end }} + {{- end }} + {{- include "component.resources" . | nindent 10 }} + {{- include "component.imagePullSecrets" . | nindent 6 }} + {{- include "component.nodeSelectorLabels" . | nindent 6 }} + {{- include "component.affinity" . | nindent 6 }} + {{- include "component.tolerations" . | nindent 6 }} diff --git a/charts/terminal/templates/helpers/component.tpl b/charts/terminal/templates/helpers/component.tpl new file mode 100644 index 0000000..c8e13aa --- /dev/null +++ b/charts/terminal/templates/helpers/component.tpl @@ -0,0 +1,169 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "component.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 "component.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 }} + +{{/* +Selector labels +*/}} +{{- define "component.selectorLabels" -}} +app: {{ include "component.name" . }} +app.kubernetes.io/name: {{ include "component.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "component.labels" -}} +helm.sh/chart: {{ include "component.chart" . }} +{{ include "component.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "component.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Returns Prometheus metrics' annotations depending on input Values +*/}} +{{- define "component.metricsAnnotations" -}} +prometheus.io/scrape: {{ default false .enabled | print | quote }} +prometheus.io/port: {{ default 4242 .port | print | quote }} +prometheus.io/path: {{ default "/metrics" .endpoint | print | quote }} +{{- end }} + +{{/* +Returns replica count depending on global Values and HPA settings +*/}} +{{- define "component.replicaCount" -}} +{{- if not (and .Values.autoscaling .Values.autoscaling.enabled) }} +{{- if and .Values.profile.enabled }} +replicas: {{ get .Values.profile.replicas .Chart.Name }} +{{- else }} +replicas: {{ .Values.replicaCount }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Returns full docker image name +*/}} +{{- define "component.image" -}} +{{ printf "%s:%s" (print .repository) (print .tag) }} +{{- end }} + +{{/* +Returns container ports configuration depending on input service +*/}} +{{- define "component.port" -}} +- name: {{ .name }} + containerPort: {{ default .port .internalPort }} + protocol: TCP +{{- end }} + +{{/* +Returns component's resource consumption +*/}} +{{- define "component.resources" -}} +{{- if .Values.profile.enabled }} +{{- with .Values.profile }} +resources: + {{- with .requests }} + requests: + cpu: {{ .cpu }} + memory: {{ .memory }} + {{- end }} + {{- with .limits }} + limits: + cpu: {{ .cpu }} + memory: {{ .memory }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Returns component's probes +*/}} +{{- define "component.probes" -}} +{{- $svc := get .Values.services .subservice }} +{{- $port := default $svc.port $svc.internalPort }} +{{- range $name, $probe := .Values.probes }} +{{ printf "%sProbe" $name }}: + httpGet: + path: {{ default "/health" $probe.path }} + port: {{ default $port $probe.port }} + initialDelaySeconds: {{ default 5 $probe.initialDelaySeconds }} + timeoutSeconds: {{ default 10 $probe.timeoutSeconds }} + periodSeconds: {{ default 10 $probe.periodSeconds }} +{{- end }} +{{- end }} + +{{/* +Returns personal and global component's image pull secrets +*/}} +{{- define "component.imagePullSecrets" -}} +imagePullSecrets: +{{- if .Values.image.pullSecret }} +- name: {{ .Values.image.pullSecret }} +{{- end }} +{{- end }} + +{{/* +Returns personal and global component's node selector labels +*/}} +{{- define "component.nodeSelectorLabels" -}} +nodeSelector: + {{- if .Values.nodeSelector }} + {{ toYaml .Values.nodeSelector | nindent 2 }} + {{- end }} +{{- end }} + +{{/* +Returns personal and global component's tolerations +*/}} +{{- define "component.tolerations" -}} +tolerations: +{{- if .Values.tolerations }} +{{ toYaml .Values.tolerations }} +{{- end }} +{{- end }} + +{{/* +Returns component pod's affinity +*/}} +{{- define "component.affinity" -}} +affinity: + {{- if .Values.affinity }} + {{ toYaml .Values.affinity | nindent 2 }} + {{- end }} +{{- end }} diff --git a/charts/terminal/templates/helpers/ingress.tpl b/charts/terminal/templates/helpers/ingress.tpl new file mode 100644 index 0000000..6392f04 --- /dev/null +++ b/charts/terminal/templates/helpers/ingress.tpl @@ -0,0 +1,60 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns Ingress API version depending on K8s cluster version +*/}} +{{- define "ingress.apiVersion" -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version -}} +networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.Version -}} +networking.k8s.io/v1beta1 +{{- else -}} +extensions/v1beta1 +{{- end }} +{{- end }} + +{{/* +Returns default Ingress annotations +*/}} +{{- define "ingress.defaultAnnotations" -}} +kubernetes.io/ingress.class: nginx +kubernetes.io/tls-acme: "true" +cert-manager.io/cluster-issuer: "{{ .Values.tlsClusterIssuer }}" +{{- end }} + +{{/* +Returns Ingress TLS configuration +*/}} +{{- define "ingress.tls" -}} +{{- if .Values.ingress.tls.enabled }} +{{- if not .hosts }} +{{- $_ := set . "hosts" (list .Values.externalHostname) }} +{{- end }} +tls: + {{- range $host := .hosts }} + - secretName: "{{ $host | replace "." "-" }}-tls" + hosts: + - "{{ $host }}" + {{- end }} +{{- end }} +{{- end }} + +{{/* +Returns Ingress host path configuration +*/}} +{{- define "ingress.path" -}} +- path: {{ default .Values.ingress.path .path }} + {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.Version }} + pathType: Prefix + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- $svc := .service }} + service: + name: {{ $svc.name }} + port: + number: {{ default $svc.port $svc.internalPort }} + {{- else }} + serviceName: {{ $svc.name }} + servicePort: {{ default $svc.port $svc.internalPort }} + {{- end }} +{{- end }} diff --git a/charts/terminal/templates/helpers/job.tpl b/charts/terminal/templates/helpers/job.tpl new file mode 100644 index 0000000..a1dd7d3 --- /dev/null +++ b/charts/terminal/templates/helpers/job.tpl @@ -0,0 +1,31 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns Cron Job API version depending on K8s cluster version +*/}} +{{- define "cronjob.apiVersion" -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version -}} +batch/v1 +{{- else -}} +batch/v1beta1 +{{- end }} +{{- end }} + +{{/* +Returns env mapping from Secret +*/}} +{{- define "hook.secretEnvs" -}} +{{- $hook := get .Values.hooks .hookName }} +{{- range $secret := $hook.secrets }} +{{- range $env, $rename := $secret.envs }} +- name: {{ default $env $rename }} + valueFrom: + secretKeyRef: + {{- if $secret.this_release }} + name: {{ printf "%s-%s" (include "component.fullname" $) $secret.name }} + {{- else }} + name: {{ $secret.name }} + {{- end }} + key: {{ $env }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/terminal/templates/helpers/main.tpl b/charts/terminal/templates/helpers/main.tpl new file mode 100644 index 0000000..7d265d9 --- /dev/null +++ b/charts/terminal/templates/helpers/main.tpl @@ -0,0 +1,36 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Kong Service Name +*/}} +{{- define "main.kongSvcName" -}} +{{- printf "%s-%s-%s" .Release.Name .Values.global.kong.nameOverride .Values.global.kong.svcType }} +{{- end }} + +{{/* +Secret environment variable template +with opendax-global Secret backwards compatibility +*/}} +{{- define "main.opendaxGlobalVarReplace" -}} +- name: {{ default .name .nameOverride }} + valueFrom: + secretKeyRef: + {{- if eq (default "vault" .Values.global.kaigara.storageDriver) "k8s" }} + name: {{ printf "kaigara-%s" .secretApp }} + key: {{ .name }} + {{- else }} + name: {{ .Values.global.secretPrefix }}-global + key: {{ .key }} + {{- end }} +{{- end }} + +{{/* +Returns pod annotations snippet depending on input Values +*/}} +{{- define "main.withGlobalAnnotations" -}} +{{- range $key, $value := .Values.global.podAnnotations }} +{{ printf "\"%s\": \"%s\"" $key (print $value) }} +{{- end }} +{{- range $key, $value := .Values.podAnnotations }} +{{ printf "\"%s\": \"%s\"" $key (print $value) }} +{{- end }} +{{- end }} diff --git a/charts/terminal/templates/helpers/service.tpl b/charts/terminal/templates/helpers/service.tpl new file mode 100644 index 0000000..1bcd6b8 --- /dev/null +++ b/charts/terminal/templates/helpers/service.tpl @@ -0,0 +1,17 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Returns service ports configuration depending on input service +*/}} +{{- define "service.port" -}} +- name: {{ kebabcase .name }} + {{- if eq .type "NodePort" }} + port: {{ default .port .internalPort }} + {{- if .nodePort }} + nodePort: {{ .nodePort }} + {{- end }} + {{- else }} + port: {{ default .port .externalPort }} + {{- end }} + targetPort: {{ default .port .internalPort }} + protocol: TCP +{{- end }} diff --git a/charts/terminal/templates/ingress.yaml b/charts/terminal/templates/ingress.yaml new file mode 100644 index 0000000..1c957e9 --- /dev/null +++ b/charts/terminal/templates/ingress.yaml @@ -0,0 +1,19 @@ +{{- if .Values.ingress.enabled }} +apiVersion: {{ include "ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "component.fullname" . }}-ws + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + {{- include "ingress.defaultAnnotations" . | nindent 4 }} +spec: + {{- $svc := set .Values.service "name" (printf "%s-%s" (include "component.fullname" .) .Values.service.name ) }} + {{- $root := set . "service" $svc }} + rules: + - host: {{ .Values.externalHostname }} + http: + paths: + {{- include "ingress.path" $root | nindent 10 }} + {{- include "ingress.tls" $root | nindent 2 }} +{{- end }} diff --git a/charts/terminal/templates/secret.yaml b/charts/terminal/templates/secret.yaml new file mode 100644 index 0000000..89c2d04 --- /dev/null +++ b/charts/terminal/templates/secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "component.fullname" . }}-opt-env + labels: + {{- include "component.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install, pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation + "helm.sh/hook-weight": "-1" +data: +{{- range $key, $value := .Values.secrets }} + {{- $key | nindent 2 }}: {{ $value | print | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/terminal/templates/service.yaml b/charts/terminal/templates/service.yaml new file mode 100644 index 0000000..231fad5 --- /dev/null +++ b/charts/terminal/templates/service.yaml @@ -0,0 +1,13 @@ +{{- $svc := .Values.service }} +apiVersion: v1 +kind: Service +metadata: + name: "{{ include "component.fullname" $ }}-{{ $svc.name }}" + labels: + {{- include "component.labels" $ | nindent 4 }} +spec: + type: {{ default "ClusterIP" $svc.type }} + ports: + {{- include "service.port" $svc | nindent 4 }} + selector: + {{- include "component.selectorLabels" $ | nindent 4 }} diff --git a/charts/terminal/values.yaml b/charts/terminal/values.yaml new file mode 100644 index 0000000..d8f7e2b --- /dev/null +++ b/charts/terminal/values.yaml @@ -0,0 +1,59 @@ +replicaCount: 1 + +image: + repository: quay.io/openware/terminal + tag: 0.1.7 + pullPolicy: IfNotPresent + pullSecret: openware-quay + +metrics: + port: 8080 + enabled: false + endpoint: "/metrics" + +fullnameOverride: "" +nameOverride: "" + +secrets: {} +externalSecret: "" + +service: + name: web + port: 3000 + +externalHostname: terminal.v4.uat.opendax.app +tlsClusterIssuer: letsencrypt-prod + +ingress: + enabled: true + path: / + tls: + enabled: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +profile: + enabled: false + # requests: + # cpu: 100m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + +probes: + readiness: {} + liveness: {} + +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +extraLabels: {}