【问题标题】:How to reuse Jenkins credentials without masking the PASSWORD in withCredentials.usernamePassword?如何在不掩盖 withCredentials.usernamePassword 中的 PASSWORD 的情况下重用 Jenkins 凭据?
【发布时间】:2019-04-20 17:06:10
【问题描述】:

背景

  • 我正在使用脚本化管道和共享库。

我们所有的实现都在 src 目录下,我在管道中重用了引用:

def static myFunction(steps, context) {
  steps.withCredentials([steps.usernamePassword(
      credentialsId: 'credentialsId',
      usernameVariable: 'GITHUB_USERNAME',
      passwordVariable: 'GITHUB_PASSWORD')]) {

     // use of steps.env.GITHUB_PASSWORD
  }
}
  • 我需要使用设置为 UsernamePassword 凭据的相同凭据对 Github Enterprise 进行 2 次 API 调用 虽然第一次调用按预期工作,但第二次调用失败,因为 env.GITHUB_PASSWORD 值是 ma​​sked 详情

https://wiki.jenkins.io/display/JENKINS/Credentials+Binding+Plugin 中所述,问题可能与多次使用时如何屏蔽凭据绑定有关。也就是说,一旦我们使用 ${env.PASSWORD} 一次,它就会屏蔽所有对同一个值的使用。

详情

我正在使用 curl to,我需要生成 URL

def teamMembersApi = sh(curl -H 'Authorization: token ${env.PASSWORD}' ${githubRepoApi}")

此调用的响应是另一个 API URL,我用“teamMembersApi”创建了另一个 URL。所以,打第二个电话……

def teamMembers = sh("curl -H 'Authorization: token ${env.PASSWORD}' ${teamMembersApi}")

此时,${env.PASSWORD} 的值被屏蔽,因此第二次调用因凭据无效而失败

问题

据我了解,这是通过任何会导致“toString()”的方法访问值时“屏蔽”值的结果,这将使其无法在字符串中重复使用。 .

  • 如何重复使用相同的凭据,即使它们有资格被屏蔽?

验证

  • 我尝试使用 2 块 steps.withCredentials
  • 我尝试使用 httpRequest 步骤不引用变量

使用 httpRequest,我得到 MalformedURLException 和一个格式清晰的 URL...我确保 URL 是字符串格式并且具有协议...

java.net.MalformedURLException: no protocol: https://github.company.com/org/repo

【问题讨论】:

  • 您的 Shell 脚本示例将代码括在双引号中:sh("...")。根据Credentials Binding Plugin,代码应该用单引号括起来:“注意使用single引号来定义脚本(sh的隐式参数)......”
  • 更改此设置可能无法解决问题,但您的代码应该更安全。
  • @groverboy 双引号已经掩盖了问题是有道理的。但我假设我们需要,因为它需要将它绑定到字符串......我会尝试......

标签: jenkins jenkins-pipeline credentials


【解决方案1】:

您可以随时在withCredentials 块内使用username/password。但 请记住,username/password 只能在 withCredentials 块内生存。

我在以下代码中使用了相同的username/password 两次,效果很好。

node('docker') {
  withCredentials([steps.usernamePassword(
      credentialsId: 'ba2e4f46-56f1-4467-ae97-17b356d7f854',
      usernameVariable: 'JENKINS_USERNAME',
      passwordVariable: 'JENKINS_PASSWORD')]) {

     def log = sh(
         returnStdout: true,
         script: "curl -u ${env.JENKINS_USERNAME}:${env.JENKINS_PASSWORD} -k ${env.BUILD_URL}" + 'consoleText').trim()

     def pipelineSteps = sh(
         returnStdout: true,
         script: "curl -u ${env.JENKINS_USERNAME}:${env.JENKINS_PASSWORD} -k ${env.BUILD_URL}" + 'flowGraphTable').trim()

     echo '\n## build log ##\n' + log

     echo '\n## pipelineSteps ##\n' + pipelineSteps
  }

  echo "JENKINS_USERNAME: ${env.JENKINS_USERNAME}" 
  // print JENKINS_USERNAME: null 
  // because JENKINS_USERNAME's lifecycle is limited inside withCredentials blok.      
}

代码中的另一个问题,如果您没有为步骤sh 指定选项returnStdout: true,它应该返回null。示例:def output = sh('command')output 将是 null

【讨论】:

  • 根据上面 cmets 上的@groverboy,错误是由于双引号引起的,因为它会永久屏蔽该值...您确定第二个命令成功了吗???为了简单起见,我没有在我的示例中包含returnStdout...在接受答案之前将进行测试和验证...
猜你喜欢
  • 1970-01-01
  • 2022-08-14
  • 1970-01-01
  • 2020-01-01
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-16
相关资源
最近更新 更多