commit f68141b019e07cae4e3c63f528c57c21ce381243 Author: R. Tyler Croy Date: Wed Aug 9 18:51:39 2017 -0700 Add an initial version of the shared library diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..910ca13 --- /dev/null +++ b/README.adoc @@ -0,0 +1,54 @@ += Inline Pipeline Secrets + +This is a link:https://jenkins.io/doc/book/pipeline/shared-libraries[Pipeline +Shared Library] which helps support the use of user-defined inline secrets from +within a `Jenkinsfile`. + + +== Prerequisites + +This Shared Library requires that the +link:https://plugins.jenkins.io/workflow-aggregator[Pipeline plugin] and +link:https://plugins.jenkins.io/mask-passwords[Mask Passwords plugin] +installed. + + +== Using + +=== Decrypting Secrets + +A Pipeline can use secrets similar to environment variables: + +.Jenkinsfile +[source,groovy] +---- +node { + stage('Deploy') { + withSecrets( + AWS_SECRET_ID: '{AQAAABAAAAAQWsBycxCz0x8ouOKJLU9OTvHdsN7kt7+6RAcV2zZJTm4=}' + ) { + echo "I should be deploying something with: ${env.AWS_SECRET_ID}" + } + } +} +---- + +=== Encrypting Secrets + +A Pipeline can be used to offer a user interface for encrypting. + +.Jenkinsfile +[source,groovy] +---- +promptUserForEncryption() +---- + +== API + +`promptUserForEncryption()` + +`createSecretText()` + +`unsafeSecretAccess()` + +`withSecrets()` diff --git a/assets/with-screenshot.png b/assets/with-screenshot.png new file mode 100644 index 0000000..aaa9168 Binary files /dev/null and b/assets/with-screenshot.png differ diff --git a/vars/createSecretText.groovy b/vars/createSecretText.groovy new file mode 100644 index 0000000..1625809 --- /dev/null +++ b/vars/createSecretText.groovy @@ -0,0 +1,7 @@ +#!/usr/bin/env groovy + +import hudson.util.Secret + +def call(String text) { + return Secret.fromString(text) +} diff --git a/vars/promptUserForEncryption.groovy b/vars/promptUserForEncryption.groovy new file mode 100644 index 0000000..e23c15a --- /dev/null +++ b/vars/promptUserForEncryption.groovy @@ -0,0 +1,10 @@ +#!/usr/bin/env groovy + +def call() { + def s = input(message: 'Text', + ok: 'Encrypt', + parameters: [password(defaultValue: '', + description: 'Text for encryption', + name: 'Plain text')]) + echo "Use this encrypted value in your Jenkinsfile: ${s.encryptedValue}" +} diff --git a/vars/unsafeSecretAccess.groovy b/vars/unsafeSecretAccess.groovy new file mode 100644 index 0000000..e0e1847 --- /dev/null +++ b/vars/unsafeSecretAccess.groovy @@ -0,0 +1,7 @@ +#!/usr/bin/env groovy + +import hudson.util.Secret + +def call(String cipherText) { + return Secret.decrypt(cipherText) +} diff --git a/vars/withSecrets.groovy b/vars/withSecrets.groovy new file mode 100644 index 0000000..0b08762 --- /dev/null +++ b/vars/withSecrets.groovy @@ -0,0 +1,28 @@ +#!/usr/bin/env groovy +import hudson.util.Secret + +def call(Map ciphers, Closure body) { + List cipherPairs = [] + /* https://issues.jenkins-ci.org/browse/JENKINS-27392 */ + List cipherEnv = [] + + body.resolveStrategy = Closure.DELEGATE_FIRST + + ciphers.each { String key, String cipherText -> + String plainText = Secret.decrypt(cipherText).plainText + cipherEnv.add("${key}=${plainText}") + cipherPairs.add([var: key, + password: plainText]) + } + + try { + wrap([$class: 'MaskPasswordsBuildWrapper', + varPasswordPairs: cipherPairs]) { + withEnv(cipherEnv) { body.call() } + } + + } + catch (java.lang.IllegalArgumentException e) { + error 'Cannot use withSecret() without installing the Mask Passwords plugin' + } +}