From dc594d04d76b3dd02335daf4297c47882c0fdfcc Mon Sep 17 00:00:00 2001
From: Dobromir Palushev <s28840@bht-berlin.de>
Date: Fri, 2 Sep 2022 19:22:16 +0200
Subject: [PATCH] pipeline multiple updates

---
 .gitlab-ci.yml                                | 124 ++++++++++++------
 app/.dockerignore                             |   2 +
 app/Dockerfile                                |   2 +-
 app/README.md                                 |   2 +-
 app/k8s-manifests/configmap.yaml              |   8 --
 app/k8s-manifests/service.yaml                |  13 --
 k8s-manifests/configmap.yaml                  |   9 ++
 .../deployment.yaml                           |   7 +-
 .../gitlab-registry-credentials.yaml          |   0
 k8s-manifests/ingress.yaml                    |  23 ++++
 .../secrets.yaml                              |   2 +-
 k8s-manifests/service.yaml                    |  17 +++
 12 files changed, 144 insertions(+), 65 deletions(-)
 delete mode 100644 app/k8s-manifests/configmap.yaml
 delete mode 100644 app/k8s-manifests/service.yaml
 create mode 100644 k8s-manifests/configmap.yaml
 rename {app/k8s-manifests => k8s-manifests}/deployment.yaml (79%)
 rename app/registry-credentials.yaml => k8s-manifests/gitlab-registry-credentials.yaml (100%)
 create mode 100644 k8s-manifests/ingress.yaml
 rename {app/k8s-manifests => k8s-manifests}/secrets.yaml (78%)
 create mode 100644 k8s-manifests/service.yaml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b8cc189..0674d66 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,88 +1,136 @@
 workflow:
   rules:
-    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
-      when: always
     - if: >-
-        $CI_PIPELINE_SOURCE == "push"
-        && ($CI_COMMIT_BRANCH == "staging" || $CI_COMMIT_BRANCH == "master")
+        $CI_COMMIT_BRANCH == "staging" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
       when: always
     - when: never
 
 variables:
-  DOCKER_VERSION: '20.10.12'
-  K8S_NAMESPACE: 'devops-s22-deployable'
+  DOCKER_VERSION: '20.10.17'
+  K8S_VERSION: '1.24'
+  GOOGLE_CLOUD_SDK_IMAGE_VERSION: '400.0.0'
+  K8S_NAMESPACE: 'todoapp-devops'
   CONTAINER_TAG: '${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}'
 
 stages:
   - test
   - build
+  - release
   - deploy
 
-job_test-image:
+.gke-initialization:
+    before_script:
+    - echo $BASE64_GOOGLE_CREDENTIALS | base64 -d > ~/service_account.json
+    - gcloud auth activate-service-account --key-file ~/service_account.json
+    - gcloud config set project ${GCP_PROJECT_ID}
+    - gcloud config set compute/zone ${GCP_COMPUTE_REGION}
+    - gcloud container clusters get-credentials ${GCP_PROJECT_ID}-gke
+
+test-image:
   stage: test
   tags:
     - docker-priviliged
-  image: docker:$DOCKER_VERSION
+  image: docker:${DOCKER_VERSION}
   services:
-    - name: docker:$DOCKER_VERSION-dind
+    - name: docker:${DOCKER_VERSION}-dind
   script:
     - docker build
       --tag "${CONTAINER_TAG}-test"
       --target=test
       "./"
   after_script:
-    - docker image rm --force "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}"
+    - docker image rm --force "${CONTAINER_TAG}-test"
 
-job_build-image:
+build-image:
   stage: build
   needs:
-    - 'job_test-image'
-  rules:
-    - if: $CI_COMMIT_BRANCH != "staging" && $CI_COMMIT_BRANCH != "master"
-      when: 'never'
+    - 'test-image'
   tags:
     - docker-priviliged
-  image: docker:$DOCKER_VERSION
+  image: docker:${DOCKER_VERSION}
   services:
-    - name: docker:$DOCKER_VERSION-dind
+    - name: docker:${DOCKER_VERSION}-dind
+  before_script:
+    - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
   script:
-    - SERVER_PUBLIC_URL=""
-    - DB_HOST=""
-    - docker build
+    - docker image build
       --tag "${CONTAINER_TAG}"
-      --build-arg JWT_SECRET=${JWT_SECRET}
-      --build-arg SERVER_PUBLIC_URL=${SERVER_PUBLIC_URL}
-      --build-arg DB_HOST=${DB_HOST}
-      "./"
+      "./app"
+    # - docker image build
+    #   --tag "${CONTAINER_TAG}-google-sdk"
+    #   "./gcloud-image"
+    - docker push "${CONTAINER_TAG}"
+    # - docker push "${CONTAINER_TAG}-google-sdk"
+  after_script:
+    - docker image rm --force "${CONTAINER_TAG}"
+    # - docker image rm --force "${CONTAINER_TAG}-google-sdk"
+
+create-release_image:
+  stage: release
+  rules:
+    - if: $CI_COMMIT_REF_NAME =~ /main/
+      when: 'always'
+  tags:
+    - docker-privileged
+  image: docker:${DOCKER_VERSION}
+  services:
+    - name: docker:${DOCKER_VERSION}-dind
+  before_script:
     - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
-    - docker push "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}"
+    - docker pull "${CONTAINER_TAG}"
+  script:
+    - VERSION=$(cat ./app/client/package.json | docker run --interactive stedolan/jq --raw-output '.version')
+    - docker tag "${CONTAINER_TAG}" "${CI_REGISTRY_IMAGE}:${VERSION}"
+    - docker push "${CI_REGISTRY_IMAGE}:${VERSION}"
   after_script:
-    - docker image rm --force "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}"
+    - docker image rm --force
+        $(docker images --format '{{.Repository}}{{.Tag}}' | grep '${CI_REGISTRY_IMAGE}')
+
+# create-release_tag:
+#   stage: release
+#   needs:
+#     - 'create-release_image'
+#   rules:
+#     - if: $CI_COMMIT_REF_NAME =~ /main/
+#       when: 'always'
+#   tags:
+#     - docker-privileged
+#   image: docker:${DOCKER_VERSION}-git
+#   services:
+#     - name: docker:${DOCKER_VERSION}-dind
+#   script:
+#     - VERSION=$(cat ./src/package.json | docker run --interactive stedolan/jq --raw-output '.version')
+#     - echo ${VERSION}
+#     #- git tag "v${VERSION}" && git push origin "v${VERSION}"
+
 
-job_deploy-image:
+deploy-image:
+  extends: .gke-initialization
   stage: deploy
   needs:
-    - 'job_build-image'
+    - 'build-image'
   rules:
     - if: $CI_COMMIT_REF_NAME =~ /staging/
       when: 'always'
       variables:
         ENVIRONMENT_NAME: 'staging'
-    - if: $CI_COMMIT_REF_NAME !~ /staging/
+    - if: $CI_COMMIT_REF_NAME !~ /main/
       when: 'always'
       variables:
-        ENVIRONMENT_NAME: 'prod'
+        ENVIRONMENT_NAME: 'production'
   tags:
     - docker
-  image:
-    name: k8s-image
-    entrypoint: ['']
+  image: google/cloud-sdk:${GOOGLE_CLOUD_SDK_IMAGE_VERSION}
   script:
-    # - IMAGE="${CI_REGISTRY_IMAGE}:${VERSION}"
-    - kubectl apply
-        --kubeconfig ${SECRET_KUBECONFIG_PATH}
-        --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
-        --kustomize -
+    - VERSION="${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}"
+    - IMAGE="${CI_REGISTRY_IMAGE}:${VERSION}"
+    - cd "app/k8s-manifests"
+    - kubectl apply secrets.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
+    - kubectl apply gitlab-registry-credentials.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
+    - kubectl apply configmap.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
+    - kubectl apply deployment.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
+    - kubectl apply service.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
+    - kubectl apply ingress.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
 
 
 
diff --git a/app/.dockerignore b/app/.dockerignore
index 5734ba9..114cdfa 100644
--- a/app/.dockerignore
+++ b/app/.dockerignore
@@ -2,3 +2,5 @@ client/node_modules
 server/node_modules
 .dockerignore
 Dockerfile
+README.md
+npm-debug.log
diff --git a/app/Dockerfile b/app/Dockerfile
index 2ac29aa..e2085b5 100644
--- a/app/Dockerfile
+++ b/app/Dockerfile
@@ -6,7 +6,7 @@ ARG NODEJS_VERSION='16.17.0'
 FROM node:$NODEJS_VERSION-alpine AS base
 
 ENV \
-    PORT=3002 \
+    PORT=3000 \
     # For local dev - mongodb://host.docker.internal:27017/todo-app
     MONGODB_URL=<should-be-dynamically-set> \
     JWT_SECRET=<should-be-dynamically-set>
diff --git a/app/README.md b/app/README.md
index 50acb84..61839f4 100644
--- a/app/README.md
+++ b/app/README.md
@@ -1,6 +1,6 @@
 Todo-App
 ========
-
+d
 
 This application represents the *deployable workload* for the
 [lecture assignment](https://github.com/lucendio/lecture-devops-material/blob/master/assignments/exercise.md). 
diff --git a/app/k8s-manifests/configmap.yaml b/app/k8s-manifests/configmap.yaml
deleted file mode 100644
index 967de9f..0000000
--- a/app/k8s-manifests/configmap.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: app-config
-data:
-  PORT: 3000
-  # MONGODB_URL: mongo-service.namespace (from infra repo. Does this work? Or do I have to dynamically set it?)
-  MONGODB_URL: mongodb://<mongo-service>:27017/todo-app
diff --git a/app/k8s-manifests/service.yaml b/app/k8s-manifests/service.yaml
deleted file mode 100644
index c5a84a2..0000000
--- a/app/k8s-manifests/service.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
-  name: todo-app-service
-spec:
-  selector:
-      app: todo-app
-  ports:
-    - port: 8080
-      targetPort: 3000
-      # port for external IP address (that you need to put in your browser)
-      # nodePort: 30000
-  # type: LoadBalancer
diff --git a/k8s-manifests/configmap.yaml b/k8s-manifests/configmap.yaml
new file mode 100644
index 0000000..3014616
--- /dev/null
+++ b/k8s-manifests/configmap.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: todo-app-config
+data:
+  PORT: 3000
+  # MONGODB_URL: mongodb://<mongo-service>:27017/todo-app
+  # mongodb-service.<namespace>?
+  MONGODB_URL: mongodb-service
diff --git a/app/k8s-manifests/deployment.yaml b/k8s-manifests/deployment.yaml
similarity index 79%
rename from app/k8s-manifests/deployment.yaml
rename to k8s-manifests/deployment.yaml
index 97eb0bf..2de3f43 100644
--- a/app/k8s-manifests/deployment.yaml
+++ b/k8s-manifests/deployment.yaml
@@ -1,7 +1,7 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  name: app-deployment
+  name: todo-app-deployment
   labels:
     app: todo-app
 spec:
@@ -24,8 +24,9 @@ spec:
         ports:
         - containerPort: 3000
           # imagePullPolicy: IfNotPresent
+        # env for mongodb username and pass?
         envFrom:
         - configMapRef:
-          name: app-config
+          name: todo-app-config
         - secretRef:
-          name: app-secrets
+          name: todo-app-secrets
diff --git a/app/registry-credentials.yaml b/k8s-manifests/gitlab-registry-credentials.yaml
similarity index 100%
rename from app/registry-credentials.yaml
rename to k8s-manifests/gitlab-registry-credentials.yaml
diff --git a/k8s-manifests/ingress.yaml b/k8s-manifests/ingress.yaml
new file mode 100644
index 0000000..6757622
--- /dev/null
+++ b/k8s-manifests/ingress.yaml
@@ -0,0 +1,23 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: todo-app-ingress
+  annotations:
+    kubernetes.io/ingress.class: "gce" # an external load-balancer
+    kubernetes.io/ingress.allow-http: "false" # disabling HTTP
+    kubernetes.io/ingress.global-static-ip-name: todoapp-ip # staging-todoapp-ip for staging
+    networking.gke.io/managed-certificates: todoapp-managed-cert # defined in the infrastructure repository
+spec:
+  # rules:
+  # - http:
+  #     paths:
+  #     - path: /*
+  #       pathType: ImplementationSpecific
+  #       backend:
+  #         serviceName: todo-app-service
+  #         servicePort: 80
+  defaultBackend:
+    service:
+      name: todo-app-service
+      port:
+        number: 8080
diff --git a/app/k8s-manifests/secrets.yaml b/k8s-manifests/secrets.yaml
similarity index 78%
rename from app/k8s-manifests/secrets.yaml
rename to k8s-manifests/secrets.yaml
index 9097a62..c61ce1a 100644
--- a/app/k8s-manifests/secrets.yaml
+++ b/k8s-manifests/secrets.yaml
@@ -1,7 +1,7 @@
 apiVersion: v1
 kind: Secret
 metadata:
-  name: app-secrets
+  name: todo-app-secrets
 type: Opaque
 data:
   JWT_SECRET: <jwt-secret in base64>
diff --git a/k8s-manifests/service.yaml b/k8s-manifests/service.yaml
new file mode 100644
index 0000000..4a69e79
--- /dev/null
+++ b/k8s-manifests/service.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: todo-app-service
+  annotations:
+    cloud.google.com/app-protocols: '{"https-port":"HTTPS","http-port":"HTTP"}'
+spec:
+  type: NodePort
+  selector:
+      app: todo-app
+  ports:
+    - name: https-port
+      port: 443
+      targetPort: 3000
+    - name: http-port
+      port: 8080
+      targetPort: 3000
-- 
GitLab