default:
  image: $CI_REGISTRY_IMAGE:latest

variables:
  CAMPUS_IP: 138.26.48.47
  CHEAHA_IP: 172.20.10.9
  TEST_IP: 138.26.49.134
  ANSIBLE_REMOTE_TMP: "/tmp"
  AWS_DEFAULT_REGION: "bhm"
  AWS_HOST: "s3.lts.rc.uab.edu"
  OS_AUTH_TYPE: "v3applicationcredential"
  OS_AUTH_URL: "https://keystone.cloud.rc.uab.edu:5000/v3"
  OS_IDENTITY_API_VERSION: "3"
  OS_INTERFACE: "public"
  OS_REGION_NAME: "bhm1"
  PROXY_NETWORK: "proxy-net"
  PKR_VAR_flavor: "m1.medium-ruffner"
  PKR_VAR_source_image: "CentOS-7-x86_64-GenericCloud-2009"
  PKR_VAR_floating_ip_network: "uab-campus"
  PKR_VAR_security_groups: '["allow-ssh"]'
  PKR_VAR_skip_create_image: "false"
  PKR_VAR_ssh_username: "centos"
  PKR_VAR_networks: '["8cf2f12e-905d-46d9-bc70-b0897c65f75a"]'
  GIT_AUTHOR_NAME: "Gitlab runner"
  GIT_AUTHOR_EMAIL: "gitlab@runner"
  INSTANCE_FLAVOR: "m1.medium-ruffner"
  HTTP_PROXY_INSTANCE_NAME: "http-proxy"
  SSH_PROXY_INSTANCE_NAME: "ssh-proxy"

stages:
  - build
  - deploy

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "web"
    - if: $CI_PIPELINE_SOURCE == "schedule"

.get_build_date: &get_build_date
  - export BUILD_DATE=$(TZ=America/Chicago date +%Y-%m-%dT%H%M%S)
  - echo BUILD_DATE=${BUILD_DATE}

.update_ansible_repo: &update_ansible_repo
  - *get_build_date
  - |
    export EXT_REPO_DIR=$(basename -s .git $EXT_PR_TARGET_REPO)
    if [ ! -d $CI_PROJECT_DIR/$EXT_REPO_DIR ]; then
      git clone ${EXT_PR_TARGET_REPO} ${EXT_REPO_DIR}
      cd ${EXT_REPO_DIR}
      git remote add upstream ${EXT_PR_SRC_REPO}
      cd ..
    fi
  - cd ${EXT_REPO_DIR}
  - git config user.name "${GIT_AUTHOR_NAME}"
  - git config user.email "${GIT_AUTHOR_EMAIL}"
  - git checkout ${EXT_PR_TARGET_BRANCH}
  - git fetch origin ${EXT_PR_TARGET_BRANCH}
  - git merge origin/${EXT_PR_TARGET_BRANCH}
  - git checkout -b integration
  - git fetch upstream ${EXT_PR_SRC_BRANCH}
  - git merge upstream/${EXT_PR_SRC_BRANCH}
  # export vars into job artifacts
  - export EXT_REPO_HEAD=$(git rev-parse --short HEAD)
  - export EXT_PR_SRC_BRANCH_SHA=$(git rev-parse --short upstream/${EXT_PR_SRC_BRANCH})
  - export EXT_PR_TARGET_BRANCH_SHA=$(git rev-parse --short origin/${EXT_PR_TARGET_BRANCH})
  - cd ..
  - export PACKER_IMAGE_HEAD=$(git rev-parse --short HEAD)
  - echo EXT_REPO_HEAD=${EXT_REPO_HEAD} | tee -a $CI_PROJECT_DIR/image.env
  - echo EXT_PR_SRC_BRANCH_SHA=${EXT_PR_SRC_BRANCH_SHA} | tee -a $CI_PROJECT_DIR/image.env
  - echo EXT_PR_TARGET_BRANCH_SHA=${EXT_PR_TARGET_BRANCH_SHA} | tee -a $CI_PROJECT_DIR/image.env
  - echo PACKER_IMAGE_HEAD=${PACKER_IMAGE_HEAD} | tee -a $CI_PROJECT_DIR/image.env

.get_ansible_files: &get_ansible_files
  - s3cmd get --force -r --host=$AWS_HOST --host-bucket=$AWS_HOST s3://cheaha-cloud-ansible-files/ ansible/files/

.build_proxy_image_template: &build_proxy_image_template
  script:
    - *update_ansible_repo
    - *get_ansible_files
    # packer vars for job env
    - export PKR_VAR_flavor="${PROXY_BUILD_FLAVOR:-$PKR_VAR_flavor}"
    - export PKR_VAR_build_instance_name="${BUILD_TARGET}-${EXT_REPO_HEAD}"
    - export PKR_VAR_image_date_suffix=false
    - |
      if [ $CI_PIPELINE_SOURCE == 'merge_request_event' ]; then
        export PKR_VAR_image_name="${BUILD_TARGET}-PR-${CI_MERGE_REQUEST_IID}"
      elif [ $CI_PIPELINE_SOURCE == 'schedule' ]; then
        export PKR_VAR_image_name="${BUILD_TARGET}-${BUILD_DATE}"
      fi
    # Ansible var overrides
    - |
      if [ -n "${PROXY_ENABLE_VAR}" ]; then
        sed -i -E "s/(${PROXY_ENABLE_VAR}: ).*/\1true/" $EXT_REPO_DIR/group_vars/all
      fi
    - 'sed -i -E "s|(s3_endpoint: ).*|\1\"${S3_ENDPOINT}\"|" $EXT_REPO_DIR/group_vars/all'
    - 'sed -i -E "s/(lts_access_key: ).*/\1\"${AWS_ACCESS_KEY_ID}\"/" $EXT_REPO_DIR/group_vars/all'
    - 'sed -i -E "s/(lts_secret_key: ).*/\1\"${AWS_SECRET_ACCESS_KEY}\"/" $EXT_REPO_DIR/group_vars/all'
    - 'sed -i -E "s/(s3_shibboleth_bucket_name: ).*/\1\"${S3_SHIBBOLETH_BUCKET_NAME}\"/" $EXT_REPO_DIR/group_vars/all'
    - 'sed -i -E "s/(s3_shibboleth_object_name: ).*/\1\"${S3_SHIBBOLETH_OBJECT_NAME}\"/" $EXT_REPO_DIR/group_vars/all'
    - 'sed -i -E "s|(ssh_pub_key: ).*|\1\"{{ lookup(''file'', ''${SSH_PUB_KEY}'') }}\"|" $EXT_REPO_DIR/group_vars/all'
    # packer commands
    - packer init openstack-proxy
    - packer validate openstack-proxy
    - packer build -machine-readable openstack-proxy | tee proxy_build.log
    - export BUILT_PROXY_IMAGE_ID=$(grep 'Image:' proxy_build.log | awk '{print $4}')
    - echo BUILT_PROXY_IMAGE_ID=${BUILT_PROXY_IMAGE_ID} | tee -a $CI_PROJECT_DIR/image.env
    # set image properties with repo state
    - openstack image set --property EXT_PR_SRC_REPO=${EXT_PR_SRC_REPO} --property EXT_PR_SRC_BRANCH_SHA=${EXT_PR_SRC_BRANCH_SHA} --property EXT_PR_TARGET_REPO=${EXT_PR_TARGET_REPO} --property EXT_PR_TARGET_BRANCH_SHA=${EXT_PR_TARGET_BRANCH_SHA} --property PACKER_IMAGE_HEAD=${PACKER_IMAGE_HEAD} ${BUILT_PROXY_IMAGE_ID}
  artifacts:
    reports:
      dotenv: image.env

build_http_proxy_image:
  stage: build
  environment:
    name: build
  tags:
    - build
  variables:
    PROXY_ENABLE_VAR: "enable_http_proxy"
  <<: *build_proxy_image_template
  rules:
    - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "http-proxy"
      when: always

build_ssh_proxy_image:
  stage: build
  environment:
    name: build
  tags:
    - build
  variables:
    PROXY_ENABLE_VAR: "enable_ssh_proxy"
  <<: *build_proxy_image_template
  rules:
    - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "ssh-proxy"
      when: always

.build_login_image_template: &build_login_image_template
  script:
    - *update_ansible_repo
    - *get_ansible_files
    # packer vars for job env
    - export PKR_VAR_flavor="${PROXY_BUILD_FLAVOR:-$PKR_VAR_flavor}"
    - export PKR_VAR_build_instance_name="${BUILD_TARGET}-${EXT_REPO_HEAD}"
    - export PKR_VAR_image_date_suffix=false
    - |
      if [ $CI_PIPELINE_SOURCE == 'merge_request_event' ]; then
        export PKR_VAR_image_name="${BUILD_TARGET}-PR-${CI_MERGE_REQUEST_IID}"
      elif [ $CI_PIPELINE_SOURCE == 'schedule' ]; then
        export PKR_VAR_image_name="${BUILD_TARGET}-${BUILD_DATE}"
      fi
    # packer commands
    - packer init openstack-login
    - packer validate openstack-login
    - packer build -machine-readable openstack-login | tee login_build.log
    - export BUILT_LOGIN_IMAGE_ID=$(grep 'Image:' login_build.log | awk '{print $4}')
    - echo BUILT_LOGIN_IMAGE_ID=${BUILT_LOGIN_IMAGE_ID} | tee -a $CI_PROJECT_DIR/image.env
    # set image properties with repo state
    - openstack image set --property EXT_PR_SRC_REPO=${EXT_PR_SRC_REPO} --property EXT_PR_SRC_BRANCH_SHA=${EXT_PR_SRC_BRANCH_SHA} --property EXT_PR_TARGET_REPO=${EXT_PR_TARGET_REPO} --property EXT_PR_TARGET_BRANCH_SHA=${EXT_PR_TARGET_BRANCH_SHA} --property PACKER_IMAGE_HEAD=${CI_COMMIT_SHORT_SHA} ${BUILT_LOGIN_IMAGE_ID}
  artifacts:
    reports:
      dotenv: image.env

build_login_image:
  stage: build
  environment:
    name: build
  tags:
    - build
  <<: *build_login_image_template
  rules:
    - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "login"
      when: always

build_ood_image:
  stage: build
  environment:
    name: build
  tags:
    - build
  script:
    - *update_ansible_repo
    - *get_ansible_files
    # packer vars for job env
    - export PKR_VAR_flavor="${OOD_BUILD_FLAVOR:-$PKR_VAR_flavor}"
    - export PKR_VAR_build_instance_name="${BUILD_TARGET}-${EXT_REPO_HEAD}"
    - export PKR_VAR_image_date_suffix=false
    - export PKR_VAR_image_name="${BUILD_TARGET}-${BUILD_DATE}"
    - |
      if [ $ENV = 'knightly' ] || [ $ENV = 'prod' ]; then
        curl --header "PRIVATE-TOKEN: ${ANSIBLE_VAR_TOKEN}" \
        "${CI_API_V4_URL}/projects/2836/repository/files/knightly/raw?ref=main" \
        -o CRI_XCBC/group_vars/$ENV
        sed -i -E "s/(lts_access_key: ).*/\1\"${AWS_ACCESS_KEY_ID}\"/" CRI_XCBC/group_vars/$ENV
        sed -i -E "s/(lts_secret_key: ).*/\1\"${AWS_SECRET_ACCESS_KEY}\"/" CRI_XCBC/group_vars/$ENV
        sed -i -E "s/(user_register_app_key: ).*/\1\"${SELF_REG_APP_KEY}\"/" CRI_XCBC/group_vars/$ENV
        sed -i -E "s/(celery_user_password: ).*/\1\"${CELERY_PASSWD}\"/" CRI_XCBC/group_vars/$ENV
        sed -i -E "s|(ssh_pub_key: ).*|\1\"{{ lookup('file', '${SSH_PUB_KEY}') }}\"|" CRI_XCBC/group_vars/$ENV
        grep ssh_pub_key CRI_XCBC/group_vars/$ENV
      fi
    # packer commands
    - packer init openstack-ood
    - packer validate openstack-ood
    - packer build -machine-readable openstack-ood | tee ood_build.log
    - export BUILT_OOD_IMAGE_ID=$(grep 'Image:' ood_build.log | awk '{print $4}')
    - echo BUILT_OOD_IMAGE_ID=${BUILT_OOD_IMAGE_ID} | tee -a $CI_PROJECT_DIR/image.env
    # set image properties with repo state
    - openstack image set --property EXT_PR_SRC_REPO=${EXT_PR_SRC_REPO} --property EXT_PR_SRC_BRANCH_SHA=${EXT_PR_SRC_BRANCH_SHA} --property EXT_PR_TARGET_REPO=${EXT_PR_TARGET_REPO} --property EXT_PR_TARGET_BRANCH_SHA=${EXT_PR_TARGET_BRANCH_SHA} --property PACKER_IMAGE_HEAD=${CI_COMMIT_SHORT_SHA} ${BUILT_OOD_IMAGE_ID}
  artifacts:
    reports:
      dotenv: image.env
  rules:
    - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "ood"
      when: always

deploy_http_proxy_node:
  stage: deploy
  environment:
    name: $ENV
  tags:
    - build
  script:
    - openstack image set --accept $HTTP_PROXY_IMAGE_ID || true
    - FAILED=false
    - |
      cat > user_data.txt <<EOF
      #!/bin/bash
      cat >> /etc/NetworkManager/conf.d/90-dns-none.conf<<EEOF
      [main]
      dns=none
      EEOF
      systemctl reload NetworkManager
      echo "$DEV_KEY" >> /root/.ssh/authorized_keys
      ip route replace default via ${DEFAULT_GATEWAY_IP} dev eth0
      git clone ${CI_REPOSITORY_URL} /tmp/${CI_PROJECT_NAME}
      cd /tmp/${CI_PROJECT_NAME}
      git checkout ${CI_COMMIT_REF_NAME}
      cat >> ansible/hosts<<EEOF
      [$ENV]
      127.0.0.1
      EEOF
      ansible-playbook -c local -i ansible/hosts --extra-vars="$EXTRA_VARS" ansible/cluster.yml | tee -a /tmp/ansible.log
      rm -rf /tmp/${CI_PROJECT_NAME}
      EOF
    - |
      export cmd="openstack server create"
      cmd+=" -c id -f value --image $HTTP_PROXY_IMAGE_ID"
      cmd+=" --flavor $INSTANCE_FLAVOR"
      for security_group in ${SECURITY_GROUP_LIST[@]};
      do
        cmd+=" --security-group $security_group"
      done
      cmd+=" --user-data user_data.txt"
      if [ -n "$PROXY_NETWORK" ];then cmd+=" --network $PROXY_NETWORK"; fi
      if [ -n "$HTTP_PROXY_PORT" ];then cmd+=" --port $HTTP_PROXY_PORT"; fi
      cmd+=" --wait $HTTP_PROXY_INSTANCE_NAME"
    - export HTTP_PROXY_INSTANCE_ID=$(bash -c "$cmd")
    - |
      # Associate the floating IP(s) with the HTTP Proxy instance
      for HTTP_PROXY_FLOATING_IP in ${HTTP_PROXY_FLOATING_IP_LIST[@]};
      do
        echo "Associating FLOATING_IP $HTTP_PROXY_FLOATING_IP with HTTP_PROXY_INSTANCE_ID $HTTP_PROXY_INSTANCE_ID"
        openstack server add floating ip $HTTP_PROXY_INSTANCE_ID $HTTP_PROXY_FLOATING_IP
      done
  rules:
    - if: $PIPELINE_TARGET == "deploy" && $HTTP_PROXY_IMAGE_ID
      when: always

deploy_ssh_proxy_node:
  stage: deploy
  environment:
    name: $ENV
  tags:
    - build
  script:
    - openstack image set --accept $SSH_PROXY_IMAGE_ID || true
    - FAILED=false
    - |
      cat > user_data.txt <<EOF
      #!/bin/bash
      cat >> /etc/NetworkManager/conf.d/90-dns-none.conf<<EEOF
      [main]
      dns=none
      EEOF
      systemctl reload NetworkManager
      echo "$DEV_KEY" >> /root/.ssh/authorized_keys
      ip route replace default via ${DEFAULT_GATEWAY_IP} dev eth0
      git clone ${CI_REPOSITORY_URL} /tmp/${CI_PROJECT_NAME}
      cd /tmp/${CI_PROJECT_NAME}
      git checkout ${CI_COMMIT_REF_NAME}
      cat >> ansible/hosts<<EEOF
      [$ENV]
      127.0.0.1
      EEOF
      ansible-playbook -c local -i ansible/hosts --extra-vars="$EXTRA_VARS" ansible/cluster.yml | tee -a /tmp/ansible.log
      rm -rf /tmp/${CI_PROJECT_NAME}
      EOF
    - |
      export cmd="openstack server create"
      cmd+=" -c id -f value --image $SSH_PROXY_IMAGE_ID"
      cmd+=" --flavor $INSTANCE_FLAVOR"
      for security_group in ${SECURITY_GROUP_LIST[@]};
      do
        cmd+=" --security-group $security_group"
      done
      cmd+=" --user-data user_data.txt"
      if [ -n "$PROXY_NETWORK" ];then cmd+=" --network $PROXY_NETWORK"; fi
      if [ -n "$SSH_PROXY_PORT" ];then cmd+=" --port $SSH_PROXY_PORT"; fi
      cmd+=" --wait $SSH_PROXY_INSTANCE_NAME"
    - export SSH_PROXY_INSTANCE_ID=$(bash -c "$cmd")
    - |
      # Associate the floating IP(s) with the SSH Proxy instance
      for SSH_PROXY_FLOATING_IP in ${SSH_PROXY_FLOATING_IP_LIST[@]};
      do
        echo "Associating FLOATING_IP $SSH_PROXY_FLOATING_IP with SSH_PROXY_INSTANCE_ID $SSH_PROXY_INSTANCE_ID"
        openstack server add floating ip $SSH_PROXY_INSTANCE_ID $SSH_PROXY_FLOATING_IP
      done
  rules:
    - if: $PIPELINE_TARGET == "deploy" && $SSH_PROXY_IMAGE_ID
      when: always

deploy_login_node:
  stage: deploy
  environment:
    name: $ENV
  tags:
    - build
  script:
    - openstack image set --accept $LOGIN_IMAGE_ID || true
    - FAILED=false
    - |
      cat > user_data.txt <<EOF
      #!/bin/bash
      cat >> /etc/NetworkManager/conf.d/90-dns-none.conf<<EEOF
      [main]
      dns=none
      EEOF
      systemctl reload NetworkManager
      echo "$DEV_KEY" >> /root/.ssh/authorized_keys
      ip route replace default via ${DEFAULT_GATEWAY_IP} dev eth0
      git clone ${CI_REPOSITORY_URL} /tmp/${CI_PROJECT_NAME}
      cd /tmp/${CI_PROJECT_NAME}
      git checkout ${CI_COMMIT_REF_NAME}
      cat >> ansible/hosts<<EEOF
      [$ENV]
      127.0.0.1
      EEOF
      s3cmd get --force -r --access_key=$AWS_ACCESS_KEY_ID --secret_key=$AWS_SECRET_ACCESS_KEY --host=$AWS_HOST --host-bucket=$AWS_HOST s3://cheaha-cloud-ansible-files/ /tmp/${CI_PROJECT_NAME}/ansible/files/ 
      ansible-playbook -c local -i ansible/hosts --extra-vars="$EXTRA_VARS" ansible/cluster.yml | tee -a /tmp/ansible.log
      rm -rf /tmp/${CI_PROJECT_NAME}
      EOF
    - |
      export cmd="openstack server create"
      cmd+=" -c id -f value --image $LOGIN_IMAGE_ID"
      cmd+=" --flavor $INSTANCE_FLAVOR"
      for security_group in ${SECURITY_GROUP_LIST[@]};
      do
        cmd+=" --security-group $security_group"
      done
      cmd+=" --user-data user_data.txt"
      if [ -n "$INSTANCE_NETWORK" ];then cmd+=" --network $INSTANCE_NETWORK"; fi
      if [ -n "$LOGIN_PORT" ];then cmd+=" --port $LOGIN_PORT"; fi
      cmd+=" --wait $LOGIN_INSTANCE_NAME"
    - export LOGIN_INSTANCE_ID=$(bash -c "$cmd")
    - |
      # Associate the floating IP(s) with the SSH Proxy instance
      for LOGIN_FLOATING_IP in ${LOGIN_FLOATING_IP_LIST[@]};
      do
        echo "Associating FLOATING_IP $LOGIN_FLOATING_IP with LOGIN_INSTANCE_ID $LOGIN_INSTANCE_ID"
        openstack server add floating ip $LOGIN_INSTANCE_ID $LOGIN_FLOATING_IP
      done
  rules:
    - if: $PIPELINE_TARGET == "deploy" && $LOGIN_IMAGE_ID
      when: always