image: docker:stable
services:
    - docker:dind
 
stages:
    - metabuild
    - build
    - static_tests   
    - dynamic_tests     
    - deployment

# build the container that further steps will run in in order to avoid duplicating instructions between steps
metabuild:
    stage: metabuild
    before_script:
        - echo $REGISTRY_PROD_PASSWORD | docker login $REGISTRY_PROD -u $REGISTRY_PROD_USERNAME --password-stdin
    script:
        - docker build -f pica-ci/Dockerfile . -t $REGISTRY_PROD/pica-ci
        - docker push $REGISTRY_PROD/pica-ci:latest
    tags: [build]
    only:
        changes:
            - pica-dokuwiki/*
        
# build the container that was modified
build:
    stage: build
    image: $REGISTRY_PROD/pica-ci:latest
    before_script:
        - echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin
        - echo $MODIFIED_IMAGE
        - source /etc/profile.d/ci-variables
    script:
        - docker build -f $MODIFIED_IMAGE/Dockerfile $MODIFIED_IMAGE -t $REGISTRY/ci-builds/$CI_COMMIT_SHA
        - docker push $REGISTRY/ci-builds/$CI_COMMIT_SHA
    after_script:
        - docker logout $REGISTRY        
    tags: [build]
    only:
        changes:
            - pica-dokuwiki/*

# run CoreOS' Clair and make the CI failed if a critical vulnerability isn't in the whitelist
clair:
    stage: static_tests
    image: $REGISTRY_PROD/pica-ci:latest
    before_script:
        - echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin
        - docker pull $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest
        - docker logout $REGISTRY
        - source /etc/profile.d/ci-variables
    script:
        - docker run -d --name db arminc/clair-db:latest
        - docker run -p 6060:6060 -d --link db:postgres --name clair --restart on-failure arminc/clair-local-scan:v2.0.6
        - wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
        - mv clair-scanner_linux_amd64 clair-scanner
        - chmod +x clair-scanner
        - while( ! wget -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; done 
        - ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r clair-report.json -l clair.log -w $MODIFIED_IMAGE/clair-whitelist.yml --threshold="High" $REGISTRY/ci-builds/$CI_COMMIT_SHA 
    artifacts:
        paths:
            - clair-report.json
            - clair.log
    tags: [build]
    only:
        changes:
            - pica-dokuwiki/*
    allow_failure: false

# run docker-bench-security and upload the results
docker-bench-security:
    stage: dynamic_tests
    image: $REGISTRY_PROD/pica-ci:latest
    before_script:
        - echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin
        - docker pull $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest
        - docker logout $REGISTRY
        - source /etc/profile.d/ci-variables
        - sed -i -e "s/$MODIFIED_IMAGE_FULL/$REGISTRY\/ci-builds\/$CI_COMMIT_SHA:latest/g" $MODIFIED_IMAGE/docker-compose.yml
        # remove links to external networks to be able to start the container locally 
        - sed -i -e '/networks/,+3d' $MODIFIED_IMAGE/docker-compose.yml
    script:
        # if secrets.example files exist, remove the .example extension to be able to start the container
        - if [[ -d $MODIFIED_IMAGE/secrets ]]; then for i in $MODIFIED_IMAGE/secrets/* ; do cp $i $(echo $i| cut -d '.' -f1,2); done; fi;
        - cd $MODIFIED_IMAGE
        - docker-compose up -d
        - git clone https://github.com/docker/docker-bench-security.git
        - cd docker-bench-security
        - sh docker-bench-security.sh -c container_images,container_runtime,docker_security_operations -e check_5_12,check_4_1 -l ../../report.txt
    artifacts:
        paths:
            - report.txt
    after_script:
        - docker logout $REGISTRY 
    tags: [build]
    only:
        changes:
            - pica-dokuwiki/*

# automatically deploy the container on pica01-test
deployment-test: 
    stage: deployment
    image: $REGISTRY_PROD/pica-ci:latest
    before_script:
        - source /etc/profile.d/ci-variables
        - export DOCKER_HOST=tcp://pica01-test.picasoft.net:2376
        - export DOCKER_TLS_VERIFY=1
        - export DOCKER_CERT_PATH=/tmp/certs
        - mkdir -p $DOCKER_CERT_PATH
        - echo "$DEV_DOCKER_CA_CERT" > $DOCKER_CERT_PATH/ca.pem
        - echo "$DEV_DOCKER_CLIENT_CERT" > $DOCKER_CERT_PATH/cert.pem
        - echo "$DEV_DOCKER_CLIENT_KEY" > $DOCKER_CERT_PATH/key.pem
    script:        
        - echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin     
        - docker pull $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest
        - docker tag $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest  $MODIFIED_IMAGE_FULL
        - cd $MODIFIED_IMAGE
        - sed -i -e  s/picasoft.net/test.picasoft.net/g docker-compose.yml
        - if [[ $(docker container ls --format "{{.Names}}" | grep $CONTAINER_NAME) ]]; then docker stop $CONTAINER_NAME | xargs docker rm; fi
        - docker-compose up -d --force-recreate --remove-orphans $CONTAINER_NAME
    after_script:
        - rm -rf $DOCKER_CERT_PATH
        - docker logout $REGISTRY
    tags: [build]
    only:
        changes:
            - pica-dokuwiki/*

# automatically deploy the container on the production host associated with the modified image
# this will only happen after manually triggering the deployment
deployment-prod: 
    stage: deployment
    image: $REGISTRY_PROD/pica-ci:latest
    before_script:
        - source /etc/profile.d/ci-variables
        - TMP_DOCKER_CA_CERT="${HOST}_DOCKER_CA_CERT" && eval DOCKER_CA_CERT_VARIABLE=\$$TMP_DOCKER_CA_CERT
        - TMP_DOCKER_CLIENT_CERT="${HOST}_DOCKER_CLIENT_CERT" && eval DOCKER_CLIENT_CERT_VARIABLE=\$$TMP_DOCKER_CLIENT_CERT
        - TMP_DOCKER_CLIENT_KEY="${HOST}_DOCKER_CLIENT_KEY" && eval DOCKER_CLIENT_KEY_VARIABLE=\$$TMP_DOCKER_CLIENT_KEY
        - export DOCKER_HOST=tcp://$HOST.picasoft.net:2376
        - export DOCKER_TLS_VERIFY=1
        - export DOCKER_CERT_PATH=/tmp/certs
        - mkdir -p $DOCKER_CERT_PATH
        - echo "$DOCKER_CA_CERT_VARIABLE" > $DOCKER_CERT_PATH/ca.pem
        - echo "$DOCKER_CLIENT_CERT_VARIABLE" > $DOCKER_CERT_PATH/cert.pem
        - echo "$DOCKER_CLIENT_KEY_VARIABLE" > $DOCKER_CERT_PATH/key.pem
    script:  
        - echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin
        - docker pull $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest 
        - docker tag $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest  $MODIFIED_IMAGE_FULL
        - cd $MODIFIED_IMAGE
        - if [[ $(docker container ls --format "{{.Names}}" | grep $CONTAINER_NAME) ]]; then docker stop $CONTAINER_NAME | xargs docker rm; fi
        - docker-compose up -d --force-recreate --remove-orphans $CONTAINER_NAME
    after_script:
        - docker tag $REGISTRY/ci-builds/$CI_COMMIT_SHA:latest $REGISTRY_PROD/$MODIFIED_IMAGE_FULL
        - docker push $REGISTRY_PROD/$MODIFIED_IMAGE_FULL
        - rm -rf $DOCKER_CERT_PATH
        - docker logout $REGISTRY
    tags: [build]
    only:
        changes:
            - pica-dokuwiki/*
    when: manual