1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-28 05:47:08 +02:00

Provide Additional pod properties for dockerExecuteOnKubernetes (#2051)

Provide additional pod properties for dockerExecuteOnKubernetes

Co-authored-by: Kay Wegner <kay.wegner@sap.com>
This commit is contained in:
Marcus Holl 2020-10-02 12:56:16 +02:00 committed by GitHub
parent 9992881c37
commit b2b4278b34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 4 deletions

View File

@ -25,6 +25,7 @@ import static org.junit.Assert.assertThat
import static org.junit.Assert.assertTrue
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertFalse
import static org.junit.Assert.assertNotNull
import static org.junit.Assert.assertNull
class DockerExecuteOnKubernetesTest extends BasePiperTest {
@ -64,6 +65,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
def securityContext
def inheritFrom
def yamlMergeStrategy
def podSpec
Map resources = [:]
List stashList = []
@ -76,6 +78,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
containerCommands = []
resources = [:]
bodyExecuted = false
podSpec = null
JenkinsUtils.metaClass.static.isPluginActive = { def s -> new PluginMock(s).isActive() }
helper.registerAllowedMethod('sh', [Map.class], { return whichDockerReturnValue })
helper.registerAllowedMethod('container', [Map.class, Closure.class], { Map config, Closure body ->
@ -93,7 +96,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
inheritFrom = options.inheritFrom
yamlMergeStrategy = options.yamlMergeStrategy
podNodeSelector = options.nodeSelector
def podSpec = new JsonSlurper().parseText(options.yaml) // this yaml is actually json
podSpec = new JsonSlurper().parseText(options.yaml) // this yaml is actually json
def containers = podSpec.spec.containers
securityContext = podSpec.spec.securityContext
@ -585,6 +588,89 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
assertThat(namespace, is(equalTo(expectedNamespace)))
}
@Test
void testDockerExecuteWithAdditionalPodProperties() {
nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [
additionalPodProperties: [
tolerations:[
[
key: "key1",
operator: "Equal",
value: "value1",
effect: "NoSchedule",
],
[
key: "key2",
operator: "Equal",
value: "value2",
effect: "NoExecute",
],
],
subdomain: 'foo',
shareProcessNamespace: false
]
]]]
stepRule.step.dockerExecuteOnKubernetes(
script: nullScript,
juStabUtils: utils,
dockerImage: 'maven:3.5-jdk-8-alpine',
) { bodyExecuted = true }
assertTrue(bodyExecuted)
assertEquals(
[
[
"key": "key1",
"operator": "Equal",
"value": "value1",
"effect": "NoSchedule"
],
[
"key": "key2",
"operator": "Equal",
"value": "value2",
"effect": "NoExecute"
]
], podSpec.spec.tolerations)
assertEquals('foo', podSpec.spec.subdomain)
assertFalse(podSpec.spec.shareProcessNamespace)
assertThat(loggingRule.log, containsString('Additional pod properties found ([tolerations, subdomain, shareProcessNamespace]). Providing additional pod properties is some kind of expert mode. In case of any problems caused by these additional properties only limited support can be provided.'))
}
@Test
void testDockerExecuteWithAdditionalPodPropertiesContainerPropertyIsNotOverwritten() {
nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [
additionalPodProperties: [
containers:[
[
some: "stupid",
stuff: "here",
]
],
subdomain: 'foo',
shareProcessNamespace: false,
]
]]]
stepRule.step.dockerExecuteOnKubernetes(
script: nullScript,
juStabUtils: utils,
dockerImage: 'maven:3.5-jdk-8-alpine',
) { bodyExecuted = true }
assertTrue(bodyExecuted)
// This is not contained in the configuration above.
assertNotNull(podSpec.spec.containers[0].name)
// This is contained in the config above.
assertNull(podSpec.spec.some)
assertNull(podSpec.spec.stuff)
assertEquals('foo', podSpec.spec.subdomain)
assertFalse(podSpec.spec.shareProcessNamespace)
}
@Test
void testDockerExecuteOnKubernetesWithSecurityContext() {
def expectedSecurityContext = [runAsUser: 1000, fsGroup: 1000]

View File

@ -29,6 +29,10 @@ import groovy.transform.Field
* Allows to specify the shell to be used for execution of commands.
*/
'containerShell',
/**
* Kubernetes only: Allows to specify additional pod properties. For more details see step `dockerExecuteOnKubernetes`
*/
'additionalPodProperties',
/**
* Environment variables to set in the container, e.g. [http_proxy: 'proxy:8080'].
*/
@ -183,6 +187,7 @@ void call(Map parameters = [:], body) {
}
def dockerExecuteOnKubernetesParams = [
script: script,
additionalPodProperties: config.additionalPodProperties,
containerName: config.dockerName,
containerCommand: config.containerCommand,
containerShell: config.containerShell,

View File

@ -33,6 +33,7 @@ import hudson.AbortException
* @parentConfigKey jenkinsKubernetes
*/
'inheritFrom',
'additionalPodProperties',
'resources',
/**
* Print more detailed information into the log.
@ -41,6 +42,26 @@ import hudson.AbortException
'verbose'
]
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
/**
* Additional pod specific configuration. Map with the properties names
* as key and the corresponding value as value. The value can also be
* a nested structure.
* The properties will be added to the pod spec inside node `spec` at the
* same level like e.g. `containers`.
* This property provides some kind of an expert mode. Any property
* which is not handled otherwise by the step can be set. It is not
* possible to overwrite e.g. the `containers` property or to
* overwrite the `securityContext` property.
* Alternate way for providing `additionalPodProperties` is via
* `general/jenkinsKubernetes/additionalPodProperties` in the project configuration.
* Providing the resources map as parameter to the step call takes
* precedence.
* This freedom comes with great responsibility. The property
* `additionalPodProperties` should only be used in case you
* really know what you are doing.
*/
'additionalPodProperties',
/**
* Allows to specify start command for container created with dockerImage parameter to overwrite Piper default (`/usr/bin/tail -f /dev/null`).
*/
@ -306,10 +327,10 @@ private String generatePodSpec(Map config) {
metadata : [
lables: config.uniqueId
],
spec : [
containers: containers
]
spec : [:]
]
podSpec.spec += getAdditionalPodProperties(config)
podSpec.spec.containers = getContainerList(config)
podSpec.spec.securityContext = getSecurityContext(config)
return new JsonUtils().groovyObjectToPrettyJsonString(podSpec)
@ -355,6 +376,16 @@ chown -R ${runAsUser}:${fsGroup} ."""
return null
}
private Map getAdditionalPodProperties(Map config) {
Map podProperties = config.additionalPodProperties ?: config.jenkinsKubernetes.additionalPodProperties ?: [:]
if(podProperties) {
echo "Additional pod properties found (${podProperties.keySet()})." +
' Providing additional pod properties is some kind of expert mode. In case of any problems caused by these' +
' additional properties only limited support can be provided.'
}
return podProperties
}
private Map getSecurityContext(Map config) {
return config.securityContext ?: config.jenkinsKubernetes.securityContext ?: [:]
}