【发布时间】:2021-10-16 06:19:28
【问题描述】:
感谢this question 的回答,我最近了解了withCredentials DSL。
尝试使用@RamKamath 的答案,即以下 Jenkinsfile:
pipeline {
agent any
stages {
stage( "1" ) {
steps {
script {
def credId = "cred_id_stored_in_jenkins"
withCredentials([usernamePassword(credentialsId: credId,
passwordVariable: 'password',
usernameVariable: 'username')]) {
String url = "https://bitbucket.company.com/rest/build-status/1.0/commits"
String commit = '0000000000000000000000000000000000000001'
Map dict = [:]
dict.state = "INPROGRESS"
dict.key = "foo_002"
dict.url = "http://server:8080/blue/organizations/jenkins/job/detail/job/002/pipeline"
List command = []
command.add("curl -f -L")
command.add('-u ${username}:${password}')
command.add("-H \\\"Content-Type: application/json\\\"")
command.add("-X POST ${url}/${commit}")
command.add("-d \\\''${JsonOutput.toJson(dict)}'\\\'")
sh(script: command.join(' '))
}
}
}
}
}
}
...curl 命令本身因报告“错误请求”错误而失败。这是 Jenkins 控制台输出的 sn-p:
+ curl -f -L -u ****:**** -H "Content-Type:application/json" -X POST https://bitbucket.company.com/rest/build-status/1.0/commits/0000000000000000000000000000000000000001 -d '{"state":"INPROGRESS","key":"foo_002","url":"http://server:8080/blue/organizations/jenkins/job/detail/job/002/pipeline"}'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 153 0 0 100 153 0 4983 --:--:-- --:--:-- --:--:-- 5100
curl: (22) The requested URL returned error: 400 Bad request
我知道 -u ****:**** 是 -u 的掩码 username:password 参数。
如果我将该确切的字符串复制/粘贴到 shell 中,并用实际值替换掩码值,curl 命令有效:
$ curl -f -L -u super_user:super_password -H "Content-Type:application/json" -X POST https://bitbucket.company.com/rest/build-status/1.0/commits/0000000000000000000000000000000000000001 -d '{"state":"INPROGRESS","key":"foo_002","url":"http://server:8080/blue/organizations/jenkins/job/detail/job/002/pipeline"}'
$
出了什么问题?为什么Jenkins执行curl命令会导致error 400/"Bad request",而手动执行同样的命令却运行良好?
请注意:按照建议,我将 -u ${username}:${password} 括在单引号中,而不是双引号。
更新: 我觉得字符串插值有问题,因为如果我修改 Jenkinsfile 以添加硬编码的用户名/密码,即
command.add('-u super_user:super_password')
...而不是
command.add('-u ${username}:${password}')
...那么curl 命令仍然像以前一样失败,即因为error: 400 Bad request
谁能帮我找出问题所在,大概是命令程序集和/或sh() 调用?
更新
我通过删除withCredentials() 简化了问题。即使是这个简化的curl 调用也会失败:
pipeline {
agent any
stages {
stage( "1" ) {
steps {
script {
def credId = "cred_id_stored_in_jenkins"
String url = "https://bitbucket.company.com/rest/build-status/1.0/commits"
String commit = '0000000000000000000000000000000000000001'
Map dict = [:]
dict.state = "INPROGRESS"
dict.key = "foo_002"
dict.url = "http://server:8080/blue/organizations/jenkins/job/detail/job/002/pipeline"
List command = []
command.add("curl -f -L")
command.add('-u super_user:super_password')
command.add("-H \\\"Content-Type: application/json\\\"")
command.add("-X POST ${url}/${commit}")
command.add("-d \\\''${JsonOutput.toJson(dict)}'\\\'")
sh(script: command.join(' '))
}
}
}
}
}
【问题讨论】:
-
command.add(...)在 Groovy 上下文中。根据Groovy, Strings and GString literals, Double quoted string (interpolation) 和Groovy, String Interpolation,如果您尝试使用"..."而不是'...'作为字符串分隔符会怎样?如果我尝试使用单引号内联管道项目来调整您的脚本,我会得到:[curl -f -L, -u ${username}:${password}, -H \"Content-Type: application/json\", -X POST http://localhost:8083/api/json/]. -
@GeroldBroser - 试一试,即现在
command.add(...)的每个实例都是command.add("...")。 IE。没有command.add(...)的实例使用单引号。但是curl命令的失败与原始帖子中的相同。 -
@GeroldBroser - 试图将这个问题简化为最简单的 MVRE,我发现即使没有
withCredentials()和变量,这个问题也是可重现的——即只有硬编码字符串的所有内容!我会相应地更新我的帖子;检查问题的最简单版本可能会有所帮助。 -
“没有
withCredentials()”已经是我“改编你的脚本”的一部分了。 :) -
@GeroldBroser - 更新时删除了
withCredentials()。我非常确定这是一些晦涩难懂的小字符串插值问题,这让我很头疼。但对于我的生活,我看不到它。试图在命令的正确位置获得双引号的字符串争论是地狱,我想我已经成功了——再次,因为如果我从 Jenkins 控制台输出中复制/粘贴命令到 shell,curl命令有效!
标签: rest curl jenkins-pipeline passwords password-protection