# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:

# 1. terraform: make [self-destructing] VM [with microk8s]
# 2. terraform: retrieve VM's ephemeral IP (via terraform output ip) and write to file
# 3. bash: sed the IP into the kubeconfig
# 4. kubectl apply the application
# 5. run the test
# 6. destroy the VM

# (if any of steps 1-5 fail, #6 won't be reached, but self-destruct mechanism will kick in)

- id: 'init terraform' 
  name: 'gcr.io/$PROJECT_ID/terraform'
  args: ['init']
  waitFor: ['-']

- id: 'launch vm'
  name: 'gcr.io/$PROJECT_ID/terraform'
  args: [
    'apply',
    '-var=project-name=$PROJECT_ID',
    '-var=instance-name=test-$BUILD_ID',
    '-auto-approve'
  ]
  waitFor: ['init terraform']

- id: 'patch k8s config'
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args: ['-c','find k8s -type f | xargs sed -i "s/PROJECT_ID/$PROJECT_ID/g"']
  waitFor: ['-']

- id: 'patch kubeconfig'
  name: 'gcr.io/$PROJECT_ID/terraform'
  entrypoint: '/bin/bash'
  args:
    - '-c'
    - |
      echo $(terraform output ip) > _clusterip
      sed -i.sed-bak "s/CLUSTER_IP/"$(< _clusterip)"/" kubeconfig.microk8s
      cat kubeconfig.microk8s

      # loop until connection works
      # TODO: replace this with a looped kubectl connection    
      apt-get update && apt-get -y install curl

      for i in $$(seq 0 59); do
      
        status="$$(curl -sL -w "%{http_code}" -I "http://$$(< _clusterip):8080" -o /dev/null)" || status='000'
        
        if [[ $status == '200' ]]
        then
          echo "connected to kubernetes api"
          break
        else
            if [ $$i -gt 0 ]; then
              echo "unable to connect. retrying in 5s..."
              sleep 5
            fi
        fi
      done



  waitFor: ['launch vm']

- id: 'compile web app'
  name: 'gcr.io/cloud-builders/npm'
  dir: 'web'
  args: ['install']
  waitFor: ['-'] 

- id: 'web app unit tests'
  name: 'gcr.io/cloud-builders/npm'
  dir: 'web'
  args: ['test']
  waitFor: ['compile web app']

- id: 'build web'
  name: 'gcr.io/cloud-builders/docker'
  args: [
    'build',
    '--tag=web', 
    '--tag=gcr.io/$PROJECT_ID/web',
    '--cache-from', 'gcr.io/$PROJECT_ID/web:latest',
    'web/.',
  ]
  waitFor: ['web app unit tests']

- id: 'build db'
  name: 'gcr.io/cloud-builders/docker'
  args: [
    'build',
    '--tag=mysql',
    '--tag=gcr.io/$PROJECT_ID/mysql',
    '--cache-from', 'gcr.io/$PROJECT_ID/mysql:latest',
    'mysql/.',
  ]
  env:
  - "MYSQL_ROOT_PASSWORD=password"
  waitFor: ['-']

- id: 'push web'
  name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/web']
  waitFor: ['build web']

- id: 'push db'
  name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/mysql'] 
  waitFor: ['build db']

- id: 'deploy app'
  # use vanilla kubectl container b/c this isn't GKE
  name: 'bitnami/kubectl'
  args: [
    'apply', 
    '-f', 
    'k8s/', 
    '--kubeconfig=kubeconfig.microk8s'
    ] 
  waitFor: ['patch kubeconfig']

- id: 'get endpoint'
  name: 'gcr.io/cloud-builders/kubectl'
  entrypoint: 'bash'
  args: 
  - '-c'
  - |
    # determine which node port the service was exposed on
    get_nodeport() {
      kubectl get service cookieshop-web -o=jsonpath='{.spec.ports[0].nodePort}' --kubeconfig=kubeconfig.microk8s
    }

    until [[ -n "$(get_nodeport)" ]]; do
        echo "querying for nodeport"
        sleep 3
    done

    echo "$(get_nodeport)" > _nodeport
  waitFor: ['deploy app']  

- id: 'integration test'
  name: 'gcr.io/cloud-builders/curl'
  entrypoint: '/bin/bash'
  args: 
  - '-c'
  - |
    # cat _endpoint
    ### -r = retries; -i = interval; -k = keyword to search for ###
    ./test/test-connection.sh -r 20 -i 5 -u http://$(cat _clusterip):$(cat _nodeport) &&
    ./test/test-content.sh -r 20 -i 5 -u http://$(cat _clusterip):$(cat _nodeport) -k 'Chocolate Chip'
  waitFor: ['get endpoint']

- id: 'delete vm'
  name: 'gcr.io/$PROJECT_ID/terraform'
  args: [
    'destroy',
    '-var=project-name=$PROJECT_ID',
    '-var=instance-name=test-$BUILD_ID',
    '-auto-approve'
  ]
  waitFor: ['integration test']

timeout:
  3600s