Using salt-pepper to connect SALT_MASTER from Jenkins slaves
Due to specific Jenkins behavior of groovy interpreter it is impossible
to connect to SALT_MASTER_IP from Jenkins slaves. The solution has been
suggested by Jakub Josef so in order to cope with this issue salt-pepper
is used to connect to SALT_MASTER_IP from slaves.
Change-Id: I6537de0937383f6688224e609cb730e62a993b37
diff --git a/src/com/mirantis/mk/Python.groovy b/src/com/mirantis/mk/Python.groovy
index b95275f..29f471f 100644
--- a/src/com/mirantis/mk/Python.groovy
+++ b/src/com/mirantis/mk/Python.groovy
@@ -283,3 +283,13 @@
echo(data)
return data
}
+
+/**
+ * Install salt-pepper in isolated environment
+ *
+ * @param path Path where virtualenv is created
+ */
+def setupPepperVirtualenv(path) {
+ requirements = ['salt-pepper']
+ setupVirtualenv(path, 'python2', requirements)
+}
\ No newline at end of file
diff --git a/src/com/mirantis/mk/Salt.groovy b/src/com/mirantis/mk/Salt.groovy
index 755dcd5..853965e 100644
--- a/src/com/mirantis/mk/Salt.groovy
+++ b/src/com/mirantis/mk/Salt.groovy
@@ -22,7 +22,6 @@
"creds": common.getCredentials(credentialsId)
]
params["authToken"] = saltLogin(params)
-
return params
}
@@ -43,7 +42,7 @@
}
/**
- * Run action using Salt API
+ * Run action using Salt API (using plain HTTP request from Jenkins master)
*
* @param master Salt connection object
* @param client Client type
@@ -66,7 +65,6 @@
'client': client,
'expr_form': target.type,
]
-
if(batch != null && ( (batch instanceof Integer && batch > 0) || (batch instanceof String && batch.contains("%")))){
data['client']= "local_batch"
data['batch'] = batch
@@ -92,6 +90,54 @@
}
/**
+ * Run action using Salt API (using salt pepper from slave shell)
+ *
+ * @param master Salt connection object
+ * @param client Client type
+ * @param target Target specification, eg. for compound matches by Pillar
+ * data: ['expression': 'I@openssh:server', 'type': 'compound'])
+ * @param function Function to execute (eg. "state.sls")
+ * @param batch Batch param to salt (integer or string with percents)
+ * @param args Additional arguments to function
+ * @param kwargs Additional key-value arguments to function
+ * @param timeout Additional argument salt api timeout
+ * @param read_timeout http session read timeout
+ */
+@NonCPS
+def runSaltCommandPepper(pepperVenv, client, target, function, batch = null, args = null, kwargs = null, timeout = -1, read_timeout = -1) {
+ def http = new com.mirantis.mk.Http()
+
+ data = [
+ 'tgt': target.expression,
+ 'fun': function,
+ 'client': client,
+ 'expr_form': target.type,
+ ]
+ if(batch != null && ( (batch instanceof Integer && batch > 0) || (batch instanceof String && batch.contains("%")))){
+ data['client']= "local_batch"
+ data['batch'] = batch
+ }
+
+ if (args) {
+ data['arg'] = args
+ }
+
+ if (kwargs) {
+ data['kwarg'] = kwargs
+ }
+
+ if (timeout != -1) {
+ data['timeout'] = timeout
+ }
+
+ headers = [
+ 'X-Auth-Token': "${master.authToken}"
+ ]
+
+ return runPepperCommand(data, pepperVenv)
+}
+
+/**
* Return pillar for given master and target
* @param master Salt connection object
* @param target Get pillar target
@@ -637,3 +683,52 @@
}
runSaltProcessStep(master, 'I@salt:master', 'cmd.run', ["git -C ${reclass_dir} update-index --skip-worktree classes/cluster/overrides.yml"])
}
+
+/**
+* Execute salt commands via salt-api with
+* CLI client salt-pepper
+*
+* @param data Salt command map
+* @param venv Path to virtualenv with
+*/
+
+def runPepperCommand(data, venv) {
+ def python = new com.mirantis.mk.Python()
+ def dataStr = new groovy.json.JsonBuilder(data).toString()
+
+ def pepperCmd = "pepper -c ${venv}/pepperrc --make-token --json \'${dataStr}\'"
+
+ if (venv) {
+ output = python.runVirtualenvCommand(venv, pepperCmd)
+ } else {
+ echo("[Command]: ${pepperCmd}")
+ output = sh (
+ script: pepperCmd,
+ returnStdout: true
+ ).trim()
+ }
+
+ return new groovy.json.JsonSlurperClassic().parseText(output)
+}
+
+/**
+* Create config file for pepper
+*
+* @param url SALT_MASTER URL
+* @param credentialsId credentials to SALT_API
+* @param path path to pepper env
+*/
+def createPepperEnv(url, credentialsId, path) {
+ def common = new com.mirantis.mk.Common()
+ rcFile = "${path}/pepperrc"
+ creds = common.getPasswordCredentials(credentialsId)
+ rc = """\
+[main]
+SALTAPI_EAUTH=pam
+SALTAPI_URL=${url}
+SALTAPI_USER=${creds.username}
+SALTAPI_PASS=${creds.password.toString()}
+"""
+ writeFile file: rcFile, text: rc
+ return rcFile
+}