diff --git a/.env b/.env index 35d1c5b..7637cb7 100644 --- a/.env +++ b/.env @@ -1,9 +1,10 @@ -RAILS_HOST_NAME=local3000.notch8.cloud +RAILS_HOST_NAME=scibot.test BASE_URL=https://${RAILS_HOST_NAME} -DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}?pool=30" -DB_NAME=scibot -DB_PASSWORD=testing123 -DB_USER=postgres +DATABASE_URL="postgres://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}/${DATABASE_NAME}?pool=30" +DATABASE_NAME=scibot +DATABASE_PASSWORD=testing123 +DATABASE_USER=postgres +DATABASE_HOST=db RAILS_ENV=development RAILS_SECRET_TOKEN= SLACK_CLIENT_ID= diff --git a/.github/workflows/build-test-lint.yaml b/.github/workflows/build-test-lint.yaml index 8513e0d..cd78ad9 100644 --- a/.github/workflows/build-test-lint.yaml +++ b/.github/workflows/build-test-lint.yaml @@ -28,7 +28,7 @@ jobs: # uses: scientist-softserv/actions/.github/workflows/test.yaml@v0.0.14 # with: # webTarget: - + # # lint: # needs: build # uses: scientist-softserv/actions/.github/workflows/lint.yaml@v0.0.14 diff --git a/Gemfile b/Gemfile index 4269f1a..8714fe2 100644 --- a/Gemfile +++ b/Gemfile @@ -40,5 +40,7 @@ group :development do gem 'spring-watcher-listen', '~> 2.0.0' end +gem 'rubocop' + # Windows does not include zoneinfo files, so bundle the tzinfo-data gem # gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] diff --git a/Gemfile.lock b/Gemfile.lock index 4ff396b..df9b522 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,11 +66,13 @@ GEM i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) + ast (2.4.2) async (2.6.2) console (~> 1.10) fiber-annotation io-event (~> 1.1) timers (~> 4.1) + base64 (0.1.1) bootsnap (1.15.0) msgpack (~> 1.2) builder (3.2.4) @@ -136,10 +138,12 @@ GEM i18n (1.14.1) concurrent-ruby (~> 1.0) io-event (1.2.2) + json (2.6.3) kaminari-core (1.2.2) kaminari-grape (1.0.1) grape kaminari-core (~> 1.0) + language_server-protocol (3.17.0.3) listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -183,6 +187,10 @@ GEM pagy_cursor (0.6.0) activerecord (>= 5) pagy (>= 6, < 7) + parallel (1.23.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc pg (1.4.5) puma (6.0.1) nio4r (~> 2.0) @@ -223,16 +231,34 @@ GEM rake (>= 12.2) thor (~> 1.0) zeitwerk (~> 2.5) + rainbow (3.1.1) rake (13.0.6) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) + regexp_parser (2.8.2) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) + rexml (3.2.6) roar (1.1.1) representable (~> 3.0) + rubocop (1.57.1) + base64 (~> 0.1.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.4) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) slack-ruby-bot-server (2.1.0) async @@ -264,6 +290,7 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) + unicode-display_width (2.5.0) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -283,6 +310,7 @@ DEPENDENCIES pg puma (~> 6.0.1) rails (~> 7.0.4) + rubocop slack-ruby-bot-server-events spring spring-watcher-listen (~> 2.0.0) diff --git a/README.md b/README.md index 5a2c2b0..0f67ea1 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,16 @@ The default branch `master` uses Mongoid as database adapter. For ActiveRecord, - `groups:read` - `chat:write` - `commands` -- `incoming-webhook` - **BASE_URL** stands for https://slackbot-hosted-domain.com hereafter. - Use **BASE_URL** for **Redirect**. +- `incoming-webhook` -3. Activate **Interactivity & Shortcuts** and add this url: `BASE_URL/api/slack/action` -4. Activate **Slash Commands** adding two slash commands `/ping`, `/quiz` and use this url: `BASE_URL/api/slack/command` -5. Activate **Event Subscriptions** subscribing to the event type `member_joined_channel` and add this url: `BASE_URL/api/slack/event`(This step needs the application to be running :D so you can skip this and come back a few mins later) +Slack Link to Slack-Scibot, will need to authenticate via Slack login to the workspace it is configured to work with: https://api.slack.com/apps/A062693KZRB + + **BASE_URL** stands for https://slack-scibot.notch8.cloud hereafter. + Use **https://slack-scibot.notch8.cloud** for **Redirect**. + +3. Activate **Interactivity & Shortcuts** and add this url: `https://slack-scibot.notch8.cloud/api/slack/action` +4. Activate **Slash Commands** adding two slash commands `/ping`, `/quiz` and use this url: `https://slack-scibot.notch8.cloud/api/slack/command` +5. Activate **Event Subscriptions** subscribing to the event type `member_joined_channel` and add this url: `https://slack-scibot.notch8.cloud/api/slack/event`(This step needs the application to be running :D so you can skip this and come back a few mins later) 6. Navigate to the **App Home** page and toggle **Always Show My Bot as Online** (according to your reference) #### Install dependencies and prepare `.env` file @@ -39,7 +42,7 @@ bundle install cp .env.example .env ``` -Go to https://api.slack.com/apps, click on your application. +Go to https://api.slack.com/apps, click on your application. Grab the infomations for `.env` from **Basic Information** section. ## Run the app @@ -48,7 +51,7 @@ Grab the infomations for `.env` from **Basic Information** section. rails s ``` -Open **BASE_URL** in your browser. +Open **https://slack-scibot.notch8.cloud** in your browser. ## Deployment diff --git a/bin/helm_deploy b/bin/helm_deploy new file mode 100755 index 0000000..0b7c97a --- /dev/null +++ b/bin/helm_deploy @@ -0,0 +1,29 @@ +#!/bin/bash + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +if [ -z "$1" ] || [ -z "$2" ] +then + echo './bin/helm_deploy RELEASE_NAME NAMESPACE' + exit 1 +fi +release_name="${1}" +namespace="${2}" + +DEPLOY_IMAGE="${DEPLOY_IMAGE:-ghcr.io/scientist-softserv/slack-scibot}" +DEPLOY_TAG="${DEPLOY_TAG:-latest}" +echo "${DEPLOY_TAG}" + +helm repo update + +helm upgrade \ + --install \ + --atomic \ + --timeout 15m0s \ + --set image.repository="$DEPLOY_IMAGE" \ + --set image.tag="$DEPLOY_TAG" \ + $HELM_EXTRA_ARGS \ + --namespace="$namespace" \ + --create-namespace \ + "$release_name" \ + chart \ No newline at end of file diff --git a/chart/.helmignore b/chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/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/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..64f6830 --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: slack-scibot +description: A Helm chart for Slack SciBot +version: 0.1.0 +appVersion: "1.16.0" diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 0000000..319f01b --- /dev/null +++ b/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 "chart.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 "chart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "chart.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 "chart.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/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..3cd7343 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,111 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "chart.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 "chart.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 "chart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "chart.labels" -}} +helm.sh/chart: {{ include "chart.chart" . }} +{{ include "chart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "chart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "chart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "chart.postgresql.fullname" -}} +{{- printf "%s-%s" .Release.Name "postgresql" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "chart.postgresql.host" -}} +{{- if .Values.postgresql.enabled }} +{{- include "chart.postgresql.fullname" . }} +{{- else }} +{{- .Values.externalPostgresql.host }} +{{- end }} +{{- end -}} + + +{{- define "chart.postgresql.database" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.postgresql.auth.database }} +{{- else }} +{{- .Values.externalPostgresql.database | default ( include "chart.fullname" . ) }} +{{- end }} +{{- end -}} + +{{- define "chart.postgresql.username" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.postgresql.auth.username }} +{{- else }} +{{- .Values.externalPostgresql.username | default "postgres" }} +{{- end }} +{{- end -}} + +{{- define "chart.postgresql.password" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.postgresql.auth.password }} +{{- else }} +{{- .Values.externalPostgresql.password }} +{{- end }} +{{- end -}} + +{{- define "chart.postgresql.port" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.postgresql.containerPorts.postgresql | default 5432 }} +{{- else }} +{{- .Values.externalPostgresql.port | default 5432 }} +{{- end }} +{{- end -}} + +{{- define "chart.postgresql.url" -}} +{{- printf "postgresql://%s:%s@%s/%s?pool=5" ( include "chart.postgresql.username" . ) ( include "chart.postgresql.password" . ) ( include "chart.postgresql.host" . ) ( include "chart.postgresql.database" . ) -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/configmap.yaml b/chart/templates/configmap.yaml new file mode 100644 index 0000000..3a9b44b --- /dev/null +++ b/chart/templates/configmap.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "chart.fullname" . }}-cm +data: +{{- range $key, $value := .Values.env.configmap }} + {{ $key }}: "{{ $value }}" +{{- end }} \ No newline at end of file diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml new file mode 100644 index 0000000..85ecf44 --- /dev/null +++ b/chart/templates/deployment.yaml @@ -0,0 +1,97 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "chart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "chart.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "chart.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + initContainers: + - name: db-create + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + command: ["sh", "-c", "rails db:create"] + envFrom: + - configMapRef: + name: {{ include "chart.fullname" . }}-cm + - secretRef: + name: {{ include "chart.fullname" . }}-secret + - name: db-migrate + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + command: ["sh", "-c", "rails db:migrate"] + envFrom: + - configMapRef: + name: {{ include "chart.fullname" . }}-cm + - secretRef: + name: {{ include "chart.fullname" . }}-secret + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["/bin/bash", "./ops/entrypoint.sh"] + args: ["bundle", "exec", "puma", "-p", "3000"] + readinessProbe: + tcpSocket: + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 3000 + initialDelaySeconds: 60 + periodSeconds: 120 + ports: + - name: http + containerPort: 3000 + protocol: TCP + # livenessProbe: + # httpGet: + # path: / + # port: 3000 + # readinessProbe: + # httpGet: + # path: / + # port: 3000 + resources: + {{- toYaml .Values.resources | nindent 12 }} + envFrom: + - configMapRef: + name: {{ include "chart.fullname" . }}-cm + - secretRef: + name: {{ include "chart.fullname" . }}-secret + {{- 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/chart/templates/hpa.yaml b/chart/templates/hpa.yaml new file mode 100644 index 0000000..a91f61b --- /dev/null +++ b/chart/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "chart.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml new file mode 100644 index 0000000..63c1311 --- /dev/null +++ b/chart/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "chart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else 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 "chart.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- 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 }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/secret.yaml b/chart/templates/secret.yaml new file mode 100644 index 0000000..08a52b1 --- /dev/null +++ b/chart/templates/secret.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "chart.fullname" . }}-secret +data: +{{- range $key, $value := .Values.env.secret }} + {{ $key }}: {{ $value |b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml new file mode 100644 index 0000000..c5a64ca --- /dev/null +++ b/chart/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 3000 # Container port + protocol: TCP + name: http + selector: + {{- include "chart.selectorLabels" . | nindent 4 }} diff --git a/chart/templates/serviceaccount.yaml b/chart/templates/serviceaccount.yaml new file mode 100644 index 0000000..26a57fa --- /dev/null +++ b/chart/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "chart.serviceAccountName" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/tests/test-connection.yaml b/chart/templates/tests/test-connection.yaml new file mode 100644 index 0000000..8dfed87 --- /dev/null +++ b/chart/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "chart.fullname" . }}-test-connection" + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "chart.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..23e0188 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,82 @@ +# Default values for slack-scibot. +# 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 + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + 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: {} diff --git a/config/database.yml b/config/database.yml index bb50dc0..cc106d8 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,18 +1,18 @@ -default: &default - adapter: postgresql - encoding: unicode +# Hi - please dont edit this file directly, instead make changes in your .env file + +login: &login + adapter: <%= ENV['DATABASE_ADAPTER'] || 'postgresql' %> + host: <%= ENV['DATABASE_HOST'] %> + username: <%= ENV['DATABASE_USER'] %> + password: <%= ENV['DATABASE_PASSWORD'] %> + database: <%= ENV['DATABASE_NAME'] %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + encoding: unicode development: - <<: *default - url: <%= ENV['DATABASE_URL'] %> - database: <%= ENV['DATABASE_NAME'] %> + <<: *login test: - <<: *default - url: <%= ENV['DATABASE_URL'] %> - database: slack_rails_bot_starter_test - -production: - url: <%= ENV['DATABASE_URL'] %> - database: <%= ENV['DATABASE_NAME'] %> + <<: *login + database: <%= ENV['DATABASE_TEST_NAME'] || 'slack_scibot_test' %> diff --git a/db/seed.rb b/db/seed.rb index 8e5d735..578c0b5 100644 --- a/db/seed.rb +++ b/db/seed.rb @@ -11,7 +11,7 @@ end Member.find_or_create_by(handle: 'rob') do |member| - member.name = "Rob Kauufman" + member.name = "Rob Kaufman" member.group = Group.find_by(name: 'devops') member.member_id = "U0E347KGF" end diff --git a/docker-compose.yaml b/docker-compose.yaml index 7efb68d..1845b9d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -30,10 +30,9 @@ services: env_file: - .env environment: - - POSTGRES_DB=${DB_NAME} - - POSTGRES_PASSWORD=${DB_PASSWORD} - - POSTGRES_USER=${DB_USER} - - VIRTUAL_PORT=5432 - - VIRTUAL_HOST=db.scibot.test + - POSTGRES_DB=${DATABASE_NAME} + - POSTGRES_PASSWORD=${DATABASE_PASSWORD} + - POSTGRES_USER=${DATABASE_USER} + - POSTGRES_HOST=${DATABASE_HOST} volumes: - db:/var/lib/postgresql/data diff --git a/ops/entrypoint.sh b/ops/entrypoint.sh new file mode 100755 index 0000000..4e49645 --- /dev/null +++ b/ops/entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash -l +set -e + +# Remove a potentially pre-existing server.pid for Rails. +rm -f /app/tmp/pids/server.pid + +bundle check || bundle install + +echo "Starting $@" +# Then exec the container's main process (what's set as CMD in the Dockerfile). +exec "$@" \ No newline at end of file diff --git a/ops/staging-deploy.tmpl.yaml b/ops/staging-deploy.tmpl.yaml new file mode 100644 index 0000000..6b48fbb --- /dev/null +++ b/ops/staging-deploy.tmpl.yaml @@ -0,0 +1,86 @@ +# Default values for slack-scibot. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: ghcr.io/scientist-softserv/slack-scibot + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: + - name: github + +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: true + hosts: + - host: slack-scibot.notch8.cloud + paths: + - path: / + pathType: ImplementationSpecific + annotations: { + kubernetes.io/ingress.class: "nginx", + nginx.ingress.kubernetes.io/proxy-body-size: "0", + cert-manager.io/cluster-issuer: letsencrypt-prod + } + tls: + - hosts: + - slack-scibot.notch8.cloud + secretName: slack-scibot-tls + +postgresql: + enabled: false + +# database configuration for an external postgresql; +# ignored if `postgresql.enabled` is true +externalPostgresql: + host: pg-postgresql.staging-postgres.svc.cluster.local + password: $POSTGRES_PASSWORD + +env: + configmap: + RAILS_HOST_NAME: slack-scibot.notch8.cloud + BASE_URL: https://slack-scibot.notch8.cloud + DATABASE_HOST: pg-postgresql.staging-postgres.svc.cluster.local + DATABASE_NAME: slack-scibot-staging + DATABASE_PASSWORD: $POSTGRES_PASSWORD + DATABASE_USER: postgres + RAILS_ENV: production + RAILS_SECRET_TOKEN: $RAILS_SECRET_TOKEN + SLACK_CLIENT_ID: $SLACK_CLIENT_ID + SLACK_CLIENT_SECRET: $SLACK_CLIENT_SECRET + SLACK_OAUTH_SCOPE: "users:read,channels:read,groups:read,chat:write,commands,incoming-webhook" + SLACK_SIGNING_SECRET: $SLACK_SIGNING_SECRET + secret: \ No newline at end of file