1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

Merge branch 'master' into pr/revertNoScriptRef

This commit is contained in:
Thorsten Duda 2019-12-04 08:57:17 +01:00 committed by GitHub
commit eda1e54085
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 338 additions and 13 deletions

33
.hooks/README.md Normal file
View File

@ -0,0 +1,33 @@
# Git Hooks
From [Git docs](https://git-scm.com/docs/githooks#_description):
> Hooks are programs you can place in a hooks directory to trigger actions at certain points in git’s execution. Hooks that don’t have the executable bit set are ignored.
## Usage
To use the hook, execute this command in the project root directory to link the script into the `.git/hooks` directory:
```sh
ln -s -f ../../.hooks/pre-commit ./.git/hooks/pre-commit
```
Make sure the file is executable:
```sh
chmod +x ./.hooks/pre-commit
```
## Pre-Commit Hook
From [Git docs](https://git-scm.com/docs/githooks#_pre_commit):
> This hook is invoked by git-commit, and can be bypassed with the --no-verify option. It takes no parameters, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with a non-zero status from this script causes the git commit command to abort before creating a commit.
### Content
Executes `go mod tidy` and stages `go.mod` & `go.sum`.
From [Golang docs](https://github.com/golang/go/wiki/Modules):
> `go mod tidy` — Prune any no-longer-needed dependencies from `go.mod` and add any dependencies needed for other combinations of OS, architecture, and build tags (details).

11
.hooks/pre-commit Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
STAGED_GO_FILES=$(git diff --staged --name-only | grep "\.go$")
if [[ "$STAGED_GO_FILES" = "" ]]; then
exit 0
fi
echo "cleaning GO dependencies"
go mod tidy
git add go.mod go.sum

View File

@ -53,9 +53,12 @@ jobs:
- stage: Docs
name: Create Documentation
install: docker pull squidfunk/mkdocs-material:3.0.4
before_script: documentation/bin/createDocu.sh
before_script:
- documentation/bin/createDocu.sh
- docker run -u `id -u`:`id -g` --rm -it -e GOCACHE=/tmp -v ${TRAVIS_BUILD_DIR}:/docu-gen golang sh -c "cd /docu-gen && go get github.com/SAP/jenkins-library/... && go run /docu-gen/pkg/generator/step-metadata.go --docuDir=/docu-gen/documentation/docs/steps/ --docuGen=true "
script:
- docker run -u `id -u`:`id -g` --rm -it -v ${TRAVIS_BUILD_DIR}/documentation:/docs squidfunk/mkdocs-material:3.0.4 build --clean --strict
after_script:
- mkdir -p documentation/docs-gen/misc
- cp target/docuMetaData.json documentation/docs-gen/misc
deploy:

View File

@ -0,0 +1,32 @@
# ${docGenStepName}
## ${docGenDescription}
## Prerequisites
* Cloud Foundry organization, space and deployment user are available
* Credentials for deployment have been configured in Jenkins with a dedicated Id
## ${docGenParameters}
## ${docGenConfiguration}
## ${docJenkinsPluginDependencies}
## Example
The following example creates a service key named "myServiceKey" for the service instance "myServiceInstance" in the provided cloud foundry organization and space. For the service key creation, the serviceKeyConfig is used.
```groovy
cloudFoundryCreateServiceKey(
script: this,
cloudFoundry: [
apiEndpoint: 'https://test.server.com',
credentialsId: 'cfCredentialsId',
org: 'cfOrg',
space: 'cfSpace',
serviceInstance: 'myServiceInstance',
serviceKey: 'myServiceKey',
serviceKeyConfig: '{ \"key\" : \"value\" }'
])
```

View File

@ -36,6 +36,7 @@ nav:
- checksPublishResults: steps/checksPublishResults.md
- cfManifestSubstituteVariables: steps/cfManifestSubstituteVariables.md
- cloudFoundryCreateService: steps/cloudFoundryCreateService.md
- cloudFoundryCreateServiceKey: steps/cloudFoundryCreateServiceKey.md
- cloudFoundryDeploy: steps/cloudFoundryDeploy.md
- commonPipelineEnvironment: steps/commonPipelineEnvironment.md
- containerExecuteStructureTests: steps/containerExecuteStructureTests.md

View File

@ -119,7 +119,7 @@ func docGenParameters(stepData config.StepData) string {
//create parameters detail section
parametersDetail := createParametersDetail(stepData.Spec.Inputs.Parameters)
return "Parameters\n\n" + parametersTable + parametersDetail
return "Parameters\n\n" + parametersTable + "\n\n" + parametersDetail
}
// Replaces the docGenConfiguration placeholder with the content from the yaml
@ -152,7 +152,7 @@ func createParametersTable(parameters []config.StepParameters) string {
func createParametersDetail(parameters []config.StepParameters) string {
var detail = "## Details\n"
var detail = "## Details\n\n"
var m map[string]bool = make(map[string]bool)
for _, param := range parameters {

View File

@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/assert"
)
var expectedResultDocument string = "# testStep\n\n\t## Description \n\nLong Test description\n\n\t\n\t## Prerequisites\n\t\n\tnone\n\n\t\n\t\n\t## Parameters\n\n| name | mandatory | default | possible values |\n| ------- | --------- | ------- | ------- |\n | param0 | No | val0 | |\n | param1 | No | <nil> | |\n | param2 | Yes | <nil> | |\n ## Details\n * ` param0 ` : param0 description \n * ` param1 ` : param1 description \n * ` param2 ` : param1 description \n \n\t\n\t## We recommend to define values of step parameters via [config.yml file](../configuration.md). \n\nIn following sections of the config.yml the configuration is possible:\n\n| parameter | general | step/stage |\n|-----------|---------|------------|\n | param0 | X | | \n | param1 | | | \n | param2 | | | \n \n\t\n\t## Side effects\n\t\n\tnone\n\t\n\t## Exceptions\n\t\n\tnone\n\t\n\t## Example\n\n\tnone\n"
var expectedResultDocument string = "# testStep\n\n\t## Description \n\nLong Test description\n\n\t\n\t## Prerequisites\n\t\n\tnone\n\n\t\n\t\n\t## Parameters\n\n| name | mandatory | default | possible values |\n| ------- | --------- | ------- | ------- |\n | param0 | No | val0 | |\n | param1 | No | <nil> | |\n | param2 | Yes | <nil> | |\n \n\n## Details\n\n * ` param0 ` : param0 description \n * ` param1 ` : param1 description \n * ` param2 ` : param1 description \n \n\t\n\t## We recommend to define values of step parameters via [config.yml file](../configuration.md). \n\nIn following sections of the config.yml the configuration is possible:\n\n| parameter | general | step/stage |\n|-----------|---------|------------|\n | param0 | X | | \n | param1 | | | \n | param2 | | | \n \n\t\n\t## Side effects\n\t\n\tnone\n\t\n\t## Exceptions\n\t\n\tnone\n\t\n\t## Example\n\n\tnone\n"
func configMetaDataMock(name string) (io.ReadCloser, error) {
meta1 := `metadata:

View File

@ -193,6 +193,9 @@ steps:
dockerWorkspace: '/home/piper'
stashContent:
- 'deployDescriptor'
cloudFoundryCreateServiceKey:
dockerImage: 'ppiper/cf-cli'
dockerWorkspace: '/home/piper'
detectExecuteScan:
detect:
projectVersion: '1'
@ -337,7 +340,7 @@ steps:
classic:
dockerImage: 'ppiper/mta-archive-builder'
cloudMbt:
dockerImage: 'devxci/mbtci:1.0.0'
dockerImage: 'devxci/mbtci:1.0.4'
neoDeploy:
dockerImage: 'ppiper/neo-cli'
deployMode: 'mta'

View File

@ -44,6 +44,12 @@ class TransportManagementService implements Serializable {
]
]
def proxy = config.proxy ? config.proxy : script.env.HTTP_PROXY
if (proxy){
parameters["httpProxy"] = proxy
}
def response = sendApiRequest(parameters)
echo("OAuth Token retrieved successfully.")
@ -60,8 +66,10 @@ class TransportManagementService implements Serializable {
echo("URL: '${url}', File: '${file}'")
}
def proxy = config.proxy ? config.proxy : script.env.HTTP_PROXY
script.sh """#!/bin/sh -e
curl -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' -o responseFileUpload.txt --fail '${url}/v2/files/upload'
curl ${proxy ? '--proxy ' + proxy + ' ' : ''} -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' -o responseFileUpload.txt --fail '${url}/v2/files/upload'
"""
def responseContent = script.readFile("responseFileUpload.txt")
@ -101,6 +109,12 @@ class TransportManagementService implements Serializable {
]
]
def proxy = config.proxy ? config.proxy : script.env.HTTP_PROXY
if (proxy){
parameters["httpProxy"] = proxy
}
def response = sendApiRequest(parameters)
echo("Node upload successful.")

View File

@ -0,0 +1,116 @@
import java.util.Map
import static org.hamcrest.Matchers.hasItem
import static org.junit.Assert.assertThat
import org.hamcrest.Matchers
import static org.hamcrest.Matchers.containsString
import static org.hamcrest.Matchers.equalTo
import static org.hamcrest.Matchers.hasEntry
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import util.BasePiperTest
import util.JenkinsCredentialsRule
import util.JenkinsStepRule
import util.JenkinsLoggingRule
import util.JenkinsReadYamlRule
import util.JenkinsShellCallRule
import util.JenkinsDockerExecuteRule
import com.sap.piper.JenkinsUtils
import util.Rules
import hudson.AbortException
public class CloudFoundryCreateServiceKeyTest extends BasePiperTest {
private ExpectedException thrown = new ExpectedException()
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
private JenkinsCredentialsRule credentialsRule = new JenkinsCredentialsRule(this).withCredentials('test_credentialsId', 'user', 'password')
class JenkinsUtilsMock extends JenkinsUtils {
def isJobStartedByUser() {
return true
}
}
@Rule
public RuleChain ruleChain = Rules.getCommonRules(this)
.around(new JenkinsReadYamlRule(this))
.around(thrown)
.around(stepRule)
.around(loggingRule)
.around(credentialsRule)
.around(dockerExecuteRule)
.around(shellRule)
@Before
public void setup() {
}
@Test
public void success() {
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*cf create-service-key.*/, 0 )
stepRule.step.cloudFoundryCreateServiceKey(
script: nullScript,
cloudFoundry: [
apiEndpoint: 'api.example.com',
credentialsId: 'test_credentialsId',
org: 'testOrg',
space: 'testSpace',
serviceInstance : 'myInstance',
serviceKey : 'myServiceKey',
serviceKeyConfig : '{ "key" : "value" }'
]
)
assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'ppiper/cf-cli'))
assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/piper'))
assertThat(shellRule.shell, hasItem(containsString("#!/bin/bash set +x set -e export HOME=/home/piper cf login -u 'user' -p 'password' -a api.example.com -o 'testOrg' -s 'testSpace'; cf create-service-key 'myInstance' 'myServiceKey' -c '{ \"key\" : \"value\" }'")))
}
@Test
public void noServiceKeyConfig() {
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*cf create-service-key.*/, 0 )
stepRule.step.cloudFoundryCreateServiceKey(
script: nullScript,
cloudFoundry: [
apiEndpoint: 'api.example.com',
credentialsId: 'test_credentialsId',
org: 'testOrg',
space: 'testSpace',
serviceInstance : 'myInstance',
serviceKey : 'myServiceKey'
]
)
assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'ppiper/cf-cli'))
assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/piper'))
assertThat(shellRule.shell, hasItem(containsString("#!/bin/bash set +x set -e export HOME=/home/piper cf login -u 'user' -p 'password' -a api.example.com -o 'testOrg' -s 'testSpace'; cf create-service-key 'myInstance' 'myServiceKey'")))
}
public void fail() {
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*cf create-service-key.*/, 1 )
stepRule.step.cloudFoundryCreateServiceKey(
script: nullScript,
cloudFoundry: [
apiEndpoint: 'api.example.com',
credentialsId: 'test_credentialsId',
org: 'testOrg',
space: 'testSpace',
serviceInstance : 'myInstance',
serviceKey : 'myServiceKey',
serviceKeyConfig : '{ "key" : "value" }'
]
)
assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'ppiper/cf-cli'))
assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/piper'))
assertThat(shellRule.shell, hasItem(containsString("[cloudFoundryCreateServiceKey] ERROR: The execution of the create-service-key failed, see the logs above for more details.")))
}
}

View File

@ -6,7 +6,6 @@ import com.sap.piper.Utils
import groovy.json.JsonSlurper
import hudson.AbortException
import groovy.transform.Field
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException
import java.util.UUID
@Field def STEP_NAME = getClass().getName()

View File

@ -93,7 +93,7 @@ enum GitPushMode {NONE, HTTPS, SSH}
/** Defines the template for the automatic version which will be created. */
'versioningTemplate',
/** Controls which protocol is used for performing push operation to remote repo.
* Required credentials needs to be configured ('gitSshKeyCredentialsId'/'TBD').
* Required credentials needs to be configured ('gitSshKeyCredentialsId'/'gitHttpsCredentialsId').
* Push is only performed in case 'commitVersion' is set to 'true'.
* @possibleValues 'SSH', 'HTTPS', 'NONE'
*/

View File

@ -0,0 +1,109 @@
import com.sap.piper.GenerateDocumentation
import com.sap.piper.BashUtils
import com.sap.piper.JenkinsUtils
import com.sap.piper.Utils
import com.sap.piper.ConfigurationHelper
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String STEP_NAME = 'cloudFoundryCreateServiceKey'
@Field Set STEP_CONFIG_KEYS = [
'cloudFoundry',
/**
* Cloud Foundry API endpoint.
* @parentConfigKey cloudFoundry
*/
'apiEndpoint',
/**
* Cloud Foundry credentials.
* @parentConfigKey cloudFoundry
*/
'credentialsId',
/**
* Cloud Foundry target organization.
* @parentConfigKey cloudFoundry
*/
'org',
/**
* Cloud Foundry target space.
* @parentConfigKey cloudFoundry
*/
'space',
/**
* Cloud Foundry service instance, for which the service key will be created.
* @parentConfigKey cloudFoundry
*/
'serviceInstance',
/**
* Cloud Foundry service key, which will be created.
* @parentConfigKey cloudFoundry
*/
'serviceKey',
/**
* Cloud Foundry service key configuration.
* @parentConfigKey cloudFoundry
*/
'serviceKeyConfig',
/** @see dockerExecute */
'dockerImage',
/** @see dockerExecute */
'dockerWorkspace'
]
@Field Set GENERAL_CONFIG_KEYS = STEP_CONFIG_KEYS
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
/**
* Step that creates a service key for a service instancve on Cloud Foundry
*/
@GenerateDocumentation
void call(Map parameters = [:]) {
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
def script = checkScript(this, parameters) ?: this
Map config = ConfigurationHelper.newInstance(this)
.loadStepDefaults()
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
.mixin(parameters, PARAMETER_KEYS)
.withMandatoryProperty('cloudFoundry/org')
.withMandatoryProperty('cloudFoundry/space')
.withMandatoryProperty('cloudFoundry/credentialsId')
.withMandatoryProperty('cloudFoundry/serviceInstance')
.withMandatoryProperty('cloudFoundry/serviceKey')
.use()
echo "[${STEP_NAME}] Info: docker image: ${config.dockerImage}, docker workspace: ${config.dockerWorkspace}"
executeCreateServiceKey(script, config)
}
}
private def executeCreateServiceKey(script, Map config) {
dockerExecute(script:script, dockerImage: config.dockerImage, dockerWorkspace: config.dockerWorkspace) {
withCredentials([
usernamePassword(credentialsId: config.cloudFoundry.credentialsId, passwordVariable: 'CF_PASSWORD', usernameVariable: 'CF_USERNAME')
]) {
String flag = config.cloudFoundry.serviceKeyConfig == null ? "" : "-c"
String serviceKeyConfig = config.cloudFoundry.serviceKeyConfig == null ? "" : config.cloudFoundry.serviceKeyConfig
bashScript =
"""#!/bin/bash
set +x
set -e
export HOME=${config.dockerWorkspace}
cf login -u ${BashUtils.quoteAndEscape(CF_USERNAME)} -p ${BashUtils.quoteAndEscape(CF_PASSWORD)} -a ${config.cloudFoundry.apiEndpoint} -o ${BashUtils.quoteAndEscape(config.cloudFoundry.org)} -s ${BashUtils.quoteAndEscape(config.cloudFoundry.space)};
cf create-service-key ${BashUtils.quoteAndEscape(config.cloudFoundry.serviceInstance)} ${BashUtils.quoteAndEscape(config.cloudFoundry.serviceKey)} ${flag} ${BashUtils.quoteAndEscape(serviceKeyConfig)}
"""
def returnCode = sh returnStatus: true, script: bashScript
sh "cf logout"
if (returnCode!=0) {
error "[${STEP_NAME}] Error: The execution of create-service-key failed, see the logs above for more details."
echo "Return Code: $returnCode"
}
}
}
}

View File

@ -15,7 +15,7 @@ import java.nio.charset.StandardCharsets
/**
* Pull-Request voting only:
* The URL to the Github API. see [GitHub plugin docs](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin#GitHubPlugin-Usage)
* deprecated: only supported in LTS / < 7.2
* deprecated: only supported below SonarQube v7.2
*/
'githubApiUrl',
/**
@ -33,7 +33,7 @@ import java.nio.charset.StandardCharsets
/**
* Pull-Request voting only:
* The Jenkins credentialId for a Github token. It is needed to report findings back to the pull-request.
* deprecated: only supported in LTS / < 7.2
* deprecated: only supported below SonarQube v7.2
* @possibleValues Jenkins credential id
*/
'githubTokenCredentialsId',
@ -56,7 +56,7 @@ import java.nio.charset.StandardCharsets
/**
* Pull-Request voting only:
* Disables the pull-request decoration with inline comments.
* deprecated: only supported in LTS / < 7.2
* deprecated: only supported below SonarQube v7.2
* @possibleValues `true`, `false`
*/
'disableInlineComments',
@ -72,7 +72,7 @@ import java.nio.charset.StandardCharsets
/**
* Pull-Request voting only:
* Activates the pull-request handling using the [GitHub Plugin](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin) (deprecated).
* deprecated: only supported in LTS / < 7.2
* deprecated: only supported below SonarQube v7.2
* @possibleValues `true`, `false`
*/
'legacyPRHandling',

View File

@ -37,7 +37,11 @@ import static com.sap.piper.Prerequisites.checkScript
/**
* Can be used as the description of a transport request. Will overwrite the default. (Default: Corresponding Git Commit-ID)
*/
'customDescription'
'customDescription',
/**
* Proxy which should be used for the communication with the Transport Management Service Backend.
*/
'proxy'
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS