
/**
 *  Test salt models pipeline
 *  DEFAULT_GIT_REF
 *  DEFAULT_GIT_URL
 *  CREDENTIALS_ID
 */

def common = new com.mirantis.mk.Common()
def gerrit = new com.mirantis.mk.Gerrit()
def ssh = new com.mirantis.mk.Ssh()
def git = new com.mirantis.mk.Git()

def gerritRef
try {
  gerritRef = GERRIT_REFSPEC
} catch (MissingPropertyException e) {
  gerritRef = null
}

def defaultGitRef, defaultGitUrl
try {
    defaultGitRef = DEFAULT_GIT_REF
    defaultGitUrl = DEFAULT_GIT_URL
} catch (MissingPropertyException e) {
    defaultGitRef = null
    defaultGitUrl = null
}
def checkouted = false
def merged = false

def testMinion(minion, saltOpts)
{
  sh("""bash -c 'source /srv/salt/scripts/salt-master-init.sh;
        export SUDO=sudo;
        export DEBUG=1;
        export MASTER_HOSTNAME=${master}; reclass-salt -p ${minion} >  /tmp/${minion}.pillar_verify'""")
}

def setupandtest(master) {
  def img = docker.image("ubuntu:trusty")
  def saltOpts = "--retcode-passthrough --force-color"
  def common = new com.mirantis.mk.Common()
  def workspace = common.getWorkspace()

  img.inside("-u root:root -v ${workspace}:/srv/salt/reclass") {
    wrap([$class: 'AnsiColorBuildWrapper']) {
        sh("apt-get update; apt-get install  software-properties-common   python-software-properties -y")
        sh("add-apt-repository ppa:saltstack/salt -y")
        sh("apt-get update; apt-get install -y curl subversion git python-pip sudo")
        sh("sudo apt-get install -y salt-master salt-minion salt-ssh salt-cloud salt-doc")
        sh("svn export --force https://github.com/chnyda/salt-formulas/trunk/deploy/scripts /srv/salt/scripts")
        //configure git
        sh("git config --global user.email || git config --global user.email 'ci@ci.local'")
        sh("git config --global user.name  || git config --global user.name 'CI'")
        //
        sh("cd /srv/salt/reclass; test ! -e .gitmodules || git submodule update --init --recursive")
        sh("cd /srv/salt/reclass; git commit -am 'Fake branch update' || true")

        // setup iniot and verify salt master and minions
        withEnv(["SUDO=sudo","DEBUG=1", "MASTER_HOSTNAME=${master}"]){
            sh("bash -c 'source /srv/salt/scripts/salt-master-init.sh; system_config'")
            sh("bash -c 'source /srv/salt/scripts/salt-master-init.sh; saltmaster_bootstrap'")
            sh("bash -c 'source /srv/salt/scripts/salt-master-init.sh; saltmaster_init > /tmp/${master}.init'")
            sh("bash -c 'source /srv/salt/scripts/salt-master-init.sh; verify_salt_master'")
        }

        testSteps = [:]
        nodes = sh script:"ls /srv/salt/reclass/nodes/_generated"
        for (minion in nodes.tokenize()) {
          def basename = sh script: "basename ${minion} .yml", returnStdout: true
          testSteps = { testMinion(basename.trim())}
        }
        parallel testSteps
    }

  }

}

node("python&&docker") {
  try{
    stage("checkout") {
      if (gerritRef) {
        // job is triggered by Gerrit
        // test if change aren't already merged
        def gerritChange = gerrit.getGerritChange(GERRIT_NAME, GERRIT_HOST, GERRIT_CHANGE_NUMBER, CREDENTIALS_ID)
        merged = gerritChange.status == "MERGED"
        if(!merged){
          checkouted = gerrit.gerritPatchsetCheckout ([
            credentialsId : CREDENTIALS_ID
          ])
        } else{
          common.successMsg("Change ${GERRIT_CHANGE_NUMBER} is already merged, no need to gate them")
        }
      } else if(defaultGitRef && defaultGitUrl) {
          checkouted = gerrit.gerritPatchsetCheckout(defaultGitUrl, defaultGitRef, "HEAD", CREDENTIALS_ID)
      }
      if(checkouted){
        if (fileExists('classes/system')) {
          ssh.prepareSshAgentKey(CREDENTIALS_ID)
          dir('classes/system') {
            remoteUrl = git.getGitRemote()
            ssh.ensureKnownHosts(remoteUrl)
          }
          ssh.agentSh("git submodule init; git submodule sync; git submodule update --recursive")
        }
      }else if(!merged){
        throw new Exception("Cannot checkout gerrit patchset, GERRIT_REFSPEC and DEFAULT_GIT_REF is null")
      }
    }

    def nodes
    dir ('nodes') {
      nodes = sh script: "find -type f -name cfg*.yml", returnStdout: true
    }

    stage("test") {
      for (masterNode in nodes.tokenize()) {
        basename = sh script: "basename ${masterNode} .yml", returnStdout: true
        setupandtest(basename.trim())
      }

    }
  } catch (Throwable e) {
     // If there was an error or exception thrown, the build failed
     currentBuild.result = "FAILURE"
     throw e
  } finally {
     common.sendNotification(currentBuild.result,"",["slack"])
  }
}