pipeline {
  agent {
    label "swarm"
  }
  environment {
    DOCKER_REGISTRY='dev-registry.infoclinica.ru:5000'
    DOCKER_IMAGE='ovpn-rsa'
    SERVICE_NAME="ovpn-rsa_server"
    PKI_GIT_URL='ssh://git@git.sdsys.ru:8022/iru/openvpn-pki.git'
    PKI_GIT_NAME='openvpn-pki'
    OVPN_GIT_URL='ssh://git@git.sdsys.ru:8022/iru/openvpn.git'
    OVPN_GIT_DIR='openvpn'
    JENKINS_MAIL='jenkins.dev@sdsys.ru'
    SMTP_SERVER='mail.sdsys.ru'
    DOCKER_CERT_PATH='/run/secrets/swarm'
    CLUSTER_NAME='dev-iru-swarm.infoclinica.lan'
    COMMAND=''
  }
  parameters {
    string(
      name: "branch",
      defaultValue: "97009",
      description: "Which branch to use"
    )
    choice (
      choices: 'keygen\nrevoke',
      description: 'Whats is action?',
      name: 'TASK_ACTION')
    choice (
      choices: 'client\nadmin',
      description: 'Whats is mode?',
      name: 'MODE')
    string(
      name: "client_mail",
      defaultValue: "tomishinets.v@sdsys.ru",
      description: "Email which has to be recieved certs and key"
    )
    string(
      name: "key_name",
      defaultValue: "test",
      description: "The names for generation keys and certs."
    )
    string(
      name: "mailto",
      defaultValue: "tomishinets.v@sdsys.ru",
      description: "Email which has to be notified."
    )
  }
  stages {
    stage("Pull repo") {
      steps {
        withCredentials([sshUserPrivateKey(credentialsId: 'provision', keyFileVariable: 'GIT_SSH_KEY', passphraseVariable: '', usernameVariable: 'GIT_SSH_USERNAME')]) {
          sh '''GIT_SSH_COMMAND='ssh -i ${GIT_SSH_KEY} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
                git clone ${PKI_GIT_URL}
                cd ${WORKSPACE}/${PKI_GIT_NAME} && git checkout ${branch}
             '''
        }
      }
    }
    stage("Generate Keys and Certs or Revoke") {
      steps {
        script {
          switch (TASK_ACTION) {
            case 'keygen':
              def cert = "${WORKSPACE}/${PKI_GIT_NAME}/open/easy-rsa/client_keys/sds-${key_name}.zip"
              if (fileExists(cert)) {
                currentBuild.result = 'ABORTED'
                error ("Cert already exist!!!")
              return
              }
              COMMAND ="keygen.sh"
              break
            case 'revoke':
              def cert = "${WORKSPACE}/${PKI_GIT_NAME}/open/easy-rsa/client_keys/sds-${key_name}.zip"
              if (!fileExists(cert)) {
                currentBuild.result = 'ABORTED'
                error ("Cert doesn't exist!!!")
              return
              }
              COMMAND ="revoke.sh"
              break
          }
          echo "Running ${DOCKER_REGISTRY}/iru/${DOCKER_IMAGE}:latest."
          withCredentials([sshUserPrivateKey(credentialsId: 'provision', keyFileVariable: 'GIT_SSH_KEY', passphraseVariable: '', usernameVariable: 'GIT_SSH_USERNAME')]) {
            sh """set +x
                  docker pull $DOCKER_REGISTRY/iru/$DOCKER_IMAGE:latest 
                  docker run -i --rm -e TZ=Europe/Moscow -e mode=keygen -e "SSHKEY=`cat ${GIT_SSH_KEY}`" \
                  -e git_url=${PKI_GIT_URL} -e git_dir=${PKI_GIT_NAME} \
                  $DOCKER_REGISTRY/iru/$DOCKER_IMAGE:latest /tmp/$COMMAND $key_name $branch
               """
          }
        }
      }
    }
    stage("Pull new version of REPOs") {
      steps {
        script {
          echo "Delete old repo version"
          sh 'rm -rf ${WORKSPACE}/${PKI_GIT_NAME} && rm -rf ${WORKSPACE}/${OVPN_GIT_DIR}'
          withCredentials([sshUserPrivateKey(credentialsId: 'provision', keyFileVariable: 'GIT_SSH_KEY', passphraseVariable: '', usernameVariable: 'GIT_SSH_USERNAME')]) {
            sh '''GIT_SSH_COMMAND='ssh -i ${GIT_SSH_KEY} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
                  git clone ${OVPN_GIT_URL}
                  cd ${WORKSPACE}/${OVPN_GIT_DIR} && git checkout ${branch} && cd ${WORKSPACE}
                  GIT_SSH_COMMAND='ssh -i ${GIT_SSH_KEY} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
                  git clone ${PKI_GIT_URL}
                  cd ${WORKSPACE}/${PKI_GIT_NAME} && git checkout ${branch}
               '''
          }
        }
      }
    }
    stage("Generate configs") {
      when {
        expression { params.TASK_ACTION == 'keygen' }
      }
      steps {
        script {
          switch (MODE) {
            case 'client':
              file = "${WORKSPACE}/${OVPN_GIT_DIR}/ip_client.txt"
              break
            case 'admin':
              file = "${WORKSPACE}/${OVPN_GIT_DIR}/ip_admin.txt"
              break
          }
          string ip = readFile(file)
          split = ip.tokenize(".")
          if (split[3].toInteger() >= 254) {
            currentBuild.result == 'FAILURE'
            error ("The last oktet => 254!!!")
            return
          } else {
              split[3] = (split[3].toInteger() + 1) + ""
              def newIp = split.join(".")
              string txt = split[3].toString()
              writeFile file: file, text: newIp

              def conf = "${WORKSPACE}/${OVPN_GIT_DIR}/${OVPN_GIT_DIR}/ccd/${key_name}"
              writeFile file: conf, text: "ifconfig-push " + newIp + " 255.255.0.0"
          }
          withCredentials([sshUserPrivateKey(credentialsId: 'provision', keyFileVariable: 'GIT_SSH_KEY', passphraseVariable: '', usernameVariable: 'GIT_SSH_USERNAME')]) {
            sh '''cd ${OVPN_GIT_DIR}
                  echo "Add new config for ${key_name}" > ../commit.txt
                  git add -A
                  git config --global user.email "${JENKINS_MAIL}"
                  git config --global user.name "Jenkins"
                  git commit -F ../commit.txt
                  GIT_SSH_COMMAND='ssh -i ${GIT_SSH_KEY} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
                  git push origin ${branch}
               '''
          }
        }
      }
    }
    stage("Send key, certs and config with email") {
      when {
        expression { params.TASK_ACTION == 'keygen' }
      }
      steps {
        script {
          fileZip = "${WORKSPACE}/${PKI_GIT_NAME}/open/easy-rsa/client_keys/sds-${key_name}.zip"
          if ( !fileExists("${fileZip}")) {
            currentBuild.result == 'FAILURE'
            return
          } else {
            withEnv(["zip=${fileZip}"]) {
              withCredentials([usernamePassword(credentialsId: 'jenkins', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
                sh '''echo "Ваши ключ, сертификаты и конфигурационный файл для подключения к infoclinica.ru" | email -s "Your Certs and Key" \
                      -f ${JENKINS_MAIL} \
                      -r ${SMTP_SERVER} \
                      -m login \
                      -u ${USERNAME} \
                      -i ${PASSWORD} \
                      -a ${zip} \
                      ${client_mail}
                   '''
              }
            }
          } 
        }
      }
    }
    stage("Update ccd-files and crl.pem") {
      steps {
        script {
          def NODE = sh (script: "DOCKER_HOST=tcp://${CLUSTER_NAME}:2376 DOCKER_TLS_VERIFY=1 docker service ps \${SERVICE_NAME} --format '{{.Node}}' --filter desired-state=Running" , returnStdout: true).trim()
          sh "if [ -z ${NODE} ]; then echo '${SERVICE_NAME} does not running'; exit 1; fi"
          def container_id = sh (script: "DOCKER_HOST=tcp://${NODE}:2376 DOCKER_TLS_VERIFY=1 docker ps -q -f label=ru.sdsys.subcontainer=\${SERVICE_NAME}" , returnStdout: true).trim()
          sh "DOCKER_HOST=tcp://${NODE}:2376 DOCKER_TLS_VERIFY=1 docker cp ${WORKSPACE}/${OVPN_GIT_DIR}/${OVPN_GIT_DIR}/ccd/ ${container_id}:/etc/${OVPN_GIT_DIR}/persist"
          sh "DOCKER_HOST=tcp://${NODE}:2376 DOCKER_TLS_VERIFY=1 docker cp ${WORKSPACE}/${PKI_GIT_NAME}/open/easy-rsa/keys/stonevpn.crl ${container_id}:/etc/${OVPN_GIT_DIR}/persist/stonevpn.crl"

        }
      }
    }
  }  
  post {
    always {
      echo "CleaningUp work directory"
      deleteDir()
    }
    failure {
      mail charset: 'UTF-8',
           subject: "Jenkins build ERROR",
           mimeType: 'text/html',
           to: "${mailto}",
           body: "<b>ATTENTION!!!</b> <b><br> Jenkins job failed.\n\n <b><br>Project Name:</b> ${env.JOB_NAME} <b><br>\nBuild Number:</b> ${env.BUILD_NUMBER} <b><br>\nURL Build:</b> ${RUN_DISPLAY_URL}"
    }
    aborted {
      mail charset: 'UTF-8',
           subject: "Jenkins build ERROR",
           mimeType: 'text/html',
           to: "${client_mail}",
           body: "<b>ATTENTION!!!</b> <b><br> Jenkins job aborted.\n\n <b><br> The CNAME ${key_name} is already exists!\n\n <b><br>Project Name:</b> ${env.JOB_NAME} <b><br>\nBuild Number:</b> ${env.BUILD_NUMBER} <b><br>\nURL Build:</b> ${RUN_DISPLAY_URL}"
    }
  }
}